объяснение
Befunge - это двумерная программа, использующая стеки .
Это означает, что для выполнения 5 + 6 вы пишете 56+
, что означает:
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)
Однако, как заметил ваш ум, мы не можем поместить число 56
прямо в стек.
Чтобы сделать это, мы должны написать 78*
вместо этого, который умножает 7
и 8
и помещает продукт в стек.
Детали
Ввод может быть сделан в любом формате, то есть может быть STDIN или нет, по усмотрению программиста.
На входе будет положительное целое число (без бонуса за включение 0
или отрицательное целое число ).
На выходе будет строка, состоящая только из этих символов: 0123456789+-*/
(я бы не использовал%
по модулю.)
Цель состоит в том, чтобы найти самую короткую строку, которая может представлять ввод, используя формат, описанный выше.
Например, если вход есть 123
, то выход будет 67*99*+
. Результат должен оцениваться слева направо.
Если имеется более одного приемлемого вывода (например 99*67*+
, также приемлемо), любой может быть напечатан (без бонуса за печать всех из них).
Дальнейшее объяснение
Если вы все еще не понимаете, как 67*99*+
оценивать 123
, вот подробное объяснение.
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
Программа должна найти самый короткий строку, которая может представлять ввод (число), используя формат, указанный выше.
Примечания
Это задача кода-гольфа , поэтому выигрывает самый короткий код в байтах.
Disambiguation
-
Может быть либо x-y
или y-x
, по усмотрению программиста. Тем не менее, выбор должен быть последовательным в рамках решения. Аналогично для /
.
Пример программы
Lua, 1862 байта ( попробуйте онлайн )
Поскольку я автор, я не буду играть в гольф вообще.
Объяснение:
This uses the depth-first search method.
Подробнее о поиске в глубину: здесь .
Программа:
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
бонус
Торт для вас, если вы используете Befunge (или любой другой вариант) для написания кода.
источник
Ответы:
Python 2, 278 байт
Мое лучшее решение, которое всегда дает кратчайший ответ. (но очень медленно)
Python 2, 437 байт
Это решение длиннее, но очень быстро (не грубой силой). И я совершенно уверен, что он всегда даст кратчайший результат.
источник
f(6551)
возвращает25*8*9*7+9*8+
(13 символов), а9999***52*-
(11 символов) лучше. Проверено с моей собственнойeval
функцией выше (в вопросе).while c:
;
для разделения назначений переменных (которые сохраняют байты в блоки с отступами), подсказку ven, избавиться от пробела между символом и чем-то еще, иt
можете идти.Perl,
134133132128 байтВключает +5 для
-Xlp
(2 дополнительных, потому что код содержит'
)Запустите с целевым номером на STDIN:
befour.pl
:Он не имеет искусственных ограничений и концептуально несколько эффективен, но, тем не менее, имеет ужасные времена выполнения, хотя я пожертвовал несколькими байтами, чтобы ускорить его. Генерация решения длины 11 (например, номер 6551) занимает в моей системе около 5 часов.
Принесение в жертву еще 7 байтов делает скорость несколько более терпимой.
17 минут для раствора длиной 11, около 5 часов для раствора длиной 13. Первое число, которому нужна длина 15, это 16622, что занимает около 2 дней. Первое число, которому нужна длина 17, - 73319.
Обратите внимание, что предполагается, что деление возвращает целое число путем усечения до 0 (согласно спецификации befunge 93)
источник
$
обращается к скалярному значению. Где бы на большинстве языков вы ни писалиa=4
, Perl будет использовать$a=4
. Но также используется для скалярного доступа к более сложным переменным. Например,$a{$b}
извлекает из хэша (карта, словарь)%a
скалярное значение, указанное на$b
C
550545 байт550545 байт после удаления ненужных строк новой строки (все, кроме трех строк новой строки после директив предварительной обработки).@Kenny Lau - Он может принимать в качестве входных данных целое число от 1 до 9998, но я думаю, что диапазон ввода, для которого вычисляется оптимальное решение, меньше, чем 9998. С другой стороны, оба диапазона могут быть расширены, если память позволяет это.
Программа не может вытолкнуть в стек любое число, большее 9998. (9998 можно изменить.) Я запускал программу в другой версии, повторяя итерацию по внешнему циклу (та, что с k), пока есть улучшения для любого числа между 1 и 9998 (как в алгоритме Дейкстры). После трех итераций улучшения не происходит. Таким образом, чтобы сохранить байты, я жестко закодировал k = 3.
Чтобы расширить диапазон, необходимы две вещи - изменение констант 9999 и 9998, запуск его с переменным числом итераций по внешнему циклу до тех пор, пока есть улучшение, чтобы увидеть, сколько времени потребуется, пока улучшение не произойдет, затем изменить константу к = 3 к этому значению.
источник
i
,j
иk
до тогоmain()
.Python 2, 284 байта
Отказ от ответственности: берет на себя волнение навсегда для некоторых значений ... но должна гарантированно всегда возвращать самую короткую строку и не имеет искусственно установленного предела диапазона ... даже работает на отрицательных значениях. :)
Алгоритм:
i = 0
i
, и заменитеabcd
на+-*/
соответственно, и удалитеef
i
и попробуйте снова.источник
f(i)
из0 <= i <= 6551
(захватить6551
значение , которое используется для аннулированию @pbochniak «s первоначального представления). Прямо сейчас он работает всего несколько минут, и вот последний результат теста:91 : 49+7* 3.020 s (total 108.174 s, worst 89: 5.827 s)
Обновление - он только что закончил со значением 92:92 : 149+7*+ 258.761 s (total 366.935 s, worst 92: 258.761 s)
113
полной стоимости ... смотрите полный тестовый вывод здесь (pastebin), если вам интересно ...Python 2, 182 байта
Так непристойно медленно я оставил его включенным в течение часа при вводе,
221
и он все еще не завершился. Большое медлительности, потому что я использую список в виде очереди за поиск в ширину, и.pop(0)
этоO(n)
для списков.L
это просто очередь, содержащая(stack, code to reach stack)
пары. На каждом шаге всегда добавляются цифры, и операторы выполняются, если в стеке есть хотя бы два элемента. Деление выполняется только в том случае, если последний элемент не равен 0, хотя у меня есть сильное подозрение, что деление никогда не требуется (хотя у меня нет способа доказать это, но я проверил, что это случай до 500).Программа завершается через
NameError
после печати результата (в конце концов).источник
;E
делает в конце?NameError
для завершения, такE
как больше нигде не определеноCJam, 79
Попробуйте онлайн
Это ужасно неэффективно, но, учитывая достаточно памяти и времени, в конечном итоге это работает. 123 не хватает памяти с 16 ГБ, но 120 и 125 в порядке.
источник
Pyth - 35 байт
Грубая сила. Странная вещь в том, что новый неявный ввод на самом деле вредит моему счету, потому что он, кажется, работает и для
.v
pyth_eval.Попробуйте это онлайн здесь .
источник
Python 3, 183 байта
Скорость не является абсолютно необоснованной (123, 221, 1237, 6551 финишируют с точностью до секунд или минут). Изменение
if
оператора наif j<=i and <k<2*n
ускоряет его еще больше, за счет еще 9 байтов. Я пропустил Division (/
), потому что я не вижу, как это будет необходимо.источник