Это еженедельный вызов № 2. Тема: Перевод
Напишите программу или функцию, которая принимает исходный код для программы в Prelude и выводит код для эквивалентной программы в Befunge-93 . Для того чтобы программа была эквивалентной, она должна для любого заданного ввода выдавать тот же результат, что и программа Prelude, и останавливаться тогда и только тогда, когда программа Prelude останавливается.
Язык ввода: прелюдия
Интерпретатор Python:
Программа Prelude состоит из нескольких «голосов», которые выполняют инструкции одновременно. Инструкции для каждого голоса находятся на отдельной строке. Каждый голос имеет отдельный стек, который инициализируется бесконечным количеством нулей. Выполнение начинается в крайнем левом столбце и продвигается на один столбец вправо каждый тик, за исключением случаев, когда на него влияют )
или (
инструкции. Программа завершается при достижении последнего столбца.
Прелюдия спецификации для этого вызова:
Digits 0-9 Push onto the stack a number from 0 to 9. Only single-digit
numeric literals can be used.
^ Push onto the stack the top value of the stack of the above
voice.
v Push onto the stack the top value of the stack of the below
voice.
# Remove the top value from the stack.
+ Pop the top two integers from the stack and push their sum.
- Pop the top two integers from the stack, subtract the topmost
from the second, and push the result.
( If the top of the stack is 0, jump to the column after the
matching `)` after the current column executes.
) If the top of the stack is not 0, jump to the column after
the matching `(` after the current column executes.
? Read an integer from STDIN.
! Pop one value from the stack and print it to STDOUT as an
integer.
<space> No-op
Примечания
v
и^
действуйте циклически, поэтомуv
нижний голос скопирует элемент стека верхнего голоса, а^
верхний голос скопирует из нижнего голоса. Следствие:v
и то, и другое^
дублирует верхнюю часть стека в одноголосной программе.- А
(
и его соответствие)
могут быть расположены на разных строках. Тем не менее , a)
всегда будет смотреть на стек голоса, в котором(
был размещен соответствующий голос , а не на стек, где был размещен сам голос)
. - Значения , произведенные
^
иv
инструкция по эксплуатации от значений , присутствующих до завершения каких - либо других операций в том же самом столбце. ?
и!
работать не так, как в спецификации на esolangs.org, поэтому не забудьте протестировать с немного измененным интерпретатором, представленным в этом посте.
Вклад гарантированно будет иметь:
- Соответствующие скобки
- Не более одной скобки в столбце
- Одинаковое количество символов в каждой строке
- Хотя бы одна строка
- Нет столбца с более чем одной инструкцией ввода-вывода (
!
или?
) - Один символ перевода строки после инструкций для каждого голоса
- Нет символов, кроме упомянутых выше
Язык вывода: Befunge-93
Befunge - это стековый язык, программный счетчик которого (ПК; указатель на текущую инструкцию) свободно перемещается по двумерной сетке. Он начинается в верхнем левом углу, двигаясь вправо. Поле для игры является тороидальным, то есть движение ПК охватывает оба края. Befunge также имеет стек, который инициализируется бесконечным числом нулей. Befunge выполняет следующие операции:
Вы можете принять следующие характеристики компилятора / интерпретатора Befunge-93:
- Целые числа имеют неограниченную точность.
- Это позволяет сетки любого размера.
- Координаты сетки (для
g
иp
) основаны на 0.
счет
Чтобы не допустить отправки, которые просто создают интерпретатор Prelude в Befunge и жестко кодируют в него исходный код Prelude, цель состоит в том, чтобы минимизировать размер получающегося исходного кода Befunge.
Ниже представлен ряд программ Prelude. Ваш переводчик будет работать на все это. Ваша оценка - это сумма размеров программ Befunge при условии, что все они действительны.
Ваш переводчик не должен быть оптимизирован специально для этих тестовых случаев (например, путем жесткого написания для них рукописных программ Befunge). Если я подозреваю какой-либо ответ на этот вопрос, я оставляю за собой право изменять входные данные или создавать дополнительные.
Образцы входов
Распечатать n-1
до 0
:
?(1-^!)
Логическое И:
? (0)
?(0 )
1 !
Логическое ИЛИ:
? (0)
? (0)
1 1 !
Проверьте четность ввода (т.е. по модулю 2) неотрицательного числа:
?(1-)
^ v
v1-^^-!
Квадратный вход:
^
^+ !
?(1-)
Выведите n- е число Фибоначчи, где n = 0
соответствует 0 и n = 1
соответствует 1:
0 v+v!
1 ^
?(1-)
Signum:
1) v # - !
vv (##^v^+)
?(# ^ ##
Отдел неотрицательных входов:
1 (# 1) v # - 1+)
vv (##^v^+)
? v-(0 # ^ #
?
1+ 1-!
Конечно, ваша программа должна демонстрировать одинаковое поведение во всех случаях, даже если поведение программы примера для отрицательных чисел не указано.
Наконец, ваш переводчик не должен быть неоправданно длинным:
- Он должен содержаться в сообщении Stack Exchange
- Он должен обрабатывать вводимые данные менее чем за 10 минут на обычном настольном компьютере.
Обратите внимание, что числовой ввод для Prelude или Befunge задается как необязательный знак минуса, за которым следуют одна или несколько десятичных цифр, за которыми следует новая строка. Другой ввод - неопределенное поведение.
Вы можете написать свой переводчик на любом языке. Кратчайший перевод кода Befunge выигрывает.
Leaderboard
- Sp3000 : 16430 байт
1
находится внутри цикла, поэтому его нельзя нажимать. 0 может исходить из бесконечного количества 0, которые начинаются на стеках.Ответы:
Python 3, забьет позже
Беги как
py -3 prefunge.py <input filename> <output filename>
.Это была медленная неделя для меня, поэтому мне наконец-то стало достаточно скучно, чтобы заняться этим шестимесячным вопросом. Я спросил бы, почему никто не попробовал, но я все еще чувствую боль от отладки (и, вероятно, все еще остаются ошибки, насколько я знаю).
Вопрос не предусматривает интерпретатора Befunge-93, поэтому я использовал этот , который немного отличается от спецификации. Два ключевых различия:
Если в данной строке программы нет символа, вы не можете писать в эту строку. Это означает, что вам нужно будет нажать Enter несколько раз, чтобы ввести достаточно новых строк в конце . Если вы видите
NaN
s в выводе, это наиболее вероятная причина.Ячейки сетки не инициализируются до нуля - для удобства я включил некоторую преинициализацию в выходы Befunge, но, поскольку это не является необходимым, я могу убрать его, когда начну подсчет очков.
Основная схема выходных программ такова:
Пространство стека находится за пределами программы, отсюда и новый комментарий Enter-spamming от ранее.
Основная идея состоит в том, чтобы назначить каждому голосу строку, которая служит его стеком. Для поддержки этих стеков у нас также есть специальная строка длины стека, где длина каждого стека записывается в ячейку вдоль строки. В программе много
g
плюсов иp
минусов, например, для печати процесс выглядит так:y = stack_row[stack], x = stack_length[stack]
.91+,
, то есть напечатайте как целое число, затем напечатайте новую строкуstack_length[stack]
Чтобы выполнить одновременную оценку столбца, все необходимые ячейки считываются и их значения сохраняются в стеке до того, как в них будут записаны какие-либо ячейки (например, для примера печати может быть больше инструкций между первым и вторым этапами).
`
, который больше чем, используется, чтобы убедиться, что длина стека никогда не становится отрицательной, и для нажатия 0, когда стек пуст. Отсюда и ясно видимое ветвление, но у меня есть идея, которая удалит ветвление, которое должно удалить большое количество пробелов из первой и третьей строк.Для циклов, поскольку циклы Prelude могут перемещаться в обоих направлениях, мы используем две строки на цикл в такой конфигурации:
Эти циклы в настоящее время составляют большую часть байтов, но их можно легко обойти, поместив их в кодовое поле
p
, что я планирую сделать после того, как буду рад, что переводчик работает правильно.Вот пример выходных данных для
?(1-^!)
, т.е. распечататьn-1
до0
:Квадрат-заместитель ввод:
Разделение (рекомендуются небольшие входы):
Также на ум приходит множество других небольших оптимизаций, например, замена
07p07g
на:07p
, но я делаю это по одному шагу за раз :)источник
Will score later
2 года и считай! :)