Encuentre la representación más corta de un número en SNUSP modular

10

Antecedentes

Muchos lenguajes de programación esotéricos no tienen números incorporados en literales, por lo que debe calcularlos en tiempo de ejecución; y en muchos de estos casos, la representación numérica puede ser bastante interesante. Ya hemos tenido el desafío de representar números para Underload. Este desafío se trata de representar números en SNUSP modular . (Tenga en cuenta que no necesita aprender SNUSP para completar este desafío, toda la información que necesita está en la especificación, pero puede encontrar interesantes los antecedentes).

La tarea

Para el propósito de este desafío, un número SNUSP modular es una cadena formada por los caracteres @, +y =, excepto que el último carácter es un #, y que el penúltimo carácter debe ser +o =(no puede ser @). Por ejemplo, números válidos incluyen @+#, ==#y @@+@=#; ejemplos de números no válidos incluyen +=, @@#, y +?+#.

El valor de un número SNUSP modular se calcula de forma recursiva de la siguiente manera:

  • # tiene un valor de 0 (este es el caso base).
  • Si el número tiene la forma =x, para cualquier cadena x, su valor es igual al valor de x.
  • Si el número tiene la forma +x, para cualquier cadena x, su valor es igual al valor de x, más 1.
  • Si el número tiene la forma @cx, para cualquier carácter individual cy cualquier cadena x, su valor es igual al valor de x, más el valor de cx.

Para este desafío, debe escribir un programa que tome un entero no negativo como entrada y genere una cadena que sea el número SNUSP modular más corto posible que tenga un valor igual a la entrada.

Aclaraciones

  • Es completamente posible que haya más de una cadena con el mismo valor, y en particular, para algunos enteros habrá un empate para el número SNUSP modular más corto con ese valor. En tal caso, puede generar cualquiera de los números involucrados con el empate.
  • No hay restricción en el algoritmo que usa para encontrar el número; por ejemplo, las cadenas de fuerza bruta y su evaluación es una táctica legal, pero también lo está haciendo algo más inteligente para reducir el espacio de búsqueda.
  • Como es habitual en PPCG, su envío puede ser un programa completo o una función (elija el que sea más conciso en su idioma).
  • Este no es un problema sobre el manejo de formatos de entrada y salida, por lo que puede usar cualquier medio razonable para ingresar un entero no negativo y generar una cadena. Hay una guía completa sobre meta , pero los métodos legales más comúnmente utilizados incluyen argumentos / retornos de función, argumentos de línea de comando y entrada / salida estándar.

Casos de prueba

Aquí están las representaciones más cortas de los primeros números:

  • 0 :#
  • 1 :+#
  • 2 :++#
  • 3 : +++#o@++#
  • 4 : ++++#o +@++#o@=++#
  • 5 : @+++#o@@++#
  • 6 : +@+++#o +@@++#o @=+++#o @=@++#o@@=++#
  • 7 : @++++#o@+@++#
  • 8 : @@+++#o@@@++#
  • 9 : +@@+++#o +@@@++#o @+++++#o @++@++#o @+@=++#o @@=+++#o@@=@++#
  • 10 : @=@+++#o @=@@++#o @@@=++#( este es un caso de prueba bastante importante para verificar , ya que todas las respuestas posibles incluyen =)
  • 11 : @+@+++#o @+@@++#o @@++++#o@@+@++#
  • 12 : +@+@+++#o +@+@@++#o +@@++++#o +@@+@++#o @=+@+++#o @=+@@++#o @=@=+++#o @=@=@++#o @=@@=++#o @@=++++#o @@=+@++#o@@=@=++#
  • 13 : @@@+++#o@@@@++#
  • 14 : +@@@+++#o +@@@@++#o @=@++++#o @=@+@++#o @@+++++#o @@++@++#o@@+@=++#
  • 15 : @+@++++#o @+@+@++#o @@=@+++#o @@=@@++#o @@@=+++#o@@@=@++#

Como caso de prueba más grande, la salida de la entrada 40 debe ser @@@=@@+++#, @@@=@@@++#, @@@@=@+++#, o @@@@=@@++#.

Condición de victoria

Como desafío de , el ganador es la entrada más corta, medida en bytes.

