Resuelve un rompecabezas de Matchstick


17

En el desconcertante SE, existen los llamados "problemas de cerillas" en los que las matemáticas se escriben en cerillas y se le permite mover una cierta cantidad de ellas para obtener una determinada propiedad.

En esta pregunta, consideraremos solo números enteros representados en un formato de visualización de 7 segmentos. Aquí están los 10 dígitos en ese formato:

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

Cada segmento de la pantalla es un "fósforo" que se puede mover independientemente del resto del número. Los fósforos son indivisibles e indestructibles, no se pueden romper ni eliminar de ninguna manera.

Un rompecabezas común es tomar un número dado en la base 10 e intentar hacer el mayor número posible en un número dado de movimientos. Un movimiento se considera un movimiento de una cerilla desde cualquier ranura ocupada a cualquier otra ranura desocupada. Está perfectamente permitido hacer nuevos dígitos a cada lado del número, por ejemplo, 0 se puede convertir en 77 y dar 3 movimientos.

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

Sin embargo, no puede hacer una ranura en 2 o hacer nuevas ranuras entre las existentes, por ejemplo, convertir un 4 en un 11 en el medio de un número o insertar nuevos dígitos entre los existentes. Cada movimiento no necesita hacer un número apropiado, pero el resultado final debe ser un número apropiado en la pantalla de base 10 de siete segmentos. No necesita usar cada movimiento si no lo desea. A diferencia del enigma, esta es una [etiqueta: pregunta cerrada] no puede usar ningún operador (multiplicación, exponenciación, etc.) o constantes matemáticas (Pi, número de Graham, etc.) en sus respuestas.

Tarea

Escriba un programa o función que tome un número y una cantidad de movimientos como entrada y devuelva el número más grande que se puede hacer con tantos movimientos en el número original.

Esta es una pregunta de , por lo que las respuestas se puntuarán en bytes, con menos bytes mejor.

Casos de prueba

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

Relacionado


55
Yo ... en realidad me quedé despierto hasta tarde anoche reflexionando sobre la distancia de Levenshtein entre varios dígitos de cerillas ... Qué extraña coincidencia: P
ETHproductions

1
¿Se pueden ignorar las ranuras vacías formadas en el medio al final? Por ejemplo919, 2 -> 991
DanTheMan


Asistente de trigo, ¿qué cuadrícula se está utilizando?
tuskiomi

@tuskiomi "Sin embargo, no puedes hacer una ranura en 2 o hacer nuevas ranuras entre las existentes"
Post Rock Garf Hunter

Respuestas:


7

JavaScript (ES6), 297 286 279 267 bytes

Toma entrada en la sintaxis de curry (s)(k), donde s es una matriz de caracteres de dígitos yk es el número de movimientos (entero).

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

Casos de prueba


¿Cómo?

Datos de forma y función auxiliar

  • La matriz b describe las formas de los dígitos como enteros de 7 bits, donde cada bit es un segmento:

    7 segmentos

    Por ejemplo, la forma de "7" es 0b0100101 = 37.

  • La función auxiliar B () devuelve el número de 1 en la representación binaria de un número dado:

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

Paso 1

Primero contamos el número de fósforos utilizados en el número de entrada:

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

Paso 2

Pasamos este valor a la función recursiva g () , que llena una lista r con todos los números que se pueden construir con exactamente este número de fósforos:

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

Por ejemplo, g (5) se cargará [ '17', '2', '3', '5', '71' ]en r .

Paso 3

Ahora tenemos que seleccionar el número más alto M en r que realmente se puede obtener del número de entrada, dentro del número permitido de movimientos k .

Debido a que cada número n en r usa exactamente tantos fósforos como el número de entrada s , el número de movimientos necesarios para transformar s en n es igual a mitad del número de diferencias de segmento entre cada uno de sus dígitos.

El número de diferencias de segmento entre dos dígitos x e y viene dado por el número de 1 en la representación binaria de b [x] XOR b [y] .

Finalmente, es importante tener en cuenta que necesitamos probar varias alineaciones posibles de dígitos, porque el primer dígito de s no está necesariamente asignado al primer dígito de n . El cambio entre los dígitos viene dado por la variable j en el código.


1

Mathematica, 188 197 200 203 170 174 bytes

NOTA: El código todavía tiene errores. Estoy trabajando en ello.

+30 bytes para error

(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)&

El carácter entre %y odebería ser, 0x7Fpero SE no lo permitirá. Puede hacer clic en el enlace pastebin para copiar el código original.

El código lleva mucho tiempo cuando hay más de 6-7 palos. (Puede modificar el valor inicial de ia un número menor para probarlo)

Explicación

ges una función auxiliar convertir los dígitos en una lista de representación stick (según aquí ), tal como {1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1}para 220.

h es una función auxiliar para tratar el relleno izquierdo y el relleno derecho entre dos números.

fitera desde 10^Tr@g@#(límite superior) para 1buscar un número entero cuya representación de palo tiene la misma cantidad 1 -> 0y se 0 -> 1compara con el número original y la cantidad es menor o igual que el segundo argumento.


Te di un +1 porque nunca he visto que una respuesta ganadora tenga una puntuación tan baja como la otra respuesta. Supongo que es porque es la falta de opciones de prueba en línea. Tal vez algunas personas que tienen Mathematica podrían venir y probarlo y verificar que funciona bien, para que puedan obtener más votos a favor. O tal vez alguien podría convertirlo a Octave si es posible.
geokavel
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.