Rompecabezas dos-cero-uno-cinco

13

Antecedentes

Este acertijo es una variación del acertijo de cuatro patas (el tema de una pregunta pasada ). Al igual que ese rompecabezas, el objetivo es encontrar expresiones matemáticas para diferentes números enteros, utilizando solo cuatro dígitos y ciertos operadores matemáticos. En este caso, sin embargo, los dígitos permitidos son solo 2, 0, 1 y 5 . Cada uno debe aparecer precisamente una vez en la solución y en el orden correcto. Sorprendentemente, muchos números enteros se pueden representar de esta manera. Se recomienda a los solucionadores que intenten resolverlo a mano primero, ya que es extrañamente divertido.

Reglas

Las constantes pueden construirse a partir de dígitos simples o múltiples:

  • Enteros: por ejemplo, 2, 0, 15, etc.
  • Decimales: por ejemplo, .2, .01, 1.5, etc.
  • Decimales periódicos : por ejemplo, 0,2 ~ (= 0,222 ...), 0,15 ~ (= 0,1555 ...), 20.15 ~~ (= 20,1515 ...)

Se permiten las siguientes operaciones unarias:

  • Negación unaria: -x
  • Raíz cuadrada: sqrt (x)
  • Factorial entero: x!

Se permiten las siguientes operaciones binarias:

  • Operadores aritméticos estándar: x + y, xy, x * y y x / y
  • Exponenciación arbitraria: x ^ y
  • Raíces arbitrarias: rt [x] (y) (= raíz x de y)

Tarea

Su programa debe imprimir expresiones para todos los enteros entre 0 y 100 que pueda, y luego generar el número de expresiones que ha producido.

  • Las soluciones deben imprimirse en orden en el formato n = [expr].
  • Las expresiones deben usar todos los dígitos 2, 0, 1, 5, una vez en cada orden.
  • Las expresiones deben imprimirse utilizando la notación descrita anteriormente. Los paréntesis innecesarios están permitidos pero no son obligatorios, al igual que los espacios en blanco. El orden de precedencia del operador es negación unaria, factorial, exponenciación, multiplicación / división y suma / resta.
  • El programa no necesita devolver soluciones para todos los números. Por lo tanto, un programa que simplemente genera 0 es válido; sin embargo, vea la sección de puntuación a continuación.
  • El programa debería ejecutarse en menos de 15 minutos en una computadora moderna.

Puede escribir un programa o función. Las expresiones deben imprimirse en STDOUT (o la alternativa más cercana). El número de expresiones puede imprimirse en STDOUT o devolverse como un entero. Se aplican restricciones de código estándar de golf.

Salida de ejemplo

0=2*0*1*5
10=20*1*.5
42=((2+0!)!+1)!/5!
100=20*1*5
4

Puntuación

Actualización : @orlp ha notado una falla en el sistema de puntuación. Ver http://meta.codegolf.stackexchange.com/questions/5106/way-of-salvaging-two-zero-one-five-puzzle-challenge para una discusión sobre cómo o si esto debería solucionarse.

Las soluciones se puntúan primero por el número de expresiones que producen y luego por la longitud de su código en bytes. Por lo tanto, un programa de 1000 bytes que produce 80 resultados superará a un programa de 100 bytes que produce solo 79 (aunque este último podría ampliarse fácilmente para incluir los resultados faltantes).

Para aquellos que desean un objetivo motivador, a continuación hay un límite inferior en la cantidad de expresiones que se pueden representar. No planeo enviar una entrada, ¡así que puede ser posible ganar con menos!

Al menos 85 (de 101), aunque puede ser más alto.

Marcador

Como incentivo adicional, aquí hay un resumen de la progresión de la puntuación. Cada vez que supere la puntuación más alta, siéntase libre de agregarse a la cima de la tabla (o pedirle a alguien más que lo haga).

  • 0 expresiones, 1 byte (Pyth): implementación que solo genera 0
Uri Granta
fuente
¿Es .20 una constante permitida?
Lucas
1
@Luke: sí, aunque también se puede representar como (.2 + 0) para que no aumente la expresividad
Uri Granta
1
@orlp Tenga en cuenta que los ceros iniciales y las fracciones mayores que cero no agregan ninguna expresividad: por ejemplo, 015 = 0 + 15 y 1.5 = 1 + .5.
Uri Granta
1
@ mbomb007 Eso es demasiado complicado. Aquí hay una explicación rápida que escribí: gist.github.com/orlp/e92b3b7d26ad9b11378e
orlp
2
@UriZarfaty Luego hay 99 conjuntos distintos de constantes útiles: gist.github.com/orlp/eb997e49e41878c76d0a
orlp

Respuestas:

9

85, ~ 2400 bytes

Estoy un poco triste porque este es un desafío de código de golf, ya que siento que todos mis esfuerzos anteriores han sido bastante inútiles ahora que voy a publicar esto:

  0 = ((2*0)^15)
  1 = ((2^0)^15)
  2 = (2-(0^15))
  3 = (20*.15)
  4 = (20*(1/5))
  5 = (20-15)
  6 = ((.20+1)*5)
  7 = ((20*.1)+5)
  8 = (2*((0-1)+5))
  9 = ((.20/.1~)*5)
 10 = (20/(1/.5))
 11 = ((((2-0)+1))!+5)
 12 = (20*(.1+.5))
 13 = ((-(2)-0)+15)
 14 = (20-(1+5))
 15 = ((2*0)+15)
 16 = ((2^0)+15)
 17 = ((2-0)+15)
 18 = (20-(1/.5))
 19 = (20-(1^5))
 20 = (20^(1^5))
 21 = (20+(1^5))
 22 = (20+(1/.5))
 23 = (((2-0)/.1~)+5)
 24 = ((20-1)+5)
 25 = ((20^1)+5)
 26 = ((20+1)+5)
 27 = (rt[.2](((0)!+1))-5)
 28 = (2*(-((0)!)+15))
 29 = ((((2+(0)!)+1))!+5)
 30 = ((2-0)*15)
 31 = (20+sqrt((1+(5)!)))
 32 = ((20*.1)^5)
 33 = ((.2^-((0)!))/.15~~)
 34 = (2+(((0)!+1)^5))
 35 = (20+15)
 36 = (20*(1/.5~))
 37 = (rt[.2](((0)!+1))+5)
 38 = ((20-1)/.5)
 39 = (-((2^0))+(sqrt(.1~)*(5)!))
 40 = (20*(1/.5))
 41 = (((.2~^-((0)!))/.1~)+.5)
 42 = ((20+1)/.5)
 43 = (-(2)+(((0)!/.1~)*5))
 44 = (20+((-(1)+5))!)
 45 = (20/(1-.5~))
 46 = ((.2+((0)!/.1~))*5)
 47 = (2+(((0)!/.1~)*5))
 48 = (2*(((0-1)+5))!)
 49 = ((((2+(0)!))!/.1~)-5)
 50 = (((2^0)/.1)*5)
 51 = ((.2+((0)!/.1))*5)
 52 = (2+(((0)!/.1)*5))
 54 = (((2+(0)!)/.1)/.5~)
 55 = ((2+((0)!/.1~))*5)
 56 = (((.2-(0)!)+sqrt(.1~))*-((5)!))
 58 = (-(2)+sqrt((((((0)!/sqrt(.1~)))!)!*5)))
 59 = ((((2+(0)!))!/.1~)+5)
 60 = (20/(.1~^.5))
 62 = (2*(-((0)!)+sqrt(rt[-(.1)](.5))))
 64 = ((2-0)^(1+5))
 65 = ((20/sqrt(.1~))+5)
 66 = ((-(((2+(0)!))!)/.1~)+(5)!)
 67 = (((((2+(0)!))!)!*.1)-5)
 69 = ((2^(((0)!/sqrt(.1~)))!)+5)
 70 = (((.2^-((0)!))/-(.1))+(5)!)
 72 = ((2+(0)!)*((-(1)+5))!)
 75 = ((.2^-((0)!))*15)
 76 = (rt[(-(2)^-((0)!))](.1~)-5)
 77 = (((((2+(0)!))!)!*.1)+5)
 78 = (2*(-((0)!)+(sqrt(.1~)*(5)!)))
 80 = (-(20)*(1-5))
 81 = (201-(5)!)
 82 = (2*((0)!+(sqrt(.1~)*(5)!)))
 84 = (((.2-(0)!)+.1)*-((5)!))
 85 = (((((2+(0)!))!)!*.1~)+5)
 86 = (rt[(-(2)^-((0)!))](.1~)+5)
 88 = (rt[.2]((-((0)!)-1))+(5)!)
 90 = ((20/.1~)*.5)
 93 = (((2+(0)!)/-(.1~))+(5)!)
 95 = ((20-1)*5)
 96 = ((.20-1)*-((5)!))
 98 = (-(20)*(.1-5))
 99 = ((-(20)-1)+(5)!)
100 = (20/(1/5))
85

De aquí en adelante es solo un desafío de compresión. Tal vez competiré más tarde, tal vez no. Para mí, la mayor parte de la diversión estaba en el desafío de encontrar la mayoría de las fórmulas.

Una pista para aquellos que luchan por escribir un solucionador: el tiempo de ejecución no debería ser un problema. Si tiene demasiadas fórmulas para verificar, necesita mejores heurísticas para desechar soluciones y duplicados sin remedio. El código que escribí para generar lo anterior se ejecuta en ~ 5 segundos en Python.

orlp
fuente
rt [.1] (-. 5) es la raíz 0.1a de -0.5, no la raíz -0.5a ​​de 0.1.
Uri Granta
Además, empiezo a sospechar que el ganador puede ser una salida de texto comprimido. Debería haber pensado en una mejor manera de evitar eso :-(
Uri Granta
@UriZarfaty Oh, lo arreglaré en mi código y volveré a ejecutar, dame un segundo.
orlp
Había sobreestimado significativamente cuán grande sería la salida en comparación con el tamaño del programa. Dada la pequeña gama de caracteres y paréntesis superfluos, supongo que la solución realmente se comprimirá demasiado bien.
Uri Granta
1
@ mbomb007 No hice ningún intento de limpiarlo, y creo que el código en el estado actual está roto; intente descomentar algunas cosas: gist.github.com/orlp/878da16b5b7c650ebd09 .
orlp