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
, змушує мене використовувати чотири, якщо заяви
Як це працює
Як працює Рутгер
Коротка передмова про те, як працює мова: Все є або призначенням, або функцією, і кожна функція бере рівно один аргумент. Для операцій, для яких потрібно більше одного аргументу (наприклад, множення), перший виклик повертає часткову функцію , яка при повторному виклику з другим аргументом повертає очікуваний результат. Наприклад:
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
, які представляють собою вхідні дані , що змінюється елемент в послідовності, і число модифікації для кожного нового елемента відповідно. Потім створюємо цикл "час":
w=While[{m=Modulo[$e];Not[m[1]];}];
Дужки ( {
і }
) визначають блок коду, де остаточне твердження в блоці є умовою циклу while. У цьому випадку ми почнемо з визначення часткової функції модуля, яка прийме другий аргумент m
, і повернемось e % m
. Потім ми називаємо цю часткову функцію за допомогою1 як другий аргумент, що повертається 0для цілих чисел та ненульового цілого числа для плавців. Потім обчислюємо логічне не це, відображення0 → 1 і n → 0 , n ≠ 0.
Далі ми приходимо до абсолютної чудовисько, що складається з тіла циклу:
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];}];
Основна частина цього циклу - це цикл for, який ітераціює 4разів кожна ітерація циклу while має ітераційну змінну x
і складається з:
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
.