В этих проблемах, вы будете писать интерпретатор для 2 Ом (транскрибируется в TwoMega ), язык , основанный на свободно Brainfuck с бесконечномерным пространством для хранения.
Язык
2 Ω содержит три части состояния:
Лента , которая представляет собой бесконечный список битов, все инициализируются в 0. Это имеет крайний левый элемент, но не крайний правый элемент.
Указатель памяти , которая представляет собой неотрицательное целое число , которое является индексом элемента в ленте. Более высокий указатель памяти относится к ячейке ленты дальше справа; указатель памяти 0 ссылается на самый левый элемент. Указатель памяти инициализируется в 0.
Гиперкуба , который является концептуально ∞ - мерным «окном» ячеек, каждый из которых содержит бит , инициализированное в 0. ширина Гиперкуба связана в каждом измерении только 2 клеток, но бесконечность размеров означает число клетки неисчислимы .
Индекс в гиперкуб бесконечного список бит, относится к клетке , в гиперкуба (таким же образом , что конечный список бит может быть использован для обозначения гиперкуба конечной размерности). Поскольку лента представляет собой бесконечный список битов, вся лента всегда ссылается на элемент гиперкуба; этот элемент называется референтом .
2 Ω дает значение 7 различным символам:
<
уменьшает указатель памяти на 1. Уменьшение его ниже 0 - неопределенное поведение, поэтому вам не нужно обрабатывать его.>
увеличивает указатель памяти на 1!
переворачивает бит у референта..
выводит бит на референте.^
заменяет бит в ячейке, на которую указывает указатель памяти на ленте, на инверсию бита в референте.[x]
выполняет кодx
до тех пор, пока бит у референта равен 1.
Соревнование
Ваша задача - написать программу, которая принимает строку в качестве входных данных и выполняет эти входные данные как 2- омную программу.
Это Код-гольфТаким образом, самый короткий действительный ответ (измеряется в байтах) выигрывает.
Ноты
- Вы можете предположить, что программа будет состоять только из символов
<>!.^[]
и[]
будет правильно вложена. - Ваш переводчик должен быть ограничен только доступной памятью в системе. Он должен быть в состоянии запустить примеры программ в разумные сроки.
Примеры программ
Печать 1:
!.
Печать 010:
.!.!.
Печать 0 навсегда:
![!.!]
Выведите 0 навсегда или 1 навсегда, если !
добавлено:
[.]![!.!]
источник
1
s на ленте всегда конечное. На самом деле существует довольно простая биекция между натуральными числами и состояниями ленты (интерпретировать содержимое ленты как обратное двоичное число), что показывает, что гиперкуб является в основном бесконечным одномерным массивом, доступ к которому осуществляется путем переключения битов в целочисленное значение указателя вместо того, чтобы в / уменьшать как в мозгеcat
программу: там, похоже, нет инструкции для ввода данных..
- печатает один ноль и затем существует;!^!.
- печатает один, а затем выходит. Больше было бы хорошо, хотя. В настоящее время нужно понять представления, чтобы проверить их (и, следовательно, выразить им свое мнение!)[0,0,0,0,0,0,0...]
(т. Е. Наличие a!
в начале программы).[.]![!.!]
чтобы напечатать значение этой ячейки навсегдаОтветы:
Python 2 , 167 байт
Попробуйте онлайн!
т является лента. t = 6 означает, что лента [0 1 1 0 0 0…]
m равно 2 степени указателя памяти. Таким образом, m = 8 означает, что мы указываем на бит 3 ленты.
h - гиперкуб. h = 80 (биты 4 и 6 установлены) означает, что биты в [0 0 1 0…] и [0 1 1 0…] установлены.
Чтобы прочитать бит у референта, мы проверяем 2 t & h . Чтобы перевернуть это, мы выполняем h ^ = 2 т .
Мы переводим инструкции в код Python и выполняем результат. Я сохраняю уровень отступа циклов while.
источник
2**t
(-6 байт).JavaScript (Node.js) , 148 байт
Попробуйте онлайн!
Тьюринг завершен
Нужно, чтобы init как перемещался вправо на несколько мест, и инициализировал текущий и правый один бит адреса как 1 (
>>>>>>>>^>^<
)Попробуйте онлайн!
Место
n
в BoolFuck записывается как(0, 0, ..., 0(n*0), [1], 1, 0, 0, ...)
.Ибо
>
это делаетn
=>n+1
То же самое, как
<
работатьисточник
!>.
печатает1
в boolfuck, но переводит, в!>^.
котором печатает 1 в TwoMega (>
не влияет на ленту;^
не влияет на ленту, так как референт равен 1)+>;
do[1]00...
1[0]0...
(вывод 0),!>^.
do(0,0,...)=1, ptr=([0],0,...)
(0,0,...)=1, ptr=(0,[0],...)
(0,0,...)=1, ptr=(0,[1],...)
(вывод 0), что не так?!>.
, только>
допустимая команда в boolfuck ...!
инвертирует референт, а не ячейку ленты.Brain-Flak Classic , 816 байт
Попробуйте онлайн!
Этот код был написан просто для того, чтобы у меня было место, чтобы написать доказательство полноты по Тьюрингу.
Доказательство Тьюринга-полноты
Мы показываем сокращение от Boolfuck до TwoMega:
Этот перевод сохраняет состояние Boolfuck в чётных ячейках ленты в TwoMega. Все переведенные команды сохранят следующие инварианты:
Фрагмент
!^!
будет оставаться[0]0
постоянным и переключаться между0[0]
и[1]1
(где внимание ограничено линией на гиперкубе, доступной без перемещения указателя памяти). Как таковой, он используется для временного помещения текущего значения ленты в референт для команд Boolfuck, которые заботятся об этом.Если бы TwoMega была дана команда ввода
,
с ожидаемой семантикой, команда Boolfuck,
переведена в>^<,!^>[!]!^<
. Поскольку,
нет необходимости доказывать, что Boolfuck является тьюрингово-полным, отсутствие входной команды не влияет на это доказательство.источник
Python 3 ,
297284274 байта-10 байт благодаря яйцам и Джонатану Аллану
Попробуйте онлайн!
источник
t.discard(p)
->t-={p}
t
неglobal
.f
f(C,p,t=set())
Пип ,
7571 байтПопробуйте онлайн!
Переводит 2 Ω код в эквивалентный код Pip и оценивает его.
Мы используем
i
для представления ленты,v
для указателя ленты * иl
для гиперкуба. Первые два преинициализированы на полезные значения;l
начинается как[]
, к которому мы нажимаем0
(lPU0
), чтобы избежать проблем с indexing-empty-list.* На самом деле, это побитовое отрицание указателя ленты, потому что мы храним ленту в обратном направлении для более простого преобразования в десятичную.
Остальная часть кода:
Таблица перевода:
l@FBi
является референтом: элементом гиперкубаl
в индексе (конвертируетсяi
из двоичного кода). Он появляется часто, поэтому мы вызываем его_
и заменяем_
реальным кодом в конце.!:_
логически отрицает референт на месте.--viPU0
уменьшениеv
(перемещение указателя ленты вправо); затем он толкает другой0
в левую сторонуi
, чтобы убедиться, что указатель ленты остается в границах.++v
приращенияv
(нет необходимости в проверке границ, для каждой операции).W_{
запускает цикл, в то время как референт верен (то есть ненулевой, то есть1
).}
замыкает циклO_
выводит референт без перевода строки.Наконец, для
^
:источник