Explicação
O Befunge é um programa bidimensional que utiliza pilhas .
Isso significa que, para fazer 5 + 6, você escreve 56+
, significando:
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)
No entanto, como os inteligentes de vocês observaram, não podemos colocar o número 56
diretamente na pilha.
Para isso, devemos escrever 78*
em vez disso, que se multiplica 7
e 8
e empurra o produto para a pilha.
Detalhes
A entrada pode ser obtida em qualquer formato, o que significa que pode ser STDIN ou não, a critério do programador.
A entrada será um número inteiro positivo (nenhum bônus para 0
números inteiros ou negativos).
A saída será uma string composta apenas por esses caracteres: 0123456789+-*/
(eu não usaria o %
módulo.)
O objetivo é encontrar a string mais curta que possa representar a entrada, usando o formato descrito acima.
Por exemplo, se a entrada for 123
, a saída seria 67*99*+
. A saída deve ser avaliada da esquerda para a direita.
Se houver mais de uma saída aceitável (por exemplo, 99*67*+
também é aceitável), qualquer uma poderá ser impressa (sem bônus por imprimir todas elas).
Explicação adicional
Se você ainda não entende como 67*99*+
avalia 123
, aqui está uma explicação detalhada.
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
O programa precisa encontrar a string mais curta que possa representar a entrada (número), usando o formato especificado acima.
Notas
Este é um desafio de código-golfe , portanto o código mais curto em bytes vence.
Desambiguação
O -
pode ser x-y
ou y-x
, a critério do programador. No entanto, a escolha deve ser consistente dentro da solução. Da mesma forma para o /
.
Programa de exemplo
Lua, 1862 bytes ( experimente online )
Como sou o autor, não jogarei nada.
Explicação:
This uses the depth-first search method.
Mais sobre a pesquisa em profundidade: aqui .
O 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
Bônus
Um bolo para você, se você usar o Befunge (ou qualquer outra variante) para escrever o código.
fonte
Respostas:
Python 2, 278 bytes
Minha melhor solução, que sempre dá a menor resposta. (mas muito lento)
Python 2, 437 bytes
Esta solução é mais longa, mas muito rápida (não força bruta). E tenho certeza de que sempre retorna o menor resultado possível.
fonte
f(6551)
retorna25*8*9*7+9*8+
(13 caracteres), enquanto9999***52*-
(11 caracteres) é melhor. Verificado com minha própriaeval
função acima (na pergunta).while c:
;
para separar atribuições a variáveis (que economizam bytes em blocos recuados), dica de ven, se livrar do espaço em branco entre um símbolo e qualquer outra coisa, et
pode ir.Perl,
134133132128 bytesInclui +5 para
-Xlp
(2 extras porque o código contém'
)Execute com o número de destino em STDIN:
befour.pl
:Ele não tem limites artificiais e é conceitualmente um tanto eficiente, mas possui tempos de execução terríveis, apesar de eu ter sacrificado alguns bytes para acelerar. A geração de uma solução 11 (por exemplo, número de destino 6551) leva cerca de 5 horas no meu sistema.
Sacrificar mais 7 bytes torna a velocidade um pouco mais suportável.
17 minutos para uma solução de comprimento 11, cerca de 5 horas para uma solução de comprimento 13. O primeiro número que precisa do comprimento 15 é 16622, o que leva cerca de 2 dias. O primeiro número que precisa do comprimento 17 é 73319.
Observe que ele assume que a divisão retorna um número inteiro truncando para 0 (conforme a especificação 93 do befunge)
fonte
$
acessa o valor escalar. Onde na maioria dos idiomas você escreveriaa=4
, o perl usará$a=4
. Mas também é usado para um acesso escalar de variáveis mais complexas. Por exemplo,$a{$b}
obtém do hash (mapa, dicionário)%a
o valor escalar digitado em$b
C,
550545 bytes550545 bytes após a exclusão das novas linhas desnecessárias (todas, exceto as três novas linhas após as diretivas de pré-processamento).@Kenny Lau - Ele pode receber como entrada um número inteiro entre 1 e 9998, mas acho que o intervalo de entrada para o qual uma solução ideal é calculada é menor que 9998. Por outro lado, os dois intervalos podem ser estendidos, se a memória permite.
O programa não pode enviar para a pilha nenhum número superior a 9998. (9998 pode ser modificado.) Executei o programa em uma versão diferente, repetindo o loop externo (aquele com k) enquanto houver melhoria para qualquer número entre 1 e 9998 (como no algoritmo de Dijkstra). Após três iterações, não há melhorias. Então, para economizar bytes, codifiquei k = 3.
Para estender o intervalo, são necessárias duas coisas - modificar as constantes 9999 e 9998, executando-o com um número variável de iterações no loop externo pelo tempo que houver melhorias, para ver quanto tempo leva até que nenhuma melhoria ocorra. modifique a constante k = 3 para esse valor.
fonte
i
,j
ek
antesmain()
.Python 2, 284 bytes
Isenção de responsabilidade: Demora uma eternidade para alguns valores ... mas deve- se garantir que sempre retorne a string mais curta e não tenha limite de intervalo artificialmente imposto ... até funciona com valores negativos. :)
Algoritmo:
i = 0
i
e substituaabcd
por+-*/
respectivamente e remova qualqueref
i
e tente novamente.fonte
f(i)
de0 <= i <= 6551
(para capturar o6551
valor que você usado para invalidar @pbochniak de submissão original). No momento, ele está em execução há apenas alguns minutos, e aqui está a última saída do teste:91 : 49+7* 3.020 s (total 108.174 s, worst 89: 5.827 s)
Atualização - acabou de terminar com o valor 92:92 : 149+7*+ 258.761 s (total 366.935 s, worst 92: 258.761 s)
113
... ver saída de teste completo aqui (pastebin) Se você estiver interessado ...Python 2, 182 bytes
Tão obscenamente lento, deixei-o funcionando por uma hora na entrada
221
e ele ainda não terminou. Uma grande parte da lentidão é porque eu estou usando uma lista como uma fila para uma pesquisa em largura, e.pop(0)
éO(n)
para listas.L
é apenas uma fila contendo(stack, code to reach stack)
pares. A cada etapa, os dígitos são sempre adicionados e os operadores são executados se a pilha tiver pelo menos dois elementos. A divisão só é executada se o último elemento não for 0, embora eu tenha uma forte suspeita de que a divisão nunca seja necessária (embora eu não tenha como provar isso, mas verifiquei que esse é o caso até 500).O programa termina através de um
NameError
após a impressão do resultado (eventualmente).fonte
;E
o final está fazendo?NameError
rescisão, já queE
não está definida em nenhum outro lugarCJam, 79
Experimente online
Isso é terrivelmente ineficiente, mas, com tempo e memória suficientes, ele finalmente funciona. 123 fica sem memória com 16 GB, mas 120 e 125 estão ok.
fonte
Pitão - 35 bytes
Força bruta. Uma coisa estranha é que a nova entrada implícita realmente prejudica minha pontuação, porque parece estar funcionando
.v
também para pyth_eval.Experimente online aqui .
fonte
Python 3, 183 bytes
A velocidade não é totalmente irracional (123, 221, 1237, 6551 terminam na ordem de segundos ou minutos). Alterar a
if
instrução paraif j<=i and <k<2*n
acelerar mais, ao custo de mais 9 bytes. Eu deixei de fora a divisão (/
), porque não consigo ver como seria necessário.fonte