Теорема Цекендорфа показывает, что каждое положительное целое число может быть однозначно представлено в виде суммы несмежных чисел Фибоначчи. В этом задании вы должны вычислить сумму двух чисел в представлении Цекендорфа.
Пусть F n будет n-м числом Фибоначчи, где
F 1 = 1,
F 2 = 2 и
для всех k > 2 F k = F k - 1 + F k - 2 .
Представление Цекендорфа Z ( n ) неотрицательного целого числа n представляет собой набор натуральных чисел, таких что
п = Σ я ∈ Z , ( п ) Р я и
∀ я ∈ Z , ( п ) я + 1 ∉ Z ( п ).
(в прозе: представление Цекендорфа числа n представляет собой набор натуральных чисел, таких, что числа Фибоначчи для этих индексов суммируют до n, и никакие два соседних целых числа не являются частью этого набора)
Примечательно, что представление Zeckendorf является уникальным. Вот несколько примеров для представлений Zeckendorf:
Z (0) = ∅ (пустое множество)
Z (1) = {1}
Z (2) = {2}
Z (3) = {3} ({1, 2} не является представлением Цекендорфа 3)
Z (10) = {5, 2}
Z (100) = {3, 5, 10}
В этой задаче представления Цекендорфа кодируются как наборы битов, где младший значащий бит представляет собой, если он 1
является частью набора, и т. Д. Можно предположить, что представления Цекендорфа как входных, так и выходных данных укладываются в 31 бит.
Ваша задача - вычислить Z ( n + m ) с учетом Z ( n ) и Z ( m ). Решение с наименьшей длиной в октетах выигрывает.
Справочную реализацию, написанную на ANSI C, можно найти здесь . Он также может быть использован для генерации представлений Цекендорфа или вычисления числа из его представления Цекендорфа.
Вот несколько пар примеров ввода и вывода, где первые два столбца содержат входные данные, а третий столбец содержит выходные данные:
73865 9077257 9478805
139808 287648018 287965250
34 279004309 279004425
139940 68437025 69241105
272794768 1051152 273846948
16405 78284865 83888256
9576577 4718601 19013770
269128740 591914 270574722
8410276 2768969 11184785
16384 340 16724
Ответы:
K (нгн / к) ,
45 43 4241 байтПопробуйте онлайн!
Алгоритм Бубблера
{
}
функция с аргументомx
64(
)/0
сделать 64 раза, используя 0 в качестве начального значения:1,
подготовить 1+':
добавить каждый предыдущий (оставить первый элемент без изменений)F:
назначитьF
для "последовательности Фибоначчи"|
обеспечить регресс(
..){y!x}\
.., начиная со значения слева, вычисляет кумулятивные остатки (слева направо) для списка справа. значение слева представляет собой простую сумму входных данных без представления Цекендорфа:2\x
двоичное кодирование входов. это будет матрица размером 2 бит на 2|
обеспечить регресс+/'
суммировать каждый&
где 1с? - список показателей. если есть любые 2, соответствующий индекс повторяется дважды.F@
индексация массива вF
+/
сумма<':
меньше, чем каждый предыдущий (первым результатом всегда будет фальси)2/
двоичное декодированиеисточник
CJam,
7674706359 байтПопробуйте онлайн в интерпретаторе CJam или проверьте все тестовые случаи одновременно .
идея
Мы начнем с определения небольшого варианта последовательности в вопросе:
Таким образом, бит 0 (младший бит) из входных битовых массивов или выход соответствует числу Фибоначчи G 0 и, в общем, бит к к G к .
Теперь мы заменим каждый установленный бит в Z (n) и Z (m) на индекс, который он кодирует.
Например, вход 532 10 = 1000010100 2 преобразуется в [2 4 9] .
Это дает два массива целых чисел, которые мы можем объединить в один.
Например, если n = m = 100 , результат будет A: = [2 4 9 2 4 9] .
Если мы заменим каждое k в A на G k и добавим результаты, мы получим n + m = 200 , поэтому A - это способ разложения 200 на числа Фибоначчи, но, конечно, не тот, что из теоремы Цекендорфа.
Помня, что G k + G k + 1 = G k + 2 и G k + G k = G k + G k-1 + G k-2 = G k + 1 + G k-2 , мы можем заменить последовательные и дублированные индексы другими (а именно ((k, k + 1) на k + 2 и (k, k) на (k + 1, k - 2) ), повторяя эти замены снова и снова, пока не будет достигнуто представление Цекендорфа. 1
Особый случай должен быть взят для результирующих отрицательных индексов. Поскольку G -2 = 0 , индекс -2 можно просто игнорировать. Кроме того, G -1 = 0 = G 0 , поэтому любой результирующий -1 должен быть заменен на 0 .
Для нашего примера A мы получаем следующие (отсортированные) представления, последним из которых является представление Цекендорфа.
[2 2 4 4 9 9] → [0 3 4 4 9 9] → [0 5 4 9 9] → [0 6 9 9] → [0 6 7 10] → [0 8 10]
Наконец, мы конвертируем обратно из массива целых в битовый массив.
Код
1 Реализация пытается заменить 32 раза и не проверяет, было ли фактически достигнуто представление Цекендорфа. У меня нет формального доказательства того, что этого достаточно, но я проверил все возможные суммы 15-битных представлений (чьи представления сумм требуют до 17 бит), и для всех них было достаточно 6 повторений. В любом случае увеличение числа повторений до 99 возможно без увеличения числа байтов, но это снизит производительность.
источник
APL (Dyalog Extended) , 39 байт
Попробуйте онлайн!
Изменен в полную программу, принимающую один аргумент длины 2, а также изменил генератор Фибоначчи. Спасибо @ngn за множество идей.
Использует
⎕IO←0
так, что⍳2
оценивает0 1
.Генератор Фибоначчи (новый)
Обратите внимание, что последние два числа являются неточными, но это не меняет вывод программы.
Цекендорф в равнине
APL (Dyalog Extended) , 47 байт
Попробуйте онлайн!
Изменена часть 1 предыдущего ответа для повторного использования чисел Фибоначчи. Кроме того, удалите дубликат 1, чтобы сохранить несколько байтов в других местах.
Часть 1 (новая)
APL (Dyalog Extended) , 52 байта
Попробуйте онлайн!
Как это работает
Нет сложного алгоритма для добавления в Zeckendorf, потому что APL не известен работой с отдельными элементами в массиве. Вместо этого я решил преобразовать два входных значения из Цекендорфа в простые целые числа, добавить их и преобразовать обратно.
Часть 1: Zeckendorf для простого целого числа
Часть 2: Добавьте два простых целых числа
Часть 3: Преобразование суммы обратно в Цекендорф
«Можно предположить, что представления Цекендорфа как входных, так и выходных данных помещаются в 31 бит», было довольно удобно.
Генератор Фибоначчи
Это следует из свойства чисел Фибоначчи: если Фибоначчи определяется как
тогда
Итак, накопленная сумма1 ,F0, ⋯ ,FN (Массив Фибоначчи с добавлением 1) становится F1, ⋯ ,Fn + 2 , Затем я снова добавляю 1, чтобы получить обычный массив Фибоначчи, начинающийся с индекса 0.
Цифры Фибоначчи в Цекендорф
источник
Хаскелл, 325
396байтовРЕДАКТИРОВАТЬ: новая версия:
z
делает работуисточник
=
есть, поэтому родители там не нужны и так далее, и так далее, и обратите внимание, что:
ассоциируется справа, и вы можете сократить некоторые там. Но, в любом случае, поздравляю! Выглядит очень сложно. Не могу дождаться, чтобы выяснить, как это работает!ES6, 130 байт
Первоначально я пытался вычислить сумму на месте (по сути, в соответствии с реализацией CJam), но у меня не хватало временных значений, поэтому я просто преобразовал числа в реальные целые числа и обратно.
(Да, я могу, вероятно, сохранить байт, используя eval.)
источник
Рубин ,
85 7365 байтПопробуйте онлайн!
Как?
Сначала получите верхнюю границу для закодированной суммы: (a + b) * 2 в порядке.
Теперь отфильтруйте все числа не-Зеккендорфа из (0..limit).
У нас есть справочная таблица, отсюда вниз по склону.
источник
Python 3, 207 байт
Попробуйте онлайн! (Проверьте все контрольные примеры)
объяснение
Эта программа напрямую управляет двоичными переводами представлений Цекендорфа. Функция
a(n,m)
выполняет основные вычисления иs(n)
является вспомогательной функцией, которая избавляет от соседних чисел, содержащихся в представлении Цекендорфа.Давайте начнем с функции
s(n)
(расширенной для ясности):Например, число 107 (
1101011
в двоичном виде, представляющее 1 + 2 + 5 + 13 + 21 = 42), подвергается следующему процессу:Попробуйте онлайн! (с подробным выводом)
Вот расширенная версия
a(n,m)
:Эта функция преобразует два представления Цекендорфа в четыре двоичных числа, которые легче объединить. Линия (A) - это побитовое ИЛИ двух двоичных представлений Цекендорфа - они соответствуют одной копии каждого числа Фибоначчи в любой группе. (B) и (C) - побитовое И двух чисел, сдвинутых вправо 1 и 2 раза соответственно. Мы знаем, что когда соответствующие числа Фибоначчи для (B) и (C) складываются вместе, они будут эквивалентны поразрядному И нашего
n
иm
потому что F (n) = F (n-1) + F (n-2) ,Например, предположим, что у нас есть двоичные числа n = 101001 (что соответствует 1 + 5 + 13) и m = 110110 (2 + 3 + 8 + 13). Тогда мы будем иметь (A) = 111111 (1 + 2 + 3 + 5 + 8 + 13), который преобразуется в 1010100 (3 + 8 + 21) по нашей функции
s
, (B) = 10000 (8) и ( С) = 1000 (5). Мы можем проверить, что (1 + 5 + 13) + (2 + 3 + 8 + 13) = (3 + 8 + 21) + (8) + (5) = 45. Этот процесс повторяется с ((3 + 8 + 21) + (8)) + (5) = ((3 + 8 + 21) + (5) + (3)) + (5) и т. Д.Единственная сложность этой системы в том, что она не работает для чисел Фибоначчи 1 и 2, поскольку они не подчиняются свойству
F(n)=F(n-1)+F(n-2)
(это самые младшие два числа)! Из-за этого, когда 1 или 2 содержится в обоихn
иm
, они удаляются из A, B и C, их сумма помещается в D под свойством 1 + 1 = 2 и 2 + 2 = 1 + 3. Например, если мы добавим 1 + 3 (101) + 1 + 3 + 5 (1101), мы получим:(А): 3 + 5 (1100) = 8 (10000)
(В): 2 (10)
(С): 1 (1)
(D): 2 (10)
Обратите внимание, что 3 и 5 были помещены в A, дубликат 3 был разделен на 2 + 1 в B и C, а дубликаты 1 были удалены из A, B и C, добавлены вместе и помещены в D. Аналогично, если мы сложив 2 + 3 (110) + 2 + 3 + 5 (1110), получим:
(А): 3 + 5 (1100) = 8 (10000)
(В): 2 (10)
(С): 1 (1)
(D): 1 + 3 (101)
Попробуйте онлайн! (с подробным выводом)
источник
Wolfram Language (Mathematica) , 218 байтов
Попробуйте онлайн!
Просто сопоставление с образцом.
Ungolfed:
источник