Explicación
Befunge es un programa bidimensional que utiliza pilas .
Eso significa que, para hacer 5 + 6, escribes 56+
, lo que significa:
56+
5 push 5 into stack
6 push 6 into stack
+ pop the first two items in the stack and add them up, and push the result into stack
(to those of you who do not know stacks, "push" just means add and "pop" just means take off)
Sin embargo, como han observado los inteligentes, no podemos insertar el número 56
directamente en la pila.
Para ello, debemos escribir 78*
en su lugar, lo que multiplica 7
y 8
y empuja el producto en la pila.
Detalles
La entrada puede tomarse en cualquier formato, lo que significa que puede ser STDIN o no, a discreción del programador.
La entrada será un entero positivo (sin bonificación por incluir 0
o enteros negativos).
La salida será una cadena formada únicamente por los caracteres: 0123456789+-*/
(yo no uso %
. Módulo)
El objetivo es encontrar la cadena más corta que pueda representar la entrada, utilizando el formato descrito anteriormente.
Por ejemplo, si la entrada es 123
, entonces la salida sería 67*99*+
. La salida debe evaluarse de izquierda a derecha.
Si hay más de una salida aceptable (por ejemplo, 99*67*+
también es aceptable), se puede imprimir cualquiera (no hay bonificación por imprimirlas todas).
Explicación adicional
Si aún no comprende cómo se 67*99*+
evalúa 123
, aquí hay una explicación detallada.
stack |operation|explanation
67*99*+
[6] 6 push 6 to stack
[6,7] 7 push 7 to stack
[42] * pop two from stack and multiply, then put result to stack
[42,9] 9 push 9 to stack
[42,9,9] 9 push 9 to stack
[42,81] * pop two from stack and multiply, then put result to stack
[123] + pop two from stack and add, then put result to stack
TL; DR
El programa necesita encontrar la cadena más corta que pueda representar la entrada (número), utilizando el formato especificado anteriormente.
Notas
Este es un desafío de código de golf , por lo que gana el código más corto en bytes.
Desambiguación
El -
puede ser x-y
o y-x
, a discreción del programador. Sin embargo, la elección debe ser coherente dentro de la solución. Asimismo para el /
.
Programa de muestra
Lua, 1862 bytes ( pruébelo en línea )
Como soy el autor, no jugaré golf en absoluto.
Explicación:
This uses the depth-first search method.
Más sobre la búsqueda en profundidad: aquí .
El programa:
local input = (...) or 81
local function div(a,b)
if b == 0 then
return "error"
end
local result = a/b
if result > 0 then
return math.floor(result)
else
return math.ceil(result)
end
end
local function eval(expr)
local stack = {}
for i=1,#expr do
local c = expr:sub(i,i)
if c:match('[0-9]') then
table.insert(stack, tonumber(c))
else
local a = table.remove(stack)
local b = table.remove(stack)
if a and b then
if c == '+' then
table.insert(stack, a+b)
elseif c == '-' then
table.insert(stack, b-a)
elseif c == '*' then
table.insert(stack, a*b)
elseif c == '/' then
local test = div(b,a)
if test == "error" then
return -1
else
table.insert(stack, a+b)
end
end
else
return -1
end
end
end
return table.remove(stack) or -1
end
local samples, temp = {""}, {}
while true do
temp = {}
for i=1,#samples do
local s = samples[i]
table.insert(temp, s..'0')
table.insert(temp, s..'1')
table.insert(temp, s..'2')
table.insert(temp, s..'3')
table.insert(temp, s..'4')
table.insert(temp, s..'5')
table.insert(temp, s..'6')
table.insert(temp, s..'7')
table.insert(temp, s..'8')
table.insert(temp, s..'9')
table.insert(temp, s..'+')
table.insert(temp, s..'-')
table.insert(temp, s..'*')
table.insert(temp, s..'/')
end
for i=1,#temp do
if input == eval(temp[i]) then
print(temp[i])
return
end
end
samples = temp
end
Prima
Un pastel para ti si usas Befunge (o cualquier variante) para escribir el código.
fuente
Respuestas:
Python 2, 278 bytes
Mi mejor solución, que cada vez da la respuesta más corta. (pero muy lento)
Python 2, 437 bytes
Esta solución es más larga, pero muy rápida (no fuerza bruta). Y estoy bastante seguro, que siempre devuelve el resultado más corto posible.
fuente
f(6551)
devuelve25*8*9*7+9*8+
(13 caracteres), mientras que9999***52*-
(11 caracteres) es mejor. Verificado con mi propiaeval
función anterior (en la pregunta).while c:
;
para separar las asignaciones a las variables (lo que ahorra bytes en bloques con sangría), la sugerencia de ven, eliminar el espacio en blanco entre un símbolo y cualquier otra cosa, yt
puede ir.Perl,
134133132128 bytesIncluye +5 para
-Xlp
(2 extra porque el código contiene'
)Ejecutar con el número objetivo en STDIN:
befour.pl
:No tiene límites artificiales y es conceptualmente algo eficiente, pero tiene tiempos de ejecución terribles, aunque sacrifiqué algunos bytes para acelerarlo. Generar una solución de longitud 11 (por ejemplo, el número de destino 6551) toma alrededor de 5 horas en mi sistema.
Sacrificar 7 bytes más hace que la velocidad sea algo más soportable.
17 minutos para una solución de longitud 11, aproximadamente 5 horas para una solución de longitud 13. El primer número que necesita longitud 15 es 16622, que demora aproximadamente 2 días. El primer número que necesita longitud 17 es 73319.
Tenga en cuenta que supone que la división devuelve un entero truncando hacia 0 (según la especificación de befunge 93)
fuente
$
accede al valor escalar. Donde en la mayoría de los idiomas escribiríasa=4
, Perl lo usará$a=4
. Pero también se usa para un acceso escalar de variables más complejas. Por ejemplo,$a{$b}
extrae del hash (mapa, diccionario)%a
el valor escalar introducido$b
C,
550545 bytes550545 bytes después de eliminar las nuevas líneas innecesarias (todas menos las tres nuevas líneas después de las directivas de preprocesamiento).@Kenny Lau: puede recibir como entrada un número entero entre 1 y 9998, pero creo que el rango de entrada para el que se calcula una solución óptima es menor que 9998. Por otro lado, ambos rangos se pueden extender, si la memoria lo permite
El programa no puede empujar a la pila ningún número superior a 9998. (9998 se puede modificar). Ejecuté el programa en una versión diferente, iterando sobre el bucle externo (el que tiene k) mientras haya una mejora para cualquier número entre 1 y 9998 (como en el algoritmo de Dijkstra). Después de tres iteraciones no hay mejora. Entonces, para guardar bytes, codifiqué k = 3.
Para extender el rango, son necesarias dos cosas: modificar las constantes 9999 y 9998, ejecutarlo con un número variable de iteraciones sobre el bucle externo durante el tiempo que haya una mejora, para ver cuánto tiempo lleva hasta que no ocurra ninguna mejora, luego modifique la constante k = 3 a ese valor.
fuente
i
,j
yk
antesmain()
.Python 2, 284 bytes
Descargo de responsabilidad: se vuelve loco para siempre para algunos valores ... pero se debe garantizar que siempre devuelva la cadena más corta y no tiene un límite de rango impuesto artificialmente ... incluso funciona en valores negativos. :)
Algoritmo:
i = 0
i
y reemplácelaabcd
con+-*/
respectivamente, y elimine cualquieref
i
e intente nuevamente.fuente
f(i)
partir de0 <= i <= 6551
(para capturar el6551
valor que usó para invalidar el envío original de @pbochniak). En este momento, se ha estado ejecutando durante solo unos minutos, y aquí está el último resultado de la prueba:91 : 49+7* 3.020 s (total 108.174 s, worst 89: 5.827 s)
Actualización: acaba de terminar con el valor 92:92 : 149+7*+ 258.761 s (total 366.935 s, worst 92: 258.761 s)
113
... vea el resultado completo de la prueba aquí (pastebin) si está interesado ...Python 2, 182 bytes
Tan obscenamente lento, lo dejé funcionando durante una hora en la entrada
221
y todavía no ha terminado. Gran parte de la lentitud se debe a que estoy usando una lista como cola para una búsqueda de amplitud, y.pop(0)
esO(n)
para listas.L
es solo una cola que contiene(stack, code to reach stack)
pares. En cada paso, siempre se agregan dígitos y se realizan operadores si la pila tiene al menos dos elementos. La división solo se realiza si el último elemento no es 0, aunque tengo una fuerte sospecha de que la división nunca es necesaria (aunque no tengo forma de demostrarlo, pero he comprobado que este es el caso hasta 500).El programa finaliza mediante un
NameError
después de imprimir el resultado (eventualmente).fuente
;E
haciendo al final?NameError
terminación, yaE
que no está definida en ningún otro lugarCJam, 79
Pruébalo en línea
Esto es terriblemente ineficiente, pero dado suficiente memoria y tiempo, eventualmente funciona. 123 se queda sin memoria con 16 GB, pero 120 y 125 están bien.
fuente
Pyth - 35 bytes
Fuerza bruta. Una cosa extraña es que la nueva entrada implícita realmente daña mi puntaje porque parece estar funcionando
.v
también para pyth_eval.Pruébelo en línea aquí .
fuente
Python 3, 183 bytes
La velocidad no es totalmente irrazonable (123, 221, 1237, 6551 terminan en el orden de segundos o minutos). Cambiar el
if
enunciado paraif j<=i and <k<2*n
acelerarlo más, a costa de 9 bytes más. Dejé fuera la división (/
), porque no puedo ver cómo se necesitaría.fuente