Пояснення
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
Програмі необхідно знайти найкоротший рядок, який може представляти вхід (число), використовуючи вказаний вище формат.
Примітки
Це завдання з гольф-кодом , тому виграє найкоротший код у байтах.
Однозначність
На розсуд програміста -
може бути x-y
або y-x
. Однак вибір повинен бути узгодженим у межах рішення. Так само і для /
.
Зразок програми
Луа, 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 (або будь-який його варіант) для написання коду.