n=e=$Input;
a=0;
w=While[{m=Modulo[$e];Not[m[1]];}];
w=w[{f=For[4];f=f[@x];f=f[{Print[$e];q=Equal[$x];i=If[{q[1];}];i=i[{k=Times[$e];}];Do[$i];i=If[{q[2];}];i=i[{k=Add[$e];}];Do[$i];i=If[{q[3];}];i=i[{k=Subtract[$e];}];Do[$i];i=If[{q[4];}];i=i[{k=Divide[$e];}];Do[$i];e=k[a=Increment[$a]];}];Do[$f];}];
Do[$w];
Попробуйте онлайн!
Пришло время снова использовать Рутгер. К сожалению, это может быть не самый лучший язык для этой задачи, так как он не имеет формы eval
, заставляя меня использовать четыре оператора if
Как это работает
Как работает Рутгер
Краткое предисловие о том, как работает язык: все является либо назначением, либо функцией, и каждая функция принимает ровно один аргумент. Для операций, которые требуют более одного аргумента (например, умножение), первый вызов возвращает частичную функцию , которая при повторном вызове со вторым аргументом возвращает ожидаемый результат. Например:
left = Times[5];
Print[left[6]];
распечатает 30: Попробуйте онлайн! , Хотя обычно это длиннее, чем обычная альтернатива, она может иногда сохранять байты, если функция вызывается повторно с одним постоянным аргументом и одним изменяющимся аргументом, например, при распечатке таблиц времени.
Это правило с одним аргументом применяется ко всему, что не является константой или переменной, включая циклы и условные выражения. Однако, циклы и условные ( For
, Each
, While
, DoWhile
, If
и IfElse
) являются выполнимыми , а это означает , что для того , чтобы фактически запустить их, Do
функция должна быть вызвана (см последней строки в ответе). Опять же, это может сохранить байты при многократном запуске одного и того же цикла или позволить вам запустить произвольный код между определением и выполнением циклов.
Наконец, есть три способа обращения к переменным, каждый из которых используется в этой программе. Первый - это прямая ссылка , где перед именем переменной стоит $
символ. Это напрямую обращается к значению переменной и возвращает его. Второе - это функциональные ссылки , которые не имеют префиксного символа. Это позволяет коду различать (потенциально частичные) функции, назначенные переменным, и фактические переменные, содержащие определенное значение. Наконец, косвенная ссылка с префиксом @
символа создает переменную (если она еще не существует) и возвращает объект переменной в заданной области видимости. Это позволяет вам создать переменную цикла (например, i
в for i in range(...)
).
Как работает настоящее решение
Вот негольфированный код:
n = elem = $Input;
var = 0;
while = While[{
mod = Modulo[$elem];
Not[mod[1]];
}];
while = while[{
for = For[4];
for = for[@index];
for = for[{
Print[$elem];
equal = Equal[$index];
if = If[{ equal[1]; }];
if = if[{ func = Times[$elem]; }];
Do[$if];
if = If[{ equal[2];}];
if = if[{ func = Add[$elem];}];
Do[$if];
if = If[{ equal[3];}];
if = if[{ func = Subtract[$elem];}];
Do[$if];
if=If[{ equal[4];}];
if=if[{ func = Divide[$elem];}];
Do[$if];
elem = func[var = Increment[$var]];
}];
Do[$for];
}];
Do[$while];
Попробуйте онлайн!
Как видно, она начинает путем присвоения трех переменных n
, e
и a
, которые представляют собой входные данные , изменяющийся элемент в последовательности, и число модификации для каждого нового элемента соответственно. Затем мы создаем цикл while:
w=While[{m=Modulo[$e];Not[m[1]];}];
{
}
m
e % m
100 → 1n → 0 , n ≠ 0
Далее мы подходим к абсолютному чудовищу, состоящему из тела цикла while:
w=w[{f=For[4];f=f[@x];f=f[{Print[$e];q=Equal[$x];i=If[{q[1];}];i=i[{k=Times[$e];}];Do[$i];i=If[{q[2];}];i=i[{k=Add[$e];}];Do[$i];i=If[{q[3];}];i=i[{k=Subtract[$e];}];Do[$i];i=If[{q[4];}];i=i[{k=Divide[$e];}];Do[$i];e=k[a=Increment[$a]];}];Do[$f];}];
4x
Print[$e];
q=Equal[$x];
i=If[{q[1];}];i=i[{k=Times[$e] ;}];Do[$i];
i=If[{q[2];}];i=i[{k=Add[$e] ;}];Do[$i];
i=If[{q[3];}];i=i[{k=Subtract[$e] ;}];Do[$i];
i=If[{q[4];}];i=i[{k=Divide[$e] ;}];Do[$i];
e=k[a=Increment[$a]];
Первый оператор печатает каждую итерацию последовательности перед ее изменением. Затем мы создаем частичную функцию для проверки равенства с переменной цикла x
и встречаемся с четырьмя операторами if. Каждый оператор проверяет , если x
равно 1, 2, 3 или 4 соответственно, а затем назначают k
для каждой функции в *
, +
, -
и /
, затем делает его в частичную функцию с в e
качестве аргумента. Наконец, мы относим e
к k
работать с в a
качестве второго аргумента и приращения a
.