Exprimer un nombre
Dans les années 60, les Français ont inventé le jeu télévisé "Des Chiffres et des Lettres" (Digits & Letters). Le but de la partie Chiffres de l'émission était de se rapprocher le plus possible d'un certain nombre cible à 3 chiffres, en utilisant des nombres sélectionnés de manière semi-aléatoire. Les candidats pouvaient utiliser les opérateurs suivants:
- concaténation (1 et 2 est 12)
- addition (1 + 2 est 3)
- soustraction (5 - 3 = 2)
- division (8/2 = 4); la division n'est autorisée que si le résultat est un nombre naturel
- multiplication (2 * 3 = 6)
- parenthèses, pour remplacer la priorité régulière des opérations: 2 * (3 + 4) = 14
Chaque numéro donné ne peut être utilisé qu'une seule fois ou pas du tout.
Par exemple, le nombre cible 728 peut correspondre exactement aux nombres: 6, 10, 25, 75, 5 et 50 avec l'expression suivante:
75 * 10 - ( ( 6 + 5 ) * ( 50 / 25 ) ) = 750 - ( 11 * 2 ) = 750 - 22 = 728
Dans ce défi de code, vous avez pour tâche de trouver une expression aussi proche que possible d'un certain nombre cible. Puisque nous vivons au 21e siècle, nous allons introduire des nombres cibles plus grands et plus de nombres avec lesquels travailler que dans les années 60.
Règles
- Opérateurs autorisés: concaténation, +, -, /, *, (et)
- L'opérateur de concaténation n'a pas de symbole. Concatène simplement les chiffres.
- Il n'y a pas de "concaténation inverse". 69 est 69 et ne peut pas être divisé en 6 et en 9.
- Le nombre cible est un entier positif et a un maximum de 18 chiffres.
- Il y a au moins deux nombres avec lesquels travailler et un maximum de 99 nombres. Ces nombres sont également des entiers positifs avec un maximum de 18 chiffres.
- Il est possible (en fait très probablement) que le nombre cible ne puisse pas être exprimé en termes de nombres et d'opérateurs. Le but est de se rapprocher le plus possible.
- Le programme devrait se terminer dans un délai raisonnable (quelques minutes sur un PC de bureau moderne).
- Des échappatoires standard s'appliquent.
- Votre programme peut ne pas être optimisé pour l'ensemble de tests dans la section "Scoring" de ce puzzle. Je me réserve le droit de modifier l'ensemble de test si je soupçonne quiconque enfreint cette règle.
- Ce n'est pas un golf de code.
Contribution
L'entrée se compose d'un tableau de nombres qui peut être formaté de n'importe quelle manière pratique. Le premier nombre est le nombre cible. Les autres nombres sont les nombres avec lesquels vous devez travailler pour former le nombre cible.
Production
Les exigences pour la sortie sont:
- Il doit s'agir d'une chaîne composée de:
- tout sous-ensemble des numéros d'entrée (sauf le numéro cible)
- n'importe quel nombre d'opérateurs
- Je préfère que la sortie soit une seule ligne sans espaces, mais si vous le devez, vous pouvez ajouter des espaces et des nouvelles lignes comme bon vous semble. Ils seront ignorés dans le programme de contrôle.
- La sortie doit être une expression mathématique valide.
Exemples
Pour plus de lisibilité, tous ces exemples ont une solution exacte et chaque numéro d'entrée est utilisé exactement une fois.
Entrée: 1515483, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
Sortie:111*111*(111+11+1)
Entrée: 153135, 1, 2, 3, 4, 5, 6, 7, 8, 9
Sortie:123*(456+789)
Entrée: 8888888888, 9, 9, 9, 99, 99, 99, 999, 999, 999, 9999, 9999, 9999, 99999, 99999, 99999, 1
Sortie:9*99*999*9999-9999999-999999-99999-99999-99999-9999-999-9-1
Entrée: 207901, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0
Sortie:1+2*(3+4)*(5+6)*(7+8)*90
Entrée: 34943, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0
Sortie: 1+2*(3+4*(5+6*(7+8*90)))
Mais une sortie valide est également:34957-6-8
Notation
Le score de pénalité d'un programme est la somme des erreurs relatives des expressions pour l'ensemble de tests ci-dessous.
Par exemple, si la valeur cible est 125 et que votre expression donne 120, votre score de pénalité est abs (1 - 120/125) = 0,04.
Le programme avec le plus bas score (erreur relative totale la plus faible) gagne. Si deux programmes se terminent également, la première soumission est gagnante.
Enfin, le testset (8 cas):
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 similaires précédents
Après avoir créé ce puzzle et l'avoir affiché sur le bac à sable, j'ai remarqué quelque chose de similaire (mais pas le même!) Dans deux puzzles précédents: ici (pas de solutions) et ici . Ce casse-tête est quelque peu différent, car il introduit l'opérateur de concaténation, je ne cherche pas et ne correspond pas exactement et j'aime voir des stratégies pour se rapprocher de la solution sans force brute. Je pense que c'est difficile.
Réponses:
C ++ 17, score .0086
Ce programme a un score de pénalité non déterministe en raison des courses de threads, donc je déclare en se basant sur une moyenne de trois exécutions, chacune ayant géré la suite de tests en moins d'une minute:
Voici le programme; l'explication est fournie dans les commentaires. Vous pouvez définir
CONCAT_NONE
pour les règles de compte à rebours traditionnelles qui ne permettent pas la concaténation, ouCONCAT_DIGITS
pour permettre la concaténation des valeurs d'entrée, mais pas de résultats intermédiaires. Par défaut, sans qu'aucun des deux ne soit défini, les règles les plus libérales sont utilisées.J'ai compilé cela en utilisant GCC 6.2, en utilisant
g++ -std=c++17 -fopenmp -march=native -O3
(avec quelques options de débogage et d'avertissement).la source
Python 2.7. Résultat: 1,67039106
J'ai donc décidé de me lancer moi-même. Rien d'extraordinaire. Ce programme trie les nombres dans l'ordre inverse (grand à petit) et essaie tous les opérateurs séquentiellement sur les nombres. Rapide, mais une performance qui mérite d'être dépassée.
Voici le programme:
La sortie pour tous les cas de test est:
la source