Résolvez un puzzle Matchstick

17

Sur SE déroutant, il y a ce que l'on appelle des "problèmes d'allumettes" dans lesquels les mathématiques sont écrites dans des allumettes et vous êtes autorisé à en déplacer un certain nombre pour obtenir une certaine propriété.

Dans cette question, nous ne considérerons que les entiers représentés dans un format d'affichage à 7 segments. Voici les 10 chiffres de ce format:

 __          __   __          __    __    __    __    __
|  |     |   __|  __|  |__|  |__   |__      |  |__|  |__|
|__|     |  |__   __|     |   __|  |__|     |  |__|   __|    

Chaque segment de l'affichage est un "match-stick" qui peut être déplacé indépendamment du reste du numéro. Les allumettes sont indivisibles et indestructibles, elles ne peuvent en aucun cas être cassées ou enlevées.

Un casse-tête commun consiste à prendre un nombre donné en base 10 et à essayer de faire le plus grand nombre possible dans un nombre donné de mouvements. Un mouvement est considéré comme un mouvement d'une allumette d'un emplacement occupé vers un autre emplacement inoccupé. Vous êtes parfaitement autorisé à faire de nouveaux chiffres de chaque côté du numéro, par exemple 0 peut être transformé en 77 donner 3 coups

 __      __  __      __   __      __   __
|  |    |  |        |  |    |       |    |
|__| ,   __|     ,     |      ,     |    |

Cependant, vous ne pouvez pas transformer un emplacement en 2 ou créer de nouveaux emplacements entre ceux existants, par exemple en transformant un 4 en 11 au milieu d'un nombre ou en insérant de nouveaux chiffres entre les existants. Chaque mouvement n'a pas besoin de faire un nombre correct mais le résultat final doit être un nombre correct dans l'affichage à sept segments de base 10. Vous n'avez pas besoin d'utiliser chaque mouvement si vous ne le souhaitez pas. Contrairement au casse-tête, c'est une [balise: question fermée] que vous ne pouvez pas utiliser d'opérateurs (multiplication, exponentiation, etc.) ou de constantes mathématiques (Pi, nombre de Graham, etc.) dans vos réponses.

Tâche

Écrivez un programme ou une fonction qui prend un nombre et un nombre de mouvements en entrée et renvoie le plus grand nombre qui peut être effectué avec autant de mouvements sur le nombre d'origine.

Il s'agit d'une question de donc les réponses seront notées en octets, avec moins d'octets étant mieux.

Cas de test

n, moves -> max
0, 1     -> 9
0, 3     -> 77
0, 4     -> 111
8, 3     -> 74
220, 1   -> 320
220, 2   -> 520
220, 3   -> 7227
220, 4   -> 22111
220, 5   -> 32111
747, 1   -> 747
747, 2   -> 7171
747, 3   -> 7711

en relation

Post Rock Garf Hunter
la source
5
En fait, je suis resté éveillé tard hier soir en réfléchissant à la distance de Levenshtein entre les différents chiffres de l'allumette ... Quelle étrange coïncidence: P
ETHproductions
1
Les emplacements vides formés au milieu peuvent-ils être ignorés à la fin? Par exemple919, 2 -> 991
DanTheMan
En relation
geokavel
assistant de blé, quelle grille est utilisée?
tuskiomi
@tuskiomi "Cependant, vous ne pouvez pas faire un emplacement en 2 ou créer de nouveaux emplacements entre ceux existants"
Post Rock Garf Hunter

Réponses:

7

JavaScript (ES6), 297 286 279 267 octets

Prend la saisie dans la syntaxe de curry (s)(k), où s est un tableau de caractères numériques et k est le nombre de mouvements (entier).

s=>k=>(B=(n,b=0)=>n?B(n^n&-n,b+1):b,b=[...p='u"[k,iy#}m'].map(c=>c.charCodeAt()+2),r=[],g=(n,d='')=>n?n>0&&b.map((v,i)=>g(n-B(v),d+i)):r.push(d))(s.reduce((s,c)=>s+B(b[c]),M=0))&&b.map((_,j)=>r.map(n=>M=[...n+p].reduce((t,d,i)=>t+B(b[d]^b[s[i-j]]),0)>k*2|+n<M?M:n))|M

