Алиса , 14 12 байт
/O
\i@/t&Yd&
Попробуйте онлайн!
Обратная функция (не игра в гольф):
/o Q
\i@/~~\ /dt&Z
Попробуйте онлайн!
объяснение
Алиса имеет встроенную биекцию между ℤ и ℤ 2 , которая может быть вычислена с помощью Y
(распаковка) и ее обратной Z
(упаковка). Вот выдержка из документов, объясняющих биекцию:
Детали биекции, вероятно, не имеют значения для большинства случаев использования. Суть в том, что он позволяет пользователю кодировать два целых числа в одно, а затем снова извлечь два целых числа. Повторно применяя команду pack, можно хранить целые списки или деревья целых чисел в одном числе (хотя это не особенно эффективно с точки зрения памяти). Отображение вычисляется с помощью операции упаковки является биективной функцией ℤ 2 → ℤ (т.е. отображение один к одному). Во-первых, целые числа {..., -2, -1, 0, 1, 2, ...} сопоставляются с натуральными числами (включая ноль), такими как {..., 3, 1, 0, 2, 4 , ...}(другими словами, отрицательные целые числа отображаются в нечетные натуральные числа, а неотрицательные целые числа отображаются в четные натуральные числа). Затем два натуральных числа отображаются в одно с помощью функции сопряжения Кантора , которая записывает натуральные числа вдоль диагоналей первого квадранта целочисленной сетки. В частности, {(0,0), (1,0), (0,1), (2,0), (1,1), (0,2), (3,0), ...} являются отображается на {0, 1, 2, 3, 4, 5, 6, ...} . Полученное натуральное число затем сопоставляется с целыми числами, используя обратную обратную биекцию. Команда unpack вычисляет в точности обратную зависимость от этого отображения.
Как упоминалось выше, мы можем использовать эту операцию распаковки, чтобы отобразить ℤ и ℤ k . После применения его к начальному целому числу мы можем снова распаковать второе целое число результата, что дает нам список из трех целых чисел. Таким образом, k-1 приложения Y
дают нам k целых чисел в результате.
Мы можем вычислить обратное, упаковав список с Z
конца.
Итак, сама программа имеет такую структуру:
/O
\i@/...d&
Это просто базовый шаблон для программы, которая считывает переменное число десятичных целых чисел в качестве входных данных и печатает переменное число в качестве результата. Таким образом, настоящий код действительно просто:
t Decrement k.
& Repeat the next command k-1 times.
Y Unpack.
Одна вещь, на которую я хотел бы обратить внимание: «почему у Алисы есть встроенная система для биографии ℤ → ℤ 2 , разве это не языковая территория игры в гольф»? Как и в большинстве странных встроенных функций Алисы, основной причиной является принцип разработки Алисы, согласно которому каждая команда имеет два значения: одно для кардинального (целочисленного) режима и одно для ординального (строкового) режима, и эти два значения должны как- то быть связаны, чтобы дать Кардинальный и Порядковый режим - ощущение, что они являются зеркальными вселенными, где вещи похожи, но различны. И довольно часто у меня была команда для одного из двух режимов, которые я хотел добавить, а затем мне приходилось выяснять, с какой другой командой он был связан.
В случае Y
и Z
режима Порядковый пришел первым: Я хотел бы иметь функцию чередования двух строк (ZIP) и отделить их снова (распаковать). Качество этого, которое я хотел уловить в режиме Cardinal, состояло в том, чтобы сформировать одно целое число из двух и иметь возможность извлекать два целых числа позже, что делает такую биекцию естественным выбором.
Я также подумал, что это было бы очень полезно вне игры в гольф, потому что он позволяет хранить весь список или даже дерево целых чисел в одной единице памяти (элемент стека, ячейка ленты или ячейка сетки).
k
иx
вместо целых чисел?