Comunidad
fuente
1
=óptimamente solo ocurrirá como @=, ¿verdad?
orlp
3
Por cierto, este tipo de desafíos generalmente se publican mejor como metagolf , ya que casi no habrá una respuesta interesante (solo evalúe la cadena y el bucle sobre todas las cadenas posibles).
orlp
3
@orlp: No estoy de acuerdo, este desafío sería demasiado fácil como metagolf, ya que encontrar una respuesta óptima es relativamente fácil, y metagolf no impone ninguna otra restricción en la puntuación. Espero que la mayoría de las respuestas aquí sean de fuerza bruta, pero la especificación es lo suficientemente compleja como para que la fuerza bruta a) no sea más corta yb) sea interesante para el golf por derecho propio. Si quería un cambio en la condición de victoria, probablemente el único otro interesante es el código más rápido , y eso tendría más sentido como un desafío diferente.
También hemos tenido un gran desafío de golf para Brain-flak
solo ASCII

Respuestas:

3

Oracle SQL 11.2, 341 262 bytes

WITH e AS(SELECT DECODE(LEVEL,1,'=',2,'@','+')e FROM DUAL CONNECT BY LEVEL<4),n(s,v,p,c,i)AS(SELECT'#',0,0,e,1 FROM e UNION ALL SELECT c||s,DECODE(c,'+',1,'@',p,0)+v,v,e,i+1 FROM n,e WHERE i<11)CYCLE s SET y TO 1 DEFAULT 0 SELECT s FROM n WHERE:1=v AND rownum=1;

Versión antigua

WITH e AS(SELECT DECODE(LEVEL,1,'=',2,'@','+')e FROM DUAL CONNECT BY LEVEL<4),n(s,v,p,c) AS(SELECT'#',0,0,e FROM e UNION ALL SELECT s||c,CASE c WHEN'+'THEN 1 WHEN'='THEN 0 WHEN'@'THEN p ELSE 0 END+v,v,e FROM n,e WHERE LENGTH(s)<10)CYCLE s SET y TO 1 DEFAULT 0 SELECT MIN(REVERSE(s))KEEP(DENSE_RANK FIRST ORDER BY LENGTH(s))FROM n WHERE v=:1;

: 1 el número a representar en SNUSP modular

Sin golf:

WITH e AS (SELECT DECODE(LEVEL,1,'=',2,'@','+')e FROM DUAL CONNECT BY LEVEL<4),  
n(s,v,p,c,i) AS                   
(
  SELECT '#',0,0,e,1 FROM e
  UNION ALL
  SELECT s||c
       , DECODE(c,'+',1,'@',p,0)+v 
       , v
       , e
       , i+1
  FROM n,e
  WHERE i<11
) CYCLE s SET y TO 1 DEFAULT 0
SELECT s FROM n WHERE:1=v AND rownum=1;

Primero cree una vista con 3 líneas, una para cada símbolo usado para representar números, menos # que solo se usa al final de la cadena:

SELECT DECODE(LEVEL,1,'=',2,'@','+')e FROM DUAL CONNECT BY LEVEL<4;    

Luego, la vista recursiva n genera todas las cadenas posibles con esos 3 símbolos, los concatena en # y los evalúa.

Los parámetros son:

s: la representación SNUSP modular del número que se está evaluando
v: el valor decimal de s calculado por la iteración anterior
p: v calculado por la iteración i-2
c: el siguiente símbolo para concatenar a s
i: la longitud de s, solo necesario para deshacerse de dos LONGITUD () para jugar al golf

DECODE(c,'+',1,'@',p,0)+v 

Si el último símbolo es +, agregue 1.
Si es @, agregue el valor de la iteración i-2. De lo
contrario, el símbolo es # o =. v se inicializa con 0 en la parte inicial de la vista recursiva, por lo que la nueva v es igual a la v anterior en cualquier caso.

WHERE i<11

Se calcula cada cadena posible con los 3 símbolos, esta parte asegura que la solicitud no se ejecute hasta el gran crujido.

CYCLE s SET y TO 1 DEFAULT 0

Como no hay una regla para la construcción de las cadenas, es probable que surjan duplicados. Al estar en una vista recursiva, Oracle interpreta esos duplicados como ciclos y arroja un error si el caso no se atiende explícitamente.

SELECT s FROM n WHERE:1=v AND rownum=1;