Cas de test


Comment?

Données de forme et fonction d'assistance

  • Le tableau b décrit les formes des chiffres sous forme d'entiers à 7 bits, où chaque bit est un segment:

    7 segments

    Par exemple, la forme de "7" est 0b0100101 = 37.

  • La fonction d'assistance B () renvoie le nombre de 1 dans la représentation binaire d'un nombre donné:

    B = (n, b = 0) => n ? B(n ^ n & -n, b + 1) : b

Étape 1

Nous comptons d'abord le nombre d'allumettes utilisées dans le nombre d'entrée:

s.reduce((s, c) => s + B(b[c]), 0)

Étape 2

Nous passons cette valeur à la fonction récursive g () , qui remplit une liste r avec tous les nombres qui peuvent être construits avec exactement ce nombre d'allumettes:

g = (n, d = '') =>
  n ?
    n > 0 &&
    b.map((v, i) => g(n - B(v), d + i))
  :
    r.push(d)

Par exemple, g (5) se chargera [ '17', '2', '3', '5', '71' ]dans r .

Étape 3

Nous devons maintenant sélectionner le nombre le plus élevé M dans r qui peut en fait être obtenu à partir du nombre d'entrée, dans le nombre autorisé de mouvements k .

Étant donné que chaque nombre n dans r utilise exactement autant d'allumettes que le nombre d'entrée s , le nombre de mouvements requis pour transformer s en n est égal à la moitié du nombre de différences de segment entre chacun de leurs chiffres.

Le nombre de différences de segment entre deux chiffres x et y est donné par le nombre de 1 dans la représentation binaire de b [x] XOR b [y] .

Enfin, il est important de noter que nous devons essayer plusieurs alignements de chiffres possibles, car le premier chiffre de s n'est pas nécessairement mappé au premier chiffre de n . Le décalage entre les chiffres est donné par la variable j dans le code.

Arnauld
la source
1

Mathematica, 188 197 200 203 170 174 octets

REMARQUE: Le code est toujours une sorte de buggy. J'y travaille.

+30 octets pour bug

(p=PadLeft;q=IntegerDigits;g=Join@@(#~q~2~p~7&/@ToCharacterCode["w$]m.k{% o"][[1+q@#]])&;h=(v=g@#2~#~96-g@i~#~96;Tr@v==0&&Tr@Abs@v<=2#3)&;For[i=10^Tr@g@#,!h[p,##]&&!h[PadRight,##],--i];i)&

Le caractère entre %et odevrait être 0x7Fmais SE ne le permettra pas. Vous pouvez cliquer sur le lien pastebin pour copier le code d'origine.

Le code prend beaucoup de temps lorsqu'il y a plus de 6-7 sticks. (Vous pouvez modifier la valeur de départ de ien un nombre plus petit pour le tester)

Explication

gest une fonction d'aide qui convertit les chiffres en une liste de représentations de bâton (selon ici ), comme {1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1}pour 220.

h est une fonction d'aide pour gérer le remplissage gauche et le remplissage droit entre deux nombres.

fitère de 10^Tr@g@#(limite supérieure) pour 1rechercher un entier dont la représentation en bâton a la même quantité de1 -> 0 et 0 -> 1par rapport au nombre d'origine et la quantité est plus petite ou égale au deuxième argument.

Keyu Gan
la source
Je vous ai donné un +1 parce que je n'ai jamais vu une réponse gagnante avoir un score aussi bas que l'autre réponse. Je suppose que c'est parce que c'est le manque d'options de test en ligne. Peut-être que certaines personnes qui ont Mathematica pourraient venir le tester et vérifier qu'il fonctionne bien, afin que vous puissiez obtenir encore plus de votes positifs. Ou peut-être que quelqu'un pourrait le convertir en Octave si possible.
geokavel