преамбула
Целые числа всегда либо четные, либо нечетные . Четные целые числа делятся на два, нечетные целые - нет.
Когда вы добавляете два целых числа, вы можете определить, будет ли результат четным или нечетным, основываясь на том, были ли слагаемые четными или нечетными:
- Даже + Даже = Даже
- Четный + Нечетный = Нечетный
- Нечетный + Четный = Нечетный
- Нечетный + Нечетный = Четный
Аналогично, когда вы умножаете два целых числа, вы можете сделать вывод, будет ли результат четным или нечетным, исходя из того, были ли факторы четными или нечетными:
- Даже * даже = даже
- Четный * Нечетный = Четный
- Нечетный * Четный = Четный
- Нечетный * Нечетный = Нечетный
Таким образом, если вы знаете четность или нечетность всех переменных в математическом выражении, которое включает только сложение и умножение, вы можете сделать вывод, будет ли результат четным или нечетным.
Например, мы можем с уверенностью сказать, что это (68 + 99) * 37
приводит к нечетному, потому что четный плюс нечетный ( 68 + 99
) является нечетным, и что нечетный раз другой нечетный ( odd * 37
) дает нечетное.
Вызов
Напишите программу или функцию, которая принимает строку, содержащую только четыре символа eo+*
. Эта строка представляет математическое выражение, данное в префиксной нотации, включающее только добавление ( +
) и умножение ( *
). Каждый e
представляет некоторое произвольное четное число, и каждый o
представляет некоторое произвольное нечетное число.
Ваша задача состоит в том, чтобы упростить выражение, распечатать или вернуть единичное e
или o
на основе того, является ли результат выражения четным или нечетным.
Вы можете предположить, что ввод всегда будет в действительной префиксной записи. В частности, каждый +
и *
всегда будет иметь два соответствующих операнда, следующих за ним. Эти операнды могут быть одним e
или o
, или другим, +
или *
выражением, которое, в свою очередь, имеет операнды.
Например, входные данные *+eoo
могут быть прочитаны как mul(add(e, o), o)
, или (e + o) * o
в нормальной записи инфикса . И e
первый o
- операнды, соответствующие +
, и +eo
последний o
- операнды, соответствующие *
.
Просто чтобы прояснить ситуацию, вот некоторые недопустимые входные данные, которые имеют неправильную префиксную запись:
eo
ooe
o+e
ee*
+*oe
+e*o
Единственный завершающий символ новой строки в выводе - это хорошо, но в противном случае все, что должно быть выведено, - это e
четное для четного или o
нечетного.
Самый короткий код в байтах побеждает.
Тестовые случаи
(Пустые строки служат только для визуального разделения похожих случаев.)
e -> e
o -> o
+ee -> e
+eo -> o
+oe -> o
+oo -> e
*ee -> e
*eo -> e
*oe -> e
*oo -> o
+e+ee -> e
+e+eo -> o
+e+oe -> o
+e+oo -> e
+e*ee -> e
+e*eo -> e
+e*oe -> e
+e*oo -> o
+o+ee -> o
+o+eo -> e
+o+oe -> e
+o+oo -> o
+o*ee -> o
+o*eo -> o
+o*oe -> o
+o*oo -> e
*e+ee -> e
*e+eo -> e
*e+oe -> e
*e+oo -> e
*e*ee -> e
*e*eo -> e
*e*oe -> e
*e*oo -> e
*o+ee -> e
*o+eo -> o
*o+oe -> o
*o+oo -> e
*o*ee -> e
*o*eo -> e
*o*oe -> e
*o*oo -> o
++eee -> e
++eeo -> o
++eoe -> o
++eoo -> e
++oee -> o
++oeo -> e
++ooe -> e
++ooo -> o
+*eee -> e
+*eeo -> o
+*eoe -> e
+*eoo -> o
+*oee -> e
+*oeo -> o
+*ooe -> o
+*ooo -> e
*+eee -> e
*+eeo -> e
*+eoe -> e
*+eoo -> o
*+oee -> e
*+oeo -> o
*+ooe -> e
*+ooo -> e
**eee -> e
**eeo -> e
**eoe -> e
**eoo -> e
**oee -> e
**oeo -> e
**ooe -> e
**ooo -> o
+e+e+e+ee -> e
+o+o+o+oo -> o
*e*e*e*ee -> e
*o*o*o*oo -> o
+e+o+e+oe -> e
+o+e+o+eo -> o
*e*o*e*oe -> e
*o*e*o*eo -> e
+e*e+e*ee -> e
+o*o+o*oo -> o
*e+e*e+ee -> e
*o+o*o+oo -> o
+**++*+*eeoeeooee -> e
+**++*+***eooeoeooeoe -> e
+**+***+**++**+eooeoeeoeeoeooeo -> o
+e*o*e**eoe -> e
+*e+e+o+e**eeoe -> e
**o++*ee*++eoe*eo+eoo -> o
источник
eval
ОК?Ответы:
CJam,
181713 байтовСпасибо aditsu за сохранение 4 байта.
Попробуйте тестовый набор здесь. (Набор тестов слишком длинный для постоянной ссылки. Просто скопируйте их из спецификации задачи.)
объяснение
источник
Pyth,
1614 байтовPyth может сам оценивать строку, то есть в синтаксисе Pyth. Поэтому я заменяю
e
иo
на4
и5
. Тогда оценка даст мне четное или нечетное число, и я легко смогу напечатать результат.Попробуйте онлайн: демонстрация или тестовый набор
Объяснение:
Дополнительное объяснение к замене.
G
переменная, инициализированная алфавитомabc...xyz
.U9
это список[0, 1, ..., 8]
.XzGU9
заменяет буквы алфавита значениями списка. Такa
заменяется0
,b
с1
, ...,e
с4
, ...,i
с8
,j
с0
, ... иo
с5
. Поэтому меняe
заменяют четным числом иo
нечетным числом. Все остальные замены не имеют никакого эффекта вообще.источник
Perl,
504540 символов(39 символов кода + 1 символ опции командной строки.)
Образец прогона:
источник
while/../
?sed
версию ... Спасибо, @primo.1while s/\+oe...
. Я также уверен, что[+*]
может быть заменен\W
.gema
сводит меня с ума…)Сетчатка , 29 байт
Для удобной версии файла используется
-s
флаг.Мы поменяться нечетные выражения (
*oo
,+oe
,+eo
) к ,o
пока мы не можем, а затем поменять оставшиеся символ буквы букв выраженияe
. Мы повторяем это до тех пор, пока не сможем, и последняя буква - это наш результат.(Это решение похоже на Perl-ответ manatwork .)
Попробуйте онлайн! (Деннис)
источник
Python 2, 90
Эта
iter
функция - хороший способ сделать входную строку в очередь FIFO, которая запоминает, какая часть строки была проанализирована при вызовахf
. Он идемпотентен, поэтому безвредно вызывать его снова, когда входные данные уже являются итератором, а не строкой. Задняя половина ответа, начинающаяся сor'oe'
... кажется, должна быть пригодной для игры в гольф, но я ничего не мог найти.-1 благодаря Sp3000.
источник
iter
действительно ошеломляют мой разум.eval
:def f(s,e=0,o=1):i=iter(s);a=next(i);return'eo'[eval(a*(a>'a')or f(i)+a+f(i))%2]
Mathematica,
9184 байтаИщете способ сжать это ...
источник
//.
короче чемFixedPoint
.Python 2, 80 байт
Это основано на очень умном ответе feersum, который использует
iter
для реализации операций польской нотации. Новая идея состоит в том, чтобы использоватьeval
для вычисления выражений+
и*
с темeval(f(i)+a+f(i))
, где операторa
ставит инфикс между рекурсивными результатами. Eval использует привязкиe=0,o=1
в необязательных аргументах функции. На выходе берется мод 2.источник
e+o
, поэтому ему нужны переменные для ссылки на числа.C, 79 байтов
Простая рекурсия. Полагается на некоторые (случайные?) Побитовые свойства четырех разрешенных входных символов.
источник
Утилиты Shell + GNU, 33
Ввод взят из STDIN.
Это делает ту же самую хитрость при обращении ввода и оценке с помощью стекового калькулятора - в этом случае
dc
. Мы могли бы заменитьe
иo
на0
и1
, но тогда нужно было бы вставить пробелы, чтобы избежать жадного разбора цифр в неправильные числа.Вместо
e
заменяетсяK
которая являетсяdc
командой , чтобы подтолкнуть текущую точность в стек, который по умолчанию равно 0. Аo
заменяетсяO
которая являетсяdc
командой , чтобы подтолкнуть текущую выходную базу в стек. Это должно быть странно, поэтому мы устанавливаем 15 с,Fo
прежде чем делать что-либо еще в dc.Тогда нужно просто взять мод 2 и распечатать
2%p
. Единственными возможными значениями являются сейчас0
и1
, поэтому не имеет значения, что база вывода равна 15. Затемtr
переводится обратно вo
илиe
.Мне нравится, что если ты прищуришься, этот источник выглядит почти так
dc Forever OK
.источник
Серьезно , 24 байта
Более эффективные манипуляции со стеком, вероятно, могли бы сделать это короче, но я доволен этим.
Принимает ввод в виде строки, например
"+*oee"
Попробуйте онлайн (ввод должен быть введен вручную)
Объяснение:
источник
Рубин, 61 байт
Использование рекурсивного синтаксического анализа и логической алгебры.
Функция читает один символ из стандартного ввода за раз. Если он читает a
+
или a*
, он дважды вызывает себя, чтобы определить нечетное или четное. Функция возвращаетtrue
для нечетных иfalse
дляeven
. Операторы^
XOR и&
AND используются для определения «нечетности» выражений сложения и умножения соответственно.Вот негольфированная версия:
Спасибо @Shel за указание на ошибку в начальной версии.
источник
+ee
даетo
. Мне нравится идеяf^f
на!f^f
иf&f
с,f|f
и это работает. Программа для запуска тестовых случаев: pastebin.com/ufXfd1vcf^f
иf&f
и перевернул$_==?e
и?e:?o
вместо этого :)Минколанг 0,14 , 40 байт
Я попытался сделать умный метод eval, но оказалось, что любые значения, добавленные в кодовое поле за пределами исходного пространства, никогда не будут достигнуты счетчиком программы. Так что я сделал менее умный метод eval. :П
Попробуй это здесь.
объяснение
источник
JavaScript,
110 10694 байтаКонечно, не самое маленькое решение, но, вероятно, самое маленькое из возможных решений в многословном языке, таком как JavaScript!
источник
?:
.while(i.length>2)i=i.replace(/[+*][eo]{2}/,function(o){return"+oe+eo*oo".indexOf(o)>=0?"o":"e"})
. Или, если вы переключитесь на функцию жирной стрелки ECMAScript 6, тогдаwhile(i.length>2)i=i.replace(/[+*][eo]{2}/,o=>"+oe+eo*oo".indexOf(o)>=0?"o":"e")
. Но, к сожалению, требование говорит о программе или функции, в то время как ваш текущий код является фрагментом. Он должен обрабатывать либо ввод и вывод, либо аргумент и возвращаемое значение.i
как вы сказали.О ,
24201918 байтПринимает входной сигнал, изменяет его, назначает
e
на 2 иo
на 1 исообщения его Tumblrоценивает его в качестве кода вывода.Объяснение:
источник
GNU Sed, 36
После отправки я увидел точно такой же подход , как @ manatwork - х Perl ответ и Retina ответ @ randomra в . Так что, я думаю, я могу пройти весь путь и позаимствовать их
\W\w\w
.Спасибо @Ruud за то, что сбрил 4 байта.
источник
+
, вы теряете 2 байта за побег|
, но в итоге вы выигрываете 1 байт за опцию сброса-r
.|
нужно избегать, когда-r
не используется. Тем не менее, еще 2 байта вне счета - спасибо!Haskell, 160 байт
Вызов
f
.источник
JavaScript,
9271 байтЭто немного запутано, но я хотел сделать что-то, используя
eval
побитовые операторы. Аннотированный:Повторение
(e[…]>"e")
немного раздражает, но и следующее не лучше (103 байта):Итак, в конце концов, подход @ Arkain с простым сопоставлением подстрок превосходит все ожидания. Сделано в функцию, с некоторыми оптимизациями:
источник
Дротик, 173 байта
Это не конкурентоспособно, но что угодно. Суть решения состоит в том, чтобы, начиная с 0, рекурсивно заменить каждый оператор на оценку пары символов, следующих за этим оператором, а затем удалить эти символы из списка.
источник
Haskell, 231 байт
Вот подход с использованием серьезного языка;)
Гольф версия:
Пример:
Недоверчивая и довольно полная версия:
Пример:
Особенности: сопоставление с образцом и рекурсия.
источник
Джольф, 11 байт
(Неконкурентоспособен, так как язык задвигает вопрос назад.) Попробуйте здесь!
(Заменить
\x12
на реальный символ\x12
. Это должно быть сделано автоматически в интерпретаторе.)Объяснение:
источник
Python 3,
171145135 байтовНе конкурентоспособный, но я получал удовольствие, делая это, поэтому я просто не мог оставить это при себе. В отличие от (очень умной) записи Python для рекурсивных итераторов, созданной feersum , эта операция инвертирует ввод, а затем выполняет хороший старый стековый анализ обратной польской записи.
источник
callable()
элегантно, но долго. (Изменение условия и удалениеnot
будет короче.) Вместо этого проверьте, является ли m целым числомm in[0,1]
, будет короче, но проверка, является ли значение cc in'eo'
, будет еще короче. Это позже так же, как иc>'a'
в этом случае.for
:s+=[c>'e'if c>'a'else{'*':o.and_,'+':o.xor}[c](s.pop(),s.pop())]
s.pop()
(дважды) каждого цикла. Я не беспокоился о тестировании до сих пор; но эй, сейчас вопрос спорный.operator
модуль?bool.__and__()
иbool.__xor__()
являются сподручнее:s+=[c>'e'if c>'a'else getattr(s.pop(),{'*':'__and__','+':'__xor__'}[c])(s.pop())]
. Но , основываясь на gnibbler «s нарезания наконечник , который может быть изменен вs+=[c>'e'if c>'a'else getattr(s.pop(),'__'+('axnodr'[c>'*'::2])+'__')(s.pop())]
.^
,&
) и ихoperator
аналоги, забывая о методах, которые на самом деле их реализуют. О, иreversed()
теперь был исключен благодаря другим советам по игре в гольф от Python .Haskell,
9894 байтаИзвините, что беспокою вас еще одной попыткой Haskell; просто хотел доказать, что это очень хорошо возможно менее чем за 100 байтов.
Определяет функцию,
p
которая принимает любое допустимое выражение в качестве параметра и возвращает результат в виде строки длиной 1.Пример:
Функция работает путем многократного сокращения самого правого оператора в строке, пока не останется ни одного оператора.
источник
Добавить ++ , 46 байт
Попробуйте онлайн!
Нижний колонтитул просто перечисляет все входные данные примера и их соответствующие выходные данные.
Как это устроено
Как потеря ответов здесь, это использует замену и оценку. Наша основная функция
f
, иg
является вспомогательной функцией. Мы будем использовать"*e*o*e*oe"
(что естьe
) в качестве примера.f
начинается с взятия входной строки и обращения ее к результату"eo*e*o*e*"
. Затем мы сопоставляемg
каждый элемент:g
начинается с дублирования аргумента, чтобы сохранить копию до последней команды. Затем мы проверяем, находится ли аргумент в строке"oe"
, получая 1 для букв и 0 для*
или+
. Затем мы снова выдвигаем аргумент и проверяем, равен ли он"e"
. Этот результат затем добавляется к предыдущей проверке. Это дает 0 для либо*
или+
, 1 дляo
и 2 дляe
. Затем мы берем логическое ИЛИ между этим значением и аргументом. Если значение равно 0 , оно заменяется аргументом (то есть*
или+
), в противном случае оно остается как есть (то есть 1 и 2 ).Это преобразует все буквы на обратной стороне ввода в числовое значение. Затем мы соединяем каждый элемент пробелами, чтобы гарантировать, что цифры не объединяются. Для нашего примера это дает строку
"2 1 * 2 * 1 * 2 *"
. Затем мы можем оценить это, используя постфиксную нотацию Add ++, получив 8 . Затем мы берем четность этого значения, получая либо 0 для четных чисел, либо 1 для нечетных чисел, перед индексацией в строку"eo"
и возвращением соответствующей буквы.источник