Рассмотрим грамматику над алфавитом { 0
, 1
, ?
, :
} определяется правилом производства
s →
0
┃1
┃0
?
s:
s ┃1
?
s:
s
Получив строку, сгенерированную из s , проанализируйте ее как выражение, где ?:
ассоциативно справа (например, a?B?X:Y:c?d:e?f:g
означает a?(B?X:Y):(c?d:(e?f:g))
), и оцените ее с помощью следующей семантики:
eval(0) = 0
eval(1) = 1
eval(0?a:b) = eval(b)
eval(1?a:b) = eval(a)
Если результат равен 0 , выведите некоторое фиксированное значение; если вывод равен 1 , выведите другое фиксированное значение. Укажите выбранные выходные значения (например, 0
/ 1
или False
/ True
) в своем ответе.
Контрольные примеры
0 -> 0
1 -> 1
0?0:1 -> 1
0?1:0 -> 0
1?0:1 -> 0
1?1:0 -> 1
0?1?0:1:1 -> 1
1?0?1:1:1 -> 1
1?0:1?0:1?1:1 -> 0
1?1?1:0?1?0:0:0:0 -> 1
1?0:1?0?1:1?1:0:1?1?1:1:1?0:1 -> 0
1?1?1:0?0?1:1:0?1:0:1?1?0?0:0:1?1:0:0?1?0:1:1?0:1 -> 1
0?0?1?0?0:1:0?0:0:0?0?1:1:1?0:1:0?0?0?1:0:0?1:1:1?1?0:1:1 -> 0
правила
- Вы не можете использовать встроенные языковые модули, которые интерпретируют строки как код в каком-либо языке программирования и запускают его (например, JavaScript / Perl / Ruby / Python
eval
). - Тем не менее, ваш код на самом деле не должен анализировать и затем оценивать входную строку. Вы можете использовать любой подход, чтобы получить эквивалентные результаты и не нарушать предыдущее правило.
- Ваша программа будет проверена
perl -le 'print eval<>'
. - Самый короткий код (в байтах) выигрывает.
S → T | T ? S : S
,T → 0 | 1
, устраняя необходимость говорить о ассоциативности?Ответы:
GolfScript, 21 байт
Это выводы
0
или1
. Предполагается, что вход имеет одну завершающую новую строку. Использование~
(которое оценивает строки) позволит сохранить байт:Это основано на http://golf.shinh.org/reveal.rb?The+B+Programming+Language/tails_1462638030&gs .
источник
Сетчатка , 23 байта
Попробуйте онлайн! (Первая строка включает набор тестов, разделенных переводом строки.)
объяснение
Это довольно просто на самом деле. Ввод сводится к результату путем многократного (
+
) вычисления троичных символов, содержащих только литералы. Чтобы убедиться, что это сделано справа ассоциативно, мы ищем совпадения справа налево (r
) и заменяем только последнее найденное совпадение (-1=
).Само регулярное выражение либо сопоставляет
0\?.:
и удаляет его (оставляя только материал после:
), либо1\?.:.
заменяет его значением после?
.источник
1
совпадение st вместо-1
st?Haskell,
106 101 100 9083 байтаЭто в значительной степени зависит от возможностей сопоставления с образцом в Haskell. Прежде всего, мы переворачиваем строку так, что мы можем просто выполнить поиск для первого вхождения
b:a?x
(который обычно читается какx?a:b
) и заменить ее значением. Это автоматически обеспечивает правильную ассоциативность . Здесь мы используемx:xs
шаблон. Это то, чтоf
делает функция . Затем мы в основном применяемf
к его выводу снова и снова, пока у нас не останется ни одного числа (0 или 1).Спасибо @Lynn за 12 байтов!
источник
Brainfuck,
826463 байтаВыход
\xff
для0
и\x00
для1
. Реализация мозгового перста должна позволять идти налево от стартовой ячейки.Это существенно использует тот же подход , как Python xsot в ответ , но ветвление, вероятно , труднее следовать по сравнению с моим первоначальным представлением 82 байт:
(Для этого решения выходные данные предназначены
\xfe
для0
и\xff
для1
, и более широкая совместимость достигается, когда ввод заканчивается новой строкой.)Если вам не мешает проанализировать решение xsot, идея заключается в следующем: действуйте слева направо. Если вы видите,
1?
то жадно откажитесь от него. Если вы видите,0?
тогда отбросьте все между этим и соответствующим:
. Если?
второй символ не отображается, прекратите цикл и напечатайте первый символ оставшейся строки.Таким образом, 82-байтовое решение фактически очень близко отражает эту схему. Внутренний цикл обрабатывает
0?
, как внутренний цикл xsot. Некоторое внимание уделяется тому, чтобы войти в основной цикл без проверки любых вводимых символов; т.е. мы хотим проверить, находится ли второй символ?
только один раз в конце основного цикла, а не также в начале перед входом в основной цикл.63-байтовое решение по существу объединяет внутренние и внешние циклы в один, что, как я подозревал, было возможно, учитывая сходство между этими циклами. Схема памяти в основном цикле может быть описана как:
где
[x]
означает текущую ячейку -s
начинается как фиктивное ненулевое значение, которое просто указывает, что мы все еще выполняем цикл, и немедленно перезаписывается вводимым символом (или,0
или1
).d
Клетка удерживает (отрицательную) глубину в случае , если мы находимся в середине0?
, в противном случае0
. Этоc
будет либо?
либо,:
либо перевод строки или EOF.После обновления
s
иc
мы обрабатываем0?
регистр, соответственно обновляяd
и корректируя указатель, в противном случае мы используем текущее значение вc
качестве значенияd
на следующей итерации или остановим, если мы закончили.источник
Python 2,
76747372 байтаС вводом в виде строкового литерала, чтобы избежать
raw_
.Вывод
0
или1
после<built-in function id>
.источник
3>>int(c)
`id`
трюк ... Молодцы :)Python 2, 89 байт
Ввод принимается как строковый литерал.
источник
Грязь ,
3431 байтОтпечатки
1
для правдивых входов и0
ложных. Попробуйте онлайн! К сожалению, в последнем тесте на TIO не хватает памяти.объяснение
Право-ассоциативность по сути означает, что в
a?b:c
,a
всегда либо,0
либо1
никогда более длинное выражение. Я просто рекурсивно определю шаблон, который соответствует истинному выражению, подобному этому, и проверю входные данные по нему. Также нет необходимости проверять, что каждое:
действительно является a:
, если все?
s проверены: во входных данных есть равное количество?
s и:
s, и если некоторые из?
них неправильно классифицированы как a:
, соответствующее:
не будет соответствовать, и соответствие Грайма двигатель будет возвращаться назад.источник
Haskell,
79 71 70 62 6056 байтРедактировать: Спасибо @Zgarb за 3 байта и @nimi за 4 байта!
Это рекурсивный подход,
который несколько нарушает правило вывода с некоторым фиксированным значением. Редактирование: избавление от кортежей не только экономит 8 байтов, но также дает более хороший результат:"0"
или"1"
.Безголовая версия:
Как это работает? Функция пересекает неявное дерево выражений
eval
и возвращает кортеж формы
(result, rest)
.Первый шаблон
(x:'?':r1)
совпадаетx
с'1'
иr1
с"0?0:1:0?1:0"
. Рекурсивное применениеeval
кr1
вычисляет подвыражение0?0:1
и возвращает(0,":0?1:0")
. Соответствие этому образцу(a,':':r2)
даетa=0
иr2=0?1:0
. Эта под формула также рекурсивно оценивается так, чтоb='0'
иr3=""
. Проверьте, еслиx
есть'1'
или'0'
и верните либо(a, r3)
или(b, r3)
.источник
x>'0'
работать на местеx=='1'
?':'
на_
.:
. Еще раз спасибо!if .. then .. else
сlast$e s:[a:tail(e s)|x>'0']
.JavaScript (ES6), 53 байта
Возвращает
0
или1
для правильного ввода; зависает для неверного ввода. Объяснение: поскольку в JavaScript изменение строки неудобно, моя первая попытка в 71 байт сработала с использованием отрицательного предвкушения для a,?
которое в противном случае нарушило бы ассоциативность:Поскольку это было довольно долго, я задавался вопросом, могу ли я улучшить положение дел, включив принятие решений в регулярное выражение. Как оказалось, это не был немедленный успех, так как он также занимал 71 байт:
Тогда мне пришло в голову, что
0?0:
и0?1:
всегда бездельники, не заботясь об ассоциативности. Это спасло меня почти на 25%.источник
f=
. Я не проверял, учитывает ли это количество ваших байтов или нет.Perl, 32 + 1 (
-p
флаг) = 33 байтаПолная заслуга @Mitch Swartch , поскольку его решение было на 14 байт короче моего!
Спасибо также @Neil, который предложил решение на 1 байт длиннее, чем Митч.
Необходимо
-p
пометить, как-M5.010
или-E
запустить. Например :Пояснения : Это в основном уменьшает блоки
a?b:c
(начиная с конца, чтобы убедиться, что не?
следует) вb
или вc
зависимости от истинностиa
, снова и снова, пока строка не содержит только1
или0
.источник
-
засчитывается ли ваш счет? Хмм. Интересно ... Хороший ответ!perl -e '<code>'
добавив, таким образом,p
только 1 байтperl -pe '<code>'
.?
, я смог сократить это до 34 байт таким образом.s/.*\K(1\?(.)..|0\?..)/\2/&&redo
Python 3,
9369 байтВвод является строка в виде списка символов, выход либо
"0"
или"1"
Безголовая версия:
Еще одна попытка, но со значительно большим количеством байтов:
источник
def f(s):x=s.pop(0);return[]<s<s.pop(0)>'>'and(f(s),f(s))[x<'1']or x
, и для Python 3 с небольшим расстоянием редактирования до вашего, естьdef f(s):z=s.pop;r=z(0);return s and':'<z(0)and(f(s),f(s))[r<'1']or r
.САС,
75 74 68(40 + 1 для -r) 41источник
(.*)
и добавить дополнительный термин замены.\3
вместо\2
. Кроме того, вы можете присоединиться к линии,;
чтобы получить:;s/(.*)(1\?(.):.|0\?.:)/\1\3/;t
.\3
так, значит я случайно скопировал предыдущую версию. Я знаю о точках с запятой. Но чёрт, зачем вам использовать точку с запятой.Утилиты Bash + GNU, 42
Подобная идея для большинства других совпавших по шаблону ответов.
Ideone .
источник
0
футляре, который экономит 5 байтов.