Stackylogic - это язык программирования, основанный на логике, который я создал, который принимает 0
и вводит 1
и выводит один 0
или 1
после завершения.
Программа Stackylogic состоит из строк, которые могут содержать только три символа, 01?
а также ровно один <
в конце одной из строк. Линии не могут быть пустыми и линия с <
должна иметь по крайней мере один 0
, 1
, или ?
перед ним.
Вот пример программы, которая (как я объясню) вычисляет NAND из двух битов:
1
?<
11
?
0
Каждая строка в программе Stackylogic считается стеком , с нижней частью слева и верхней справа. Неявно, есть пустой стек (пустая строка) перед первой строкой в программе и после последней строки.
Элемент <
, который мы назовем курсором , помечает стек для запуска при запуске программы Stackylogic. Выполнение программы Stackylogic происходит следующим образом:
Удалите верхний символ из стека, на который в данный момент указывает курсор.
- Если это символ
?
, предложите пользователю ввести a0
или a1
и действуйте так, как если бы это был символ. - Если это символ
0
, переместите курсор на одну стопку вверх (на строку выше текущей строки). - Если это символ
1
, переместите курсор на одну стопку вниз (на строку ниже текущей строки).
- Если это символ
Если стек, в который перемещается курсор, пуст, выведите последнее значение, извлеченное из стека (всегда a
0
или1
), и завершите программу.В противном случае, если стек, в который перемещается курсор, не пуст, вернитесь к шагу 1 и повторите процесс.
Обратите внимание, что программы Stackylogic всегда заканчиваются, потому что они должны в конечном итоге исчерпать свои стеки.
Пример NAND
В программе NAND курсор начинается на ?
:
1
?<
11
?
0
Мы будем предполагать, что пользователь вводит a 1
после ?
нажатия, что означает, что курсор будет перемещаться вниз, делая программу похожей на это:
1
11<
?
0
Теперь равнина 1
находится на вершине стека курсора. Это правильно вытолкнуто, и курсор снова перемещается:
1
1
?<
0
Теперь предположим, что пользовательский ввод 0
для ?
, что означает, что курсор будет двигаться вверх:
1
1<
0
Опять же, a 1
находится в стеке курсора, поэтому курсор появляется и перемещается вниз:
1
<
0
Наконец, стек курсоров пуст, поэтому 1
выводится последнее значение , выводится, и программа завершается.
Это верно для ворот NAND, потому что 1 NAND 0
есть 1
. Это, конечно, работает для остальных трех двухбитных входов, если вы хотите проверить.
ИЛИ Пример
Эта программа Stackylogic имитирует ИЛИ ворота:
?
?<
Легко видеть, что начальный ввод 1
толкает курсор к неявному пустому стеку ниже последней строки, заканчивая программу и выводя только 1
что введенный.
С 00
другой стороны, для ввода курсора он направляется к неявному пустому стеку вверху, заканчивая программу и выводя последний, который 0
должен быть введен.
Вызов
Напишите программу или функцию, которая принимает программу Stackylogic в виде строки и запускает ее, печатая или возвращая полученный результат 0
или 1
.
После ?
этого вы можете запросить у пользователя ввод 0
или 1
, или прочитать значение из предустановленной строки 0
«и 1
», которую вы также принимаете в качестве ввода. (Это может быть другая строка ввода для вашей программы / функции, или вы можете просто предположить, что первая или последняя строка строки программы будет входным потоком).
Вы можете предположить, что программа и входные данные всегда правильно сформированы. При желании вы можете предположить, что входные программы поставляются с одним завершающим переводом строки (хотя помните, что в конце всегда есть неявный пустой стек).
Самый короткий код в байтах побеждает.
Больше примеров программ
ZERO
0<
ONE
1<
BUFFER
?<
NOT
1
?<
0
AND
?<
?
NAND
1
?<
11
?
0
OR
?
?<
NOR
1
?
00
?<
0
XOR(v1)
?
0
1?<
?
0
XOR(v2)
?
?<
11
?
0
XNOR(v1)
1
?
0?<
1
?
XNOR(v2)
1
?
00
?<
?
MEDIAN(v1)
1
???<
0
MEDIAN(v2)
?
1?<
??
источник
?\1?<\??
. В качестве альтернативы, вот симметричная 5-строчная реализация:?\?0\?<\?1\?
1\???<\0
.111\???????<\000
.Ответы:
Retina ,
79787368666563625544 байтаЧисло байтов предполагает кодировку ISO 8859-1.
Ввод осуществляется через STDIN и, как ожидается, будет пользовательским вводом, отделенным двумя переводами строки от исходного кода.
Попробуйте онлайн! (Первые две строки включают набор тестов, где каждая строка представляет собой отдельный тестовый случай,
/
а не перевод строки.)Я не совсем уверен, что здесь произошло.
Это похоже на действительно неуклюжее решение, иэто действительно не та проблема, для которой была создана Retina, но она по-прежнему превосходит все текущие ответы по какой-то причине.объяснение
Окончательная версия этого на самом деле оказалась довольно простой.
Первый этап - это просто цикл (из-за
+
опции), который выполняет фактическую интерпретацию языка. Этап представляет собой одну подстановку регулярных выражений, но на самом деле это три различные замены, сжатые в одну стадию, используя тот факт, что захват групп из неиспользуемых ветвей просто считается пустым во время замены.Обработка
?
:Это просто берет первый символ ввода, затем сопоставляет произвольные символы, пока не найдет
?<
, и помещает этот первый символ перед<
(удаляя?
).Обработка
0
:Это соответствует строке, предшествующей a,
0<
и помещает ее после<
, удаляя0
. (По сути, это просто удаляет0
и перемещает<
одну строку вверх.)Обработка
1
:Практически то же самое, за исключением того, что мы перемещаем
<
одну строку вниз при удалении1
. Одна важная деталь, на которую следует обратить внимание, - это использование+
вместо*
, то есть мы требуем, чтобы следующая строка не была пустой.Интересно выяснить, почему это работает и почему нам не нужно отслеживать последнее значение, которое мы извлекли, чтобы определить окончательный результат. Чтобы сделать это, мы должны рассмотреть, как цикл может завершиться. Так как каждое возможное совпадение изменяет строку (так как из нее отбрасывается хотя бы один символ), нам нужно только рассмотреть случаи, когда совпадение не удается вообще.
Если символ перед
<
является?
единственным способом провала совпадения, это то, что перед ним нет символа без перевода строки, но этого не может быть, потому что мы гарантируем, что всегда достаточно ввода.Если символ в передней части
<
IS0
, регулярное выражение будет всегда совпадать с , так как всегда есть другая линия над текущим (который может быть пустой , разделяющую линию ввода из исходного кода).Если перед ним
<
стоит символ1
, регулярное выражение не будет выполнено, если либо мы находимся на последней строке (так как¶
не будет соответствовать), либо если следующая строка будет пустой (так как.+
не будет соответствовать). Обратите внимание, что оба этих случая соответствуют завершению программы после появления a1
.Наконец, есть также возможность,
<
которой не предшествует ни один из?01
. Оказывается, мы можем достичь этой ситуации, только нажав a0
и двигаясь вверх к пустой строке, так что<
теперь ей предшествует перевод строки.Таким образом, когда программа завершается на a
1
,<
после этого все равно будет1
. Но если программа завершается на a0
, она переместится на пустую строку. Мы можем легко превратить эту информацию в желаемый результат с помощью простого этапа сопоставления:Это просто подсчитывает совпадения
1<
в строке. По рассмотренному выше рассуждению это будет,1
если программа завершилась на a1
, и0
если она завершилась на a0
.источник
Выпуклый ,
10295 байтЧто ж, язык на основе списка стеков, закодированный на языке стеков, оказался довольно сложным.
Запомните мои слова: я получу это до 100 байтов или меньше!РЕДАКТИРОВАТЬ: успех!Попробуйте онлайн!
Ввод программы осуществляется через аргументы командной строки. Входные данные
0
с и1
ев нормально (на TIO, это означает символ новой строки , разделенных в поле «ввод»).Объяснение:
Весь код можно разбить на три части:
Этот бит просто берет входную программу и преобразует ее в массив строк, а также добавляет
" "
строки в начало массива. Так как выпуклые массивы обертываются, подойдет только пустой стек в начале.Эта часть определяет, с какой строки (или стека) начать выполнение. Он просматривает каждую строку и помещает правильный номер стека в
M
переменную.Это самое интересное! Он непрерывно зацикливается, пока не достигнет строки, на которой есть только пробел (
" "
) (символизирующий пустой стек). Если строка не пуста, она делает следующее:?
, возьмите ввод и добавьте этот символ в строку.0
, переместите указатель строки вверх на один.1
, переместите указатель строки вниз на один.(пробел), распечатайте последний извлеченный элемент и завершите программу.
источник
32-битный машинный код x86, 70 байт
В шестнадцатеричном виде:
Ввод - это многострочная строка с нулевым символом в конце (разделенная переводом строки), передаваемая через ESI. Пользовательский ввод считается первой строкой. Возвращает «0» / «1» в AL.
Разборка:
источник
JavaScript (ES6), 136
138Предполагая завершающий перевод строки в программе
Меньше гольфа
Контрольная работа
источник
05AB1E ,
58565553515046 байтовСэкономили 2 байта благодаря Emigna ! Код:
Использует кодировку CP-1252 . Попробуйте онлайн! ,
источник
Python 3,
147146145144 байта1 байт благодаря @Lynn.
источник
Питон 3, 318
F - программа, z - ввод. Да, мои имена переменных безумны.
источник
ES6, 190 байт
Используйте как
f(program, input)
источник
[...o]
вместоo.split``
и используйтеfor
вместоwhile
, поскольку это позволяет вам переместить два выражения вfor
два байта сохранения. Пара конкретных советов: я думаю, что вашеNumber
приведение не является необходимым, поскольку приведение*2
будет для вас, и я бы просто прочитал,i
используяj=0
иi[j++]
который, я думаю, экономит 11 байтов.f=
анонимные функции.Java,
256255231219215213 байтДемо на Ideone.
Принимает программу и ввод в качестве аргументов и возвращает результат в виде целого числа.
источник
for
цикл, но что означает ваш первый комментарий?int f(String[]I)...
и вы можете избежатьString[]p=I.split("\n");
int f(String[]P)
->(String[]I){...
PHP (<7,0),
195192 байтаПринимает программу в качестве первого аргумента и каждое значение в качестве дополнительного аргумента.
Обратите внимание, что я проверял это с разделителями ("", ..) asn пробелами, а не с символами новой строки, но это должно работать в любом случае.
Выдает устаревшее уведомление, если работает в PHP> 5.3.
Также выдает предупреждение, если вы выходите из верхней части программы. Однако он все еще работает и выводит правильно, так что все в порядке.
источник
С
264249244242C не очень хорошо справляется с манипулированием строками, но это довольно коротко.
Он работает путем сканирования строки для курсора (
<
), перемещения на 1 позицию назад, чтения команды, замены ееtab
символом и перемещения вперед или назад на одну строку. Ввод осуществляется в виде массива C char, напримерchar array[]="1\n?<\n11\n?\n0";result = f(array);
, возврат каретки также разрешен.Хотя входная строка изменена, длина не изменяется.
Тестовая программа
Запустите эту программу с каждым тестовым примером в качестве отдельного параметра, используя одну обратную косую черту вместо новых строк. Контрольные примеры будут разделены пустой строкой.
источник