Devuelve la primera representación SNUSP modular que evalúa el número decimal ingresado como parámetro: 1

En mis pruebas, esa primera línea siempre es una de las representaciones más cortas.

En el caso de que su base de datos no actúe de la misma manera, entonces esa última cláusula debe ser reemplazada por

SELECT MIN(s)KEEP(DENSE_RANK FIRST ORDER BY i)FROM n WHERE:1=v
Jeto
fuente
2

JavaScript (ES6), 100 bytes

n=>eval("for(a=[['#',0,0]];[[s,t,p],...a]=a,t-n;)a.push(['='+s,t,t],['+'+s,t+1,t],['@'+s,t+p,t]);s")

Algoritmo simple de búsqueda de amplitud de fuerza bruta.

Neil
fuente
Para 40, devuelve "@@@@@@ = ​​++ #", que se evalúa en 42
aditsu se cierra porque SE es MALO
Incluso para 12 da "@@@ +++ #", que se evalúa como 13
aditsu se cierra porque SE es MALO
Hmm, creo que cambiar t<na t-npodría funcionar ...
Neil
2

Pyth, 41 bytes

L?b+ytb@[yttb001)Chb0+hfqQyTs^L"+@="UhQ\#

Banco de pruebas

Cómo funciona:

Hay dos partes Una función recursiva que calcula el valor de una expresión SNUSP sin el final #, y una rutina de fuerza bruta.

Evaluación:

L?b+ytb@[yttb001)Chb0
L                        Define the function y(b) as follows
 ?b                      If b is nonempty
   +ytb                  The sum of y(tail(b)) and   # tail(b) = b[1:]
   @[       )            The element in the list at location
   Chb                   Character values of the first character.
                         Modular indexing means that 
                         + -> 3
                         @ -> 0
                         = -> 1
                         Index 2 is filler.
    [yttb001)            @ adds y(tail(tail(b)). Tail suppresses the error when
                         called on an empty list, so this treats @# as zero, but
                         this can't lead to problems because removing the @ will
                         always make the expression shorter.
                         + adds 1, = adds 0.
 0                       If b is the empty string, return 0

Fuerza bruta:

+hfqQyTs^L"+@="UhQ\#
               UhQ      0 ... Q     # Q is the input
        ^L"+@="         Map that list to all strings formed from the characters
                        "+@=", with that many characters.
       s                Concatenate
  fqQyT                 Filter for strings which evaluate to the input
 h                      Take the first success, which is the shortest due to
                        the order the strings were generated.
+                 \#    Add a '#' and output
isaacg
fuente
1

CJam, 58

ri:M;'#0_]]{_{M&}#_)!}{;{~[2,+1$f+"@=+"\]z\f+\af.+~}%}w=0=

Fuerza bruta, con un poco de inspiración de la respuesta de Neil. Pruébalo en línea

Versión eficiente, 107

ri0"#"a{_{:B\:A={'=A0j+}{A(B={'+B0j+}{AB>{BAB-j_N={'@\+}|}N?}?}?}{;_(0j'+\+a\,1>_W%.{j}Na-'@\f++{,}$0=}?}2j

Pruébalo en línea

Esto usa programación dinámica.

aditsu renunció porque SE es MALO
fuente
1

Haskell , 89 86 bytes

EDITAR:

  • -3 bytes: la compresión fue más corta que la indexación.

Otra solución de fuerza bruta que terminó con mucha inspiración de la respuesta de Neil. (Aunque funcionó más como el Pyth de Isaac antes de que el golf introdujera el l.)

f n=[s|(a,_,s)<-l,a==n]!!0
l=(0,0,"#"):[(a+c,a,d:s)|(a,b,s)<-l,(c,d)<-zip[0,1,b]"=+@"]

Pruébalo en línea!

  • f es la función principal, que toma un número entero y devuelve una cadena.
  • les una lista infinita de tuplas (a,b,s), las representaciones más cortas sprimero, junto con su valor ay el valor bde la representación con el primer carácter despojado. (como otros también han notado / notado, es inofensivo tratar a este último como 0 #).
  • Los elementos de lotro que el primero se generan de forma recursiva con una comprensión de la lista. des el carácter que se va a anteponer para sgenerar una nueva representación en la lista, y 'c' es el incremento correspondiente a a.
Ørjan Johansen
fuente