Expressar um número
Nos anos 60, os franceses inventaram o programa de TV "Des Chiffres et des Lettres" (Dígitos e letras). O objetivo da parte Dígitos do programa era chegar o mais próximo possível de um determinado número-alvo de três dígitos, usando alguns números selecionados aleatoriamente. Os participantes poderiam usar os seguintes operadores:
- concatenação (1 e 2 são 12)
- adição (1 + 2 é 3)
- subtração (5 - 3 = 2)
- divisão (8/2 = 4); divisão só é permitida se o resultado for um número natural
- multiplicação (2 * 3 = 6)
- parênteses, para substituir a precedência regular das operações: 2 * (3 + 4) = 14
Cada número dado pode ser usado apenas uma vez ou não.
Por exemplo, o número de destino 728 pode ser correspondido exatamente com os números: 6, 10, 25, 75, 5 e 50 com a seguinte expressão:
75 * 10 - ( ( 6 + 5 ) * ( 50 / 25 ) ) = 750 - ( 11 * 2 ) = 750 - 22 = 728
Nesse desafio de código, você terá a tarefa de encontrar uma expressão o mais próximo possível de um determinado número de destino. Como vivemos no século XXI, apresentaremos números-alvo maiores e mais números para trabalhar do que nos anos 60.
Regras
- Operadores permitidos: concatenação, +, -, /, *, (e)
- O operador de concatenação não possui símbolo. Apenas concatene os números.
- Não há "concatenação inversa". 69 é 69 e não pode ser dividido em 6 e 9.
- O número de destino é um número inteiro positivo e tem um máximo de 18 dígitos.
- Existem pelo menos dois números para trabalhar e no máximo 99 números. Esses números também são números inteiros positivos com um máximo de 18 dígitos.
- É possível (na verdade, muito provavelmente) que o número alvo não possa ser expresso em termos de números e operadores. O objetivo é chegar o mais próximo possível.
- O programa deve terminar em um tempo razoável (alguns minutos em um PC de mesa moderno).
- Aplicam-se brechas padrão.
- Seu programa pode não estar otimizado para o conjunto de testes na seção "pontuação" deste quebra-cabeça. Reservo-me o direito de alterar o conjunto de testes se suspeitar que alguém esteja violando essa regra.
- Este não é um codegolf.
Entrada
A entrada consiste em uma matriz de números que pode ser formatada de qualquer maneira conveniente. O primeiro número é o número de destino. O restante dos números são os números com os quais você deve trabalhar para formar o número de destino.
Resultado
Os requisitos para a saída são:
- Deve ser uma string que consiste em:
- qualquer subconjunto dos números de entrada (exceto o número de destino)
- qualquer número de operadores
- Prefiro que a saída seja uma única linha sem espaços, mas se for necessário, você poderá adicionar espaços e novas linhas como achar melhor. Eles serão ignorados no programa de controle.
- A saída deve ser uma expressão matemática válida.
Exemplos
Para facilitar a leitura, todos esses exemplos têm uma solução exata e cada número de entrada é usado exatamente uma vez.
Entrada: 1515483, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
Saída:111*111*(111+11+1)
Entrada: 153135, 1, 2, 3, 4, 5, 6, 7, 8, 9
Saída:123*(456+789)
Entrada: 8888888888, 9, 9, 9, 99, 99, 99, 999, 999, 999, 9999, 9999, 9999, 99999, 99999, 99999, 1
Saída:9*99*999*9999-9999999-999999-99999-99999-99999-9999-999-9-1
Entrada: 207901, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0
Saída:1+2*(3+4)*(5+6)*(7+8)*90
Entrada: 34943, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0
Saída: 1+2*(3+4*(5+6*(7+8*90)))
Mas também a saída válida é:34957-6-8
Pontuação
A pontuação da penalidade de um programa é a soma dos erros relativos das expressões para o conjunto de testes abaixo.
Por exemplo, se o valor alvo for 125 e sua expressão der 120, sua pontuação de penalidade será abs (1 - 120/125) = 0,04.
O programa com a pontuação mais baixa (menor erro relativo total) vence. Se dois programas terminarem igualmente, a primeira inscrição vence.
Finalmente, o conjunto de testes (8 casos):
14142, 10, 11, 12, 13, 14, 15
48077691, 6, 9, 66, 69, 666, 669, 696, 699, 966, 969, 996, 999
333723173, 3, 3, 3, 33, 333, 3333, 33333, 333333, 3333333, 33333333, 333333333
589637567, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
8067171096, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199
78649377055, 0, 2, 6, 12, 20, 30, 42, 56, 72, 90, 110, 132, 156, 182, 210, 240, 272, 306, 342, 380, 420, 462, 506, 552, 600, 650, 702, 756, 812, 870, 930, 992
792787123866, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169
2423473942768, 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000, 2000000, 5000000, 10000000, 20000000, 50000000
Puzzles semelhantes anteriores
Depois de criar esse quebra-cabeça e publicá-lo na caixa de areia, notei algo semelhante (mas não o mesmo!) Em dois quebra-cabeças anteriores: aqui (sem soluções) e aqui . Esse quebra-cabeça é um pouco diferente, porque apresenta o operador de concatenação, não procuro uma correspondência exata e gosto de ver estratégias para chegar perto da solução sem força bruta. Eu acho que é desafiador.