Brain-Flak (помесь Brainf ** k и Flak-Overstow) является основанным на стеке эзотерическим языком. С тех пор как этот вызов был опубликован, язык развивался и обновлялся, но эта первая редакция языка известна как «классическая мозговая атака».
Вы должны написать программу или функцию, которая берет строку классического кода Brain-Flak и оценивает ее. Он также возьмет (возможно пустой) список целых чисел. Есть входы в классическую программу Brain-Flak.
Язык
Brain-Flak имеет два стека, известные как «левый» и «правый». Активный стек начинается слева. Если пустой стек выскочил или заглянул, он вернет 0. Нет переменных. Когда программа запускается, каждый вход помещается в активный стек по порядку (так, чтобы последний вход был сверху стека).
Единственными действительными символами в программе Brain-Flak являются ()[]{}<>
, и они всегда должны быть сбалансированы . Если есть недопустимые символы или несоответствующие скобки, вы получите неопределенное поведение. Все действительно.
Есть два типа функций: Nilads и монады . Nilad это функция , которая принимает 0 аргументов. Вот все нилады:
()
+1.[]
-1.{}
Поп активный стек.<>
Переключить активный стек.
Они объединяются вместе, когда они оцениваются. Итак, если у нас было 3 на вершине активного стека, этот фрагмент:
()(){}
оценил бы, 1 + 1 + active.pop()
что оценил бы к 5. <>
оценивает к 0.
Монады берут один аргумент, кусок кода Brain-Flak. Вот все монады:
(n)
Нажмите 'n' в активном стеке.[n]
Выведите 'n' как int и перевод строки.{foo}
Пока active.peek ()! = 0, делайте foo. Оценивает до 0¹.<foo>
Выполните foo, но оцените его как 0.
Эти функции также будут возвращать значение внутри них, поэтому
(()()())
Будет толкать 3 и
[()()()]
Напечатает 3 но
[(()()())]
Напечатает и нажмет 3.
Когда выполнение программы завершено, каждое значение, оставленное в активном стеке, печатается как целое число с новой строкой между. Значения в другом стеке игнорируются.
Правила:
Ваша программа должна поддерживать числа в диапазоне (-128, 127) и размер стека не менее 255. Если вы поддерживаете больше, отлично.
Переполнение / переполнение не определено.
Образец ввода-вывода:
Пустая программа:
Вход: нет
Выход: нет
Дополнение. Источник:
({}{})
Входные данные:
2, 3
Выход:
5
Вычитание. Источник:
({}<>){({}[])<>({}[])<>}<>
Входные данные:
2, 3
Выход:
-1
Умножение. Источник:
({}<>)<>({}[]){({}[])<>(({}))<>}<>{({}<>{})<>}<>
Входные данные:
7, 8
Выход:
56
Фибоначчи. Источник:
<>((()))<>{({}[])<>({}<>)<>(({})<>({}<>))<>}<>
Входные данные:
5
Выход:
13
8
5
3
2
1
1
{[({})]}
Применяются стандартные лазейки, и выигрывает самый короткий ответ в байтах.
- ¹: Это было на самом деле ошибка с моей стороны.
{...}
следует оценить сумму всех его прогонов, что является ИМО одной из самых крутых особенностей мозгового штурма. Тем не менее, для целей этой задачи предположим, что{...}
оценивается как 0.
источник
{...}
оценивает монада ?{...}
оценивается как 0. Кроме того, аргументы передаются по порядку, поэтому передаются2
, затем3
передаются, поэтому, когда программа запускается, второй input (3
) находится сверху стека. Я проясню оба из этого поста.Ответы:
Пип
-n
,15114810198 байтПринимает список входных данных в качестве аргументов командной строки и код Brain-Flak из (строки) stdin. Попробуйте онлайн!
Изменить: сэкономил много байтов по сравнению с моим первоначальным подходом, переключившись на стратегию translate-and-eval.
Разоблаченный и прокомментированный
Эта версия также включает в себя некоторые выходные данные отладки, показывающие код Pip, полученный в результате перевода, а также содержимое стека после выполнения.
источник
Brain-Flak Classic ,
127112471239 байтПопробуйте онлайн!
+4 байта от исправления ошибки с состоянием в
{...}
монаде и -36 байтов от различных гольфов.1238 байт кода, +1 байт для
-a
флага (который можно комбинировать с языковым флагом).Это теперь оценивается
{...}
как ноль согласно спецификации вызова. Обратите внимание, что сама Brain-Flak оценивается{...}
как сумма всех запусков с момента исправления 7 мая 2016 года за два дня до публикации этого вызова.Следующий код правильно интерпретирует Brain-Flak Classic с
{...}
суммой всех запусков. Единственная разница между двумя переводчиками - это размещение одного{}
nilad.Попробуйте онлайн!
Ввод (для любого интерпретатора) - это программа Brain-Flak Classic для интерпретации, затем новая строка, затем разделенный пробелами список целых чисел. На входе проверка не выполняется. Новая строка обязательна, даже если программа или ввод пустые.
Первым шагом является анализ всех входных данных, начиная с скобок:
Затем целые числа анализируются. Обычно это не требуется, но вход был взят как ASCII. Это имеет серебряную подкладку, хотя: ввод текста позволяет нам определять высоту стека, что упрощает вещи, когда у нас нет доступа к высоте стека nilad.
Целые числа разбиты на два числа во втором стеке: одно для абсолютного значения и одно для знака. Затем они перемещаются обратно в первый стек.
Интерпретируемые стеки хранятся под кодом в первом стеке в следующем порядке: текущая высота стека, текущий стек, другая высота стека, другой стек. 0 для другой высоты стека не нужно сдвигать в этой точке, так как это будет неявный ноль при первом чтении.
Представление кода теперь перемещено обратно в левый стек. Чтобы потом было легче, мы вычитаем 4 из открывающих скобок нилад, чтобы каждая операция имела уникальное целое число от -1 до -8.
Основная часть программы фактически интерпретирует инструкции. В начале каждой итерации основного цикла текущая инструкция находится в верхней части левого стека, все, что находится ниже того же стека, и все, что находится до того, как она находится в правом стэке. Я склонен визуализировать это как книгу, открытую для определенной страницы.
После выхода из основного цикла весь код находится в правильном стеке. Единственные вещи в левом стеке - это ноль и два интерпретированных стека. Получение правильного результата - дело простое.
источник
{...}
, который является правильным поведением для современных мозговых и (как мне кажется) классических мозговых атак, однако я написал в задаче, которая{...}
оценивается как 0. Вы, вероятно, можете играть в гольф значительное количество байтов удалив эту функциональность, хотя было бы неплохо сохранить оригинал, потому что он технически болееAPL,
255257 байтЭто принимает программу в качестве правого аргумента, а ввод программы - в качестве левого аргумента, то есть:
Безголовая версия: здесь .
источник
APL (Dyalog Classic) , 146 байтов
Попробуйте онлайн!
одна классика интерпретирует другую :)
источник
Python 3, 429 байт
Используется как
g('[{}{}]', 2, 3)
Он использует
re.sub
для «компиляции» исходных текстов мозга в python, а затем выполняет питон. (для отладки заменитеexec
на,print
чтобы получить список кода Python)Правильный отступ для вложенных циклов while пожирает в коде много байтов.
источник
Python, 616 байт
Инструкции:
[1,2,...]
формате, затем нажмите вводПо сути, эта программа рекурсивно «компилирует» код Brain-flak во вложенные списки и рекурсивно интерпретирует этот список. Там, вероятно, есть способ объединить два ...
Я постараюсь переработать логику позже.
источник
Perl 5,6,
419414 байтЯ немного играл в гольф, но, вероятно, есть возможности для улучшения. Новые строки и вкладки добавлены здесь для удобства чтения:
источник
Python 2 ,
361, 348 байтПопробуйте онлайн!
-13 байтов сохранено благодаря @Mr. Xcoder!
источник