Вступление
Форте - это очень своеобразный эзотерический язык, основанный на концепции изменения значений чисел. В числах Forte не константы, а переменные, вы можете использовать LET
инструкцию, чтобы назначить им новые значения.
Например, после выполнения LET 2=4-1
отныне 2
принимает значение 3
, что означает, что всякий раз, когда значение 2
появляется в выражении, оно вместо этого «заменяется» на 3
. Выражение (1+1)*2
теперь будет оцениваться как 9
.
Эта инструкция в Forte используется как для хранения информации, так и для управления потоком (строки нумеруются, и, изменяя значение их номеров, вы можете определить порядок их выполнения). В этом вызове мы не будем иметь дело с этим вторым аспектом.
Соревнование
Вы должны написать интерпретатор для упрощенного подмножества LET
выражений Forte .
В качестве входных данных вы получите последовательность строк, следующую этой грамматике:
<line>::= <number>=<expression>
<expression>::= <number>|<expression>+<number>
Примечание: эта грамматика недопустима в Forte, потому что в ней отсутствуют номера строк, LET и круглые скобки (которые всегда обязательны)
То есть вам нужно будет только иметь дело с вычислением суммирования и присвоением значений числам. Круглые скобки не будут присутствовать во входных данных, и каждое выражение нужно будет оценивать слева направо: имейте в виду, что на частичные результаты влияют переопределения!
Числа всегда будут неотрицательными целыми числами, вплоть до предела целочисленного типа вашего языка (или 2 ^ 32, в зависимости от того, что больше).
Для каждой строки вы должны вывести результат выражения и присвоить этот результат (возможно, переназначить) значению первого числа, что будет влиять на то, как будут интерпретироваться следующие строки.
Это код-гольф , выигрывает самый короткий код (в байтах)!
Другие правила
- Формат ввода гибкий, например, вы можете взять одну строку с символами новой строки, списком строк, списком чисел ... То же самое относится и к выводу, если ясно, каков результат каждого выражения в вход.
- Вы можете предоставить функцию, полную программу или решение для запуска в среде REPL, вызывая ее один раз для каждой строки.
- Стандартные лазейки запрещены, в частности, вы не можете вызвать внешний интерпретатор Forte в своем коде.
Примеры
Все они являются частью одного и того же ввода. После каждой строки отображается ожидаемый результат относительно этой строки, иногда с комментарием, указывающим соответствующие переназначения (не является частью требуемого вывода).
5=4
4
6=5
4 # 5 -> 4
7=1+2+5
7
7=5+2+1
4 # Order of operations matters! 5+2 -> 4+2 -> 6 -> 4
18=5+6+7
12
5=3
3 # Remember: 5 -> 4
10=6+4
3 # 6 -> 4 -> 3, 3+3 = 6 -> 3
0
допустимый номер?0
действителен («Числа всегда будут неотрицательными целыми числами»)Ответы:
Желе , 28 байт
Попробуйте онлайн!
Это одна из немногих программ Jelly, в которой кажется более уместным использование стандартного ввода. Это полная программа (написание функции было бы короче, но было бы запрещено правилами PPCG, потому что она не будет работать правильно во второй раз). Формат ввода выглядит следующим образом:
объяснение
Вспомогательная функция
1Ŀ
(перевод целого числа в его значение)Скорее всего, эта вспомогательная функция будет корректно работать либо с одним значением, либо со списком значений, в зависимости от способа
y
определения. Если для одного значения задано более одного сопоставления, мы берем первое сопоставление из таблицы. Таблица отображения хранится в регистре (который в основном является просто переменной; у Jelly есть только одна переменная).Вспомогательная функция
2Ŀ
(оцените одну инструкцию LET)Мы действительно не хотим возвращаемого значения здесь; мы просто запускаем это для его побочных эффектов (обновление регистра и вывод назначенного значения). Однако функции Jelly всегда возвращают значение, поэтому мы просто возвращаем таблицу сопоставления, так как это кратко.
Основная программа
Обычно,
⁸
это даст нам первый аргумент командной строки при запуске в этом контексте, но его нет (мы берем данные из стандартного ввода), поэтому он работает в альтернативном режиме, который дает нам нулевую строку. Необходимость инициализировать регистр (из значения по умолчанию0
, которое вылетаетy
) означает, что мы не можем неявно упомянуть ввод пользователя, то есть взять его из стандартного input (Ɠ
) так же дешево, как и взять его из Аргумент командной строки (³
или⁸
) и возможность доступа к альтернативному использованию⁸
означает, что необычная (для Jelly) форма ввода на самом деле на байт короче.Возможно, это невозможно. Я до сих пор не понял, почему вторая строка должна говорить,
⁸Ǥ;
а не просто;@Ç
- эти две должны быть эквивалентны, насколько я понимаю, Jelly, учитывая отсутствие использованияµ
/ð
/ø
- но последняя по какой-то причине вылетает. Аналогичным образом, существуют различные другие способы перестановки программы без потери байтов, поэтому возможно, что я упустил способ сделать вещи немного короче.Между прочим, изменение
ḷ
в последней строке;
дает вам интересный взгляд на внутреннюю работу программы, поскольку затем она выведет «историю регистра», которая неявно выводится возвращаемыми значениями2Ḷ
.источник
Perl 5 , 92 байта
90 байтов кода +
-pl
флаги.Попробуйте онлайн!
Я использую хеш-таблицу
%h
для хранения сопоставления между числами.Функция (
sub
)f
возвращает номер, на который указывает ее входная карта (или ее входные данные, если она не указана):$h{$a=pop}
извлекает номер, на который отображается входная карта. Если это не так, спасибо//$a
, значение($b=$h{$a=pop}//$a)
является input ($a
). Мы удостоверяемся, что эти значения не являются самими входными данными, чтобы не зацикливаться бесконечно (!=$a
). Затем мы либо рекурсивно вызываем,f
либо возвращаем ввод.Основная программа состоит из двух этапов:
-
s%(\d+)\+(\d+)%f($1)+f$2%e&&redo
оценивает первое добавление с правой стороны, при этом еще есть добавление: оно заменяетсяx+y
результатом оценкиf(x)+f(y)
.-
/=/;$_=$h{f$`}=f$'
выполняет задание:/=/
позволяет получить доступ к левой стороне с$`
и правой стороне с$'
, затем$h{f$`}=f$'
делает назначение. И мы также присваиваем его тому,$_
что неявно печатается после каждой строки.источник
JavaScript (Node.js) , 81 байт
Попробуйте онлайн!
Получает ввод, вызывая f со значением, которое нужно присвоить, затем вызывая результат этого с массивом значений, которые нужно сложить вместе. (т.е.
f(5)([4])
) Повторите для нескольких строк.v
используется как функция для вычисления фактического текущего значения числа, а также как объект для хранения фактических значений. Сначалаv[x]=v[x]||x
убедитесь, чтоv[x]
это определено.v[x]-x
выполняет сравнение, чтобы определить, является ли это фактическим числом или нет. Если число не отображается на себя,v(v[x])
рекурсивно пытается снова, в противном случае вернитеx
.f
выполняет вычисление и присваивание, карри для сохранения одного байта, где второй вызов возвращает вычисленное значение.источник
Haskell ,
116 113 108106 байтПопробуйте онлайн! Каждое уравнение
4=3+1+5
обозначается как кортеж(4,[3,1,5])
. Анонимная функция(id?)
берет список таких кортежей и возвращает список всех промежуточных результатов.#
является функцией , чтобы найти неподвижную точку данной функцииe
и начальное значениеx
.Функция
?
принимает функцию оценкиe
и рекурсивно решает каждое уравнение.foldl1(\a b->e#(e#a+e#b))s
оценивает правую часть уравнения и сохраняет результатm
, например, для4=3+1+5
вычисленияeval(eval(eval 3 + eval 1) + eval 5)
, где каждыйeval
является приложением с фиксированной точкойe
. Затем функция eval модифицируется, чтобы принять во внимание новое назначениеn
:(\x->last$m:[e#x|x/=e#n])
то же самое, что и\x -> if x == eval n then m else eval x
.Начальная функция оценки -
id
это отображение каждого целого числа на себя.Спасибо Орджану Йохансену за более короткую функцию с фиксированной точкой, экономящую 2 байта!
источник
last.
(#)e=until((==)=<<e)e
или(#)=until=<<((==)=<<)
короче.ок, 48 байт
Использование:
f[5;1 2 3] / 5=1+2+3
Попробуйте онлайн!
Если вы не против того , верхнего предела чисел , которые можно использовать, например, только с помощью чисел
0
через998
, то следующие суффиксы ( 41 байт ± несколько в зависимости от максимума):Объяснение:
;
разделяет три определения.a
словарь / карта чисел В первом случае, это фактический, пустой словарь[]
, во втором случае это список номеров0
в998
.s
является функцией, которая находит «результирующее» число, когда ему присваивается число./
На конце функции означает , что она будет применять себя свой собственный вывод , пока выход не перестанет изменяться.Последний бит
f
означает, что:источник
Python 3,
146132130 байт14 байтов сохранено благодаря @Dada
2 байта сохранено благодаря @ mbomb007
Попробуйте онлайн!
Получает входные данные в виде кортежей уравнений [
x = y + z + w
as(x, (y, z, w))
], выходные данные через генератор.источник
g
может быть написаноg=lambda x:d.get(x)and d[x]!=x and g(d[x])or x
. И я думаю, что вы можете использовать 1 пробел для отступа вместо 2. Это даст вам [132 байта] ( попробуйте онлайн! ).