Мы все видели тех онлайн-математику, которые выглядят так:
Think of a number, divide by 2, multiply by 0, add 8.
И, по волшебству, все заканчивают с номером 8!
язык
Давайте определим язык программирования, который использует синтаксис текста выше, называемый «WordMath». Скрипты WordMath следуют этому шаблону:
Think of a number, <commandlist>.
Что в основном означает: взять число (в качестве ввода из STDIN) в качестве начального аккумулятора, выполнить все команды на нем и вывести результат.
Команды разделены разделителем ,
(запятая + пробел). Допустимые команды (обратите внимание, что #
представляет неотрицательное целое число :) :
add #
/subtract #
- Добавить / вычесть значение из аккумулятора.divide by #
/multiply by #
- floordiv / умножить аккумулятор на заданное значение.subtract from #
- Похожеsubtract
, ноacc = # - acc
вместоacc = acc - #
repeat
- повторите последнюю команду. Это не может быть первая команда, но вы должны поддерживать несколько последовательных повторов.
Соревнование
Ваша задача - создать программу или функцию, которая принимает действительный скрипт WordMath в качестве входных данных и переносит его в действительную полную программу - на том же языке, на котором написан ваш код.
Например, если мой код на Python 2 и сценарий:
Think of a number, subtract from 10, add 10, multiply by 2.
Выводимая программа может быть:
a = input()
a = 10 - a
a += 10
a *= 2
print(a)
Или в качестве альтернативы:
print(((10-input())+10)*2)
Пока это полная программа, которая принимает от STDIN
и печатаетSTDOUT
, или ближайшие эквиваленты языка.
правила
- Ваша исходная программа может предполагать, что ввод всегда является допустимым сценарием WordMath.
- Транспортируемые программы не должны обрабатывать математические ошибки, такие как деление на 0.
- Транслируемые программы могут предполагать, что входные данные представляют собой действительное целое число со знаком в пределах стандартного целочисленного диапазона вашего языка.
- Это код-гольф , поэтому выигрывает самое короткое решение (в байтах).
- Имеет значение только количество байтов вашей исходной программы - выводимый код может быть настолько длинным, насколько вы хотите!
Примеры скриптов
Пример 1:
Think of a number.
Возьмите ввод, ничего не делайте, отобразите это: программа кошки WordMath.
Пример 2:
Think of a number, divide by 5, subtract from 9.
Помните, что «делить» это разделение по полу, поэтому для этой программы 6 -> 8
и 29 -> 4
.
Пример 3:
Think of a number, add 5, add 10, multiply by 2, subtract 15, repeat, divide by 2.
Расширенная программа для кошек!
Пример 4:
Think of a number, subtract 1, repeat, repeat.
Берет число и вычитает 3.
-5/3
? Мы округляемся0
к отрицательной бесконечности?Ответы:
05AB1E ,
59565452 байтаПопробуйте онлайн!
Мой мозг болит как ад после этого ... Он выводит в 05AB1E код следующим образом:
Think of a Number
удаляется из-за неявного ввода.Subtract From #
кроющие к#s-
(подкачкиa
иb
и выполнить операцию).Subtract #
преобразует в#-
.Add #
преобразует в#+
.Multiply by #
преобразует в#*
.Divide by #
преобразует в#/
.Repeat
захватывает то, что в последний раз было сохранено в регистре, и объединяет его.Разъяснение:
Пример:
Входные данные:
Выход:
Попробуйте решение с вводом 10:
Попробуйте онлайн!
Смотрите это в Google:
Вот ссылка на то же уравнение, введенное в Google.
источник
Препроцессор C, 362 байта
Я ПОЛУЧИЛ это, работая только в препроцессоре C, но команда повтора оказывается слишком сложной для реализации. Поэтому вместо этого я использовал препроцессор для преобразования входных данных в массив, который затем интерпретируется некоторым дополнительным кодом.
Входные данные должны быть предоставлены в «input.wm» или просто помещены в источник в этой строке. Я включил его байты в свой счет, потому что считаю его немного хакерским и слегка противоречащим правилам испытания, так что это только уместно.
В любом случае, после того, как вы сбросите свой источник WordMath в файл input.wm, где его сможет найти компилятор, вы сможете просто скомпилировать его, как есть, с предупреждениями для создания исполняемого файла, который выполняет то, что говорит источник WordMath.
источник
Сетчатка, 170 байт
Потому что кто бы не хотел видеть это ?!
Я подумал о том, как здорово было бы увидеть решение Retina, и решил создать его быстро. Это заняло всего час. Как обычно, подсчет байтов предполагает кодировку ISO 8859-1.
Попробуйте онлайн
Вывод содержит завершающий символ новой строки, который не следует копировать при тестировании результирующей программы. Программа не поддерживает негативы, потому что стандартный целочисленный диапазон Retina (в унарном) не поддерживает.
Объяснение:
Математические программы:
Добавлять:
Добавьте количество единиц в начало. Добавить 5:
Вычесть:
Удалите количество единиц с начала. Вычтите 5:
Вычесть из:
Заменить вход
1
s наx
s. Положите рядом с фиксированным номером. Неоднократно удалитьx1
. Вычтите из 10:Умножить на:
Замените каждый
1
на определенное количество из них. Умножьте на 3:Разделить на:
Это использует мою программу Retina для Integer Division . Разделите на 2:
источник
$
совпадает в самом конце строки или перед завершающим переводом строки. Вам нужно,\z
если вы хотите только первое.GNU awk, 139 байтов
Призвание:
Тестовые случаи:
источник
Haskell,
232231 байтКонечно, функциональный программист предпочел бы вернуть функцию, а не строку, представляющую программу, но здесь мы идем:
Замечания: Мы всегда начинаем с добавления нуля, иначе перенос тривиальной программы WordMath не даст достаточно информации, чтобы определить тип, при котором
read
он используется.subtract from n
может быть реализован как(n-)
, но я использую((-)n)
для большей однородности. В случае, еслиsubtract n
я копируюsubtract
входные данные, мне не нужно их записывать, но мне нужно компенсировать недостающее место в конце.repeat
используется как операция по умолчанию; вместе с пустой начальной предыдущей операцией это позволяет легко игнорировать первые четыре слова.Пример использования:
Другие примеры дают следующие результаты:
источник
h
может выглядеть примерно такh s n r|x<-s.read.init$n=x%r.x
и вызываться с первым аргументом как функцияh(+)n r
(и где-то должна быть какая-flip
то часть, чтобы получить правильный порядок операторов), базовый случай есть_%_=id
. Основная функция может избежать всего шаблонного и просто бытьt l=id%words l
. - Благодаря карри, его можно рассматривать как переводчика, и эта идея может привести к более простому и / или более короткому решению.Python 2,
263258260221 байтЭто, вероятно, все еще может быть намного короче.
Попробуйте онлайн
Я использую
//
вместо/
, потому что последняя инструкция будет иметь.
в конце, делая любое число с плавающей точкой. Поэтому, чтобы сохранить согласованность деления, я использую целочисленное деление.Вывод тестовых случаев:
источник
if
s наo
следующее (что, я думаю, должно работать):o=[[o+[['+-'['s'in c],'//']['v'in c],'*']['m'in c]+n,n+'-'+o]['f'in c],'input()']['T'in c]
вы можете уменьшить его до 224.Befunge,
342305 байтПопробуйте онлайн!
Выход
Генерируемый код начинается с команды
&
(входное значение) и заканчивается командами.
(выходное значение) и@
(выход). Между ними у нас есть различные вычисления в форме<number><operation>
, где операция может быть+
(сложение),-
(вычитание),/
(деление на),*
(умножение на) и\-
(вычитание из).Само число немного сложнее, потому что Befunge поддерживает только числовые литералы в диапазоне от 0 до 9, поэтому все, что больше, нужно вычислять вручную. Так как мы уже чтение чисел в посимвольно, мы просто наращивать число как каждая цифра читается, так, например, 123 становится
155+*2+55+*3+
, то есть(((1 * 10) + 2) * 10) + 3
.Примеры
объяснение
Befunge не имеет возможности манипулировать строками как таковыми, поэтому большая часть анализа обрабатывается путем подсчета символов. Мы начинаем с того, что пропускаем первые 18 символов, что позволяет нам пройти фразу Думать о числе» (плюс запятая или точка). Затем, если следующий символ - это какая-то новая строка или EOF, мы сразу переходим к процедуре вывода, в противном случае мы продолжаем искать список команд.
Для разбора команды мы просто продолжаем считать символы, пока не достигнем цифры или разделителя. Если это разделитель, это должна быть команда повтора, которую мы обрабатываем как особый случай. Если это цифра, мы добавляем ее в наш выходной буфер и продолжаем искать другие цифры. Каждый раз, когда выводится цифра, мы добавляем к ней префикс
55+*
(чтобы умножить итоговое значение на 10) и добавляем суффикс+
добавляем к ней добавляем (чтобы прибавить к итоговому значению). Когда цифры заканчиваются, мы добавляем символ команды.Что касается определения команды, мы берем количество символов до первой цифры по модулю 7. Для сложения это 4 (включая следующий пробел), для вычитания это 2, для деления на 3, для умножения на 5 , и для вычитания из его 0. Вычитание из требует немного дополнительной обработки, так как это требует
\-
комбо команды, но другие просто используют свое значение для поиска соответствующего символа команды в таблице.Этот процесс повторяется для каждой команды, собирая вывод в предварительно сконструированную строку в строке 8. Каждый раз, когда добавляется дополнительная команда, мы также добавляем заключительную кавычку в строку, чтобы убедиться, что она всегда правильно завершается. Затем, когда мы в конечном итоге достигаем конца нашего ввода, мы просто «выполняем» эту строку, чтобы поместить ее в стек, а затем следуем за ней со стандартной последовательностью вывода, чтобы выписать все это.
источник
JavaScript (ES6), 163 байта
Попытайся:
источник
Vim
208171168 байтДобавлена возможность делать несколько повторов подряд в соответствии с @ Flp.Tkc, но отыграть достаточно байтов, чтобы я мог уменьшить количество байтов.
TryItOnline
Непечатные символы:
Вывод тестовых случаев:
cw^R=^R" ^[
TryItOnlinecw^R=((^R" /5) *-1+9) ^[
TryItOnlinecw^R=((((((^R" +5) +10) *2) -15) -15) /2) ^[
TryItOnlineисточник
лекс, 246 байт
lex предназначается для C, поэтому компилятор C должен будет скомпилировать его в нечто исполняемое. Библиотека lexer (
ll
) также должна быть связана. Это может добавить байт-штраф, но я не уверен, сколько байтов, если так.Программа выводит программу lex (согласно спецификации), которая оценивает переданное выражение словосочетания. Код между
%{
и только%}
для "транспилятора":Между двумя
%%
строками находится часть регулярного выражения / действия. Первым правилом, которое нужно сопоставить, было быT
(«Подумай ...»), которое строит преамбулу (программы lex должны начинаться как минимум с раздела правила, иyytext
является последним совпадающим текстом, поэтому правило, по сути, заполняет аккумулятор вводом пользователя). ).В программе отбрасывает все входные кроме той , которая согласована, а также другие правила (
ad
,fr
доre
) обрабатывать выражения wordmath положения с минимально совпадение , насколько это возможно , чтобы быть уникальным. В большинстве из них он устанавливаетc
инфикс выражения, который соединяется междуn
последним целочисленным и последним чтением приO
вызове (так, например, чтение «add 9» установит инфикс равным+=
v9
, и вызовO
вызоветn+=9;
) , (Интересно отметить, что «вычитание из 8» приведет к тому, чтоs
иfr
правила, и правила будут сопоставлены, но, поскольку ониO
вызываются только по номеру, правильное правилоn=-n+8;
- единственное выражение, которое получает выходные данные).re
Правило для «повторения» только звонкиO
опять же, который выводит последнее созданное выражение (и поскольку последующие совпадения будут сгущатьсяyytext
, поддержка "repeat" является причиной целочисленного преобразования в[0-9]+
правиле). Наконец, период вызывает вывод трейлера программы, который просто выводит аккумулятор и замыкается%%
парой, обозначающей конец программы вывода lex.Заметка: ни основная программа транспортера, ни программа вывода не завершатся. Будет работать вход по трубопроводу или обеспечение EOF (ctrl-D). Если после первого ввода требуется завершение, можно добавить exit ().
Чтобы построить / запустить:
Тест 1:
Тест 2:
Тест 3:
Тест 4:
источник
Pyth,
6967 байтПрограмма, которая принимает на вход
"quoted string"
и печатает результат.Тестирование
Как это работает
У Pyth есть префиксные операторы, поэтому основные арифметические операции выполняются с использованием
(operator)(operand1)(operand2)
, а предварительно инициализированная переменнаяQ
выдает ввод. Следовательно, переносимая программа WordMath создается, начиная со строки'Q'
и на каждом этапе, добавляя оператор, а затем добавляя или добавляя операнд как необходимый.J\Q
SetJ
, передаваемая строка программы, в строку'Q'
tcQ\,
Разбейте ввод на запятые и отбросьте первый элемент (которыйThink of a number'
)V
ИбоN
в этом:Iq@N1\r
Если символ вN[1]
это'r'
(повторить):=NZ
УстановитьN
вZ
(предыдущее значениеN
, установить в конце цикла for)x"asdm"@N1
Найти индексN[1]
в"asdm"
(сложение, вычитание, деление, умножение)@"+-/*"
Индекс с этим в"+-/*"
, давая требуемый оператор,J-eCN)\.
Получите двухэлементный список[J, -eCN)\.]
, где второй элемент - это последний элементN
разбиения на пустом пространстве с'.'
удаленными символами (операнд)qh@cN)1\f
Если первый символ второго элементаN
разбиения в пробеле равен'f'
(вычесть из):.>
Поменяйте местами элементы двухэлементного списка+
Объединить оператор и двухэлементный список в один список=Jjd
ПодбирайJ
что попало на пробелы=ZN
УстановитеZ
наN
J
РаспечататьJ
источник
Пип , 58 байт
Жаль, что я еще не реализовал этот оператор обратного вычитания.
Программа берет скрипт WordMath из стандартного ввода и выводит код Pip в стандартный вывод. Код, который выводится, аналогично, берет число из stdin и выводит результат в stdout. Попробуйте онлайн!
стратегия
Для ввода, как это:
мы хотим вывод как это:
который работает следующим образом:
Ungolfed + объяснение
Основная структура программы
{...}Mq^k
, которая разделяетсяq
(строка стандартного ввода) наk
(запятая) иM
добавляет функцию к каждому элементу.Внутри функции мы начнем с обработки
repeat
кейса. Самый короткий тест в Пипе, кажется,sNa
(есть ли пробел в команде). Если так, мы хотим использоватьa
; если нет, используйтеp
, где хранится предыдущая команда. Присвойте это значение обратно,a
а такжеp
(в следующий раз).Для нашего возвращаемого значения мы используем список, что хорошо, потому что формат вывода по умолчанию для списков состоит в объединении всего вместе. Результат всегда начинается с
Y
. Далее нам нужна таблица соответствия для операций.Заметим, что длины
add
(4),subtract
(9),divide by
(10),multiply by
(12) иsubtract from
(14) различны. Далее отметим, что они все еще различаются при использовании мода 7. Таким образом, мы можем использовать их для индексации в список из семи элементов (содержащий пять фрагментов кода и два заполнителя), чтобы сопоставить каждую команду WordMath с соответствующим кодом Pip (рассчитанным так: число можно просто конкатенировать до конца)-y+
(subtract from
)y-
(subtract
)y//
(divide by
)y+
(add
)y*
(multiply by
)Для индексов, мы используем регулярное выражение , чтобы получить индекс первого разряда в команде:
a@?`\d`
. Мы также добавили регулярное выражениеy
для будущего использования. Таблица поиска создается путем разбиения строки"-y+ y- y// y+ y* "
наs
(пробел).Нам еще предстоит обработать первую запись, которая должна быть переведена в код
Yq
. ПосколькуThink of a number
не содержит никаких цифр,@?
оператор возвращает ноль. Использование nil в качестве индекса в таблице поиска также возвращает nil. Nil - это ложь, поэтому все, что нам нужно сделать, это добавить|'q
для использованияq
вместо операции для этого случая.Последний элемент возвращаемого списка - это само число. Мы получаем это с помощью
a@y
(найдите все совпадения в команде числа с регулярным выражением, которое мы вытащили ранее). Это возвращает список цифр, но опять же, это не проблема, потому что все списки будут объединены при выводе. Для первой записиa@y
не соответствует ни одной из цифр и выдается пустой список, который ничего не добавляет к выводу.Например
С входом
выражение карты дает список
который при объединении выводит
источник
Python 2 ,
154153146 байтИсправлено и даже сохранено несколько байтов в процессе. ^ __ ^
Попробуйте онлайн!
Основано на той же стратегии, что и мой ответ Пипа . Особенности Python:
Think of
и закрытие.
удаляются из строки перед разделением (input()[9:-1]
). Период был слишком досадным для основного цикла. Удаление первых девяти символов помогает по другой причине (см. Ниже).import re
), мы используем,rfind(" ")
чтобы найти последний пробел в команде. Мы также можем использовать это для проверкиrepeat
случай.a number
это индекс пространства1
. Этот индекс удобно заполняет другое отверстие в таблице поиска. Другая проблема с обработкой входного каскада в главном цикле была+c[s:]
частью, которая привела бы кx=input() number
. Чтобы решить эту проблему, мы умножаем строку наc[0]<"a"
:1
для всех обычных команд, в которыхc
начинается с пробела, но0
для начальныхa number
.источник
WinDbg,
449388 байт-61 байт путем определения псевдонима для повторного кода
Вдохновленный LambdaBeta в использовании
#define
. Этот подход немного изменяет синтаксис WordMath (,
и.
должен быть разделен пробелом, как и другие слова, и,
не следуетrepeat
), и создает псевдоним, так что измененный синтаксис WordMath является допустимым кодом WinDbg. Последняя строка делает то, что задает вопрос и переносит путем преобразования ввода в измененный синтаксис.Ввод осуществляется путем установки строки по адресу памяти и установки псевдорегистра
$t0
по этому адресу. Примечание: это перезапишетint
at0x2000000
, поэтому, если вы начнете там свою строку, она будет частично перезаписана.$t0
также будет перезаписано.Поскольку он создает псевдонимы, в зависимости от того, выполнялся ли этот код до или после установки строки, выходной код будет другим (либо псевдонимом, либо нет). К сожалению, я не нашел способа заставить псевдонимы правильно расширяться без разделения пробелов (то есть сценарий WordMath нельзя было просто выполнить напрямую, без предварительного преобразования).
Как это работает:
Пример вывода, ввод строки перед выполнением этого кода один раз (результирующая программа напоминает WordMath):
Пример вывода, ввод строки после того, как этот код был выполнен один раз (псевдонимы расширяются при вводе строки, поэтому результирующая программа выглядит не так красиво):
Еще несколько примеров вывода, просто используя слегка измененный синтаксис WordMath:
источник
Scala, 338 байт
Попробуйте сами в ideone
Объяснение:
источник