Давайте определим последовательность Фибоначчи как
F(1) = 1
F(2) = 2
F(n) = F(n - 2) + F(n - 1)
Итак, мы имеем бесконечную последовательность 1,2,3,5,8,13,
... Хорошо известно, что любое положительное целое число может быть записано как сумма некоторых чисел Фибоначчи. Единственное предостережение в том, что это суммирование может быть не уникальным. Всегда есть хотя бы один способ записать число в виде суммы чисел Фибоначчи, но их может быть намного больше.
Ваша задача - написать полную программу, которая с использованием stdin принимает положительное целое число от одного до миллиона включительно, а затем выводит с использованием stdout все возможные суммы сумм Фибоначчи, которые суммируют до входных данных. Суммируя, числа Фибоначчи не должны повторяться, и это включает число 1
. При любом суммировании, если 1
оно присутствует, оно должно присутствовать только один раз, поскольку в моем определении приведенная выше последовательность 1
встречается только один раз. Суммы с единственным термином действительны, поэтому, если входное число является самим числом Фибоначчи, то само число является действительным суммированием и должно быть напечатано. Если несколько сумм, то между любыми двумя суммами должна быть пустая строка, чтобы их можно было легко различить.
Вот несколько примеров.
./myfib 1
1
Существует только одна такая сумма, и у нее есть только термин, так что это все, что напечатано.
./myfib 2
2
Обратите внимание, что 1+1
это неверная сумма, потому что 1
повторяется.
./myfib 3
1+2
3
Две суммы, и они оба напечатаны с пустой строкой между ними.
./myfib 10
2+8
2+3+5
./myfib 100
3+8+89
1+2+8+89
3+8+34+55
1+2+3+5+89
1+2+8+34+55
3+8+13+21+55
1+2+3+5+34+55
1+2+8+13+21+55
1+2+3+5+13+21+55
Настоящий код-гольф. Самый короткий код на любом языке выигрывает. Пожалуйста, опубликуйте свой код с некоторыми тестовыми примерами (кроме того, который я дал выше). В случае галстуков, я выбираю ту, которая получила наибольшее количество голосов после ожидания, по крайней мере, в течение двух недель и, возможно, дольше. Поэтому сообщество, пожалуйста, не стесняйтесь высказать любые решения, которые вам нравятся. Хитрость / красота кода важнее, чем то, кто публикуется первым.
Удачного кодирования!
Ответы:
GolfScript, 54 символа
Протестируйте его онлайн или посмотрите на примеры:
источник
Ruby,
118114 (вывод массива) или138134 (корректный вывод)Образец прогона:
Измените
gets
на,$*[0]
если вы хотите аргументы командной строки (>fibadd 100
), хотя +1 символ.С правильным выводом:
Образцы прогонов:
Этот последний (12804) занял всего около 3 секунд!
источник
Mathematica,
8985 символовСокращено до 85 символов благодаря Дэвиду Каррахеру.
Mathematica имеет встроенную функцию
Fibonacci
, но я не хочу ее использовать.источник
i = Input[]; #~Row~"+" & /@ Select[If[# > i, Subsets@{##}, #0[# + #2, ##]] &[2, 1], Tr@# == i &]
i = Input[]; #~Row~"+" & /@ Select[If[# > i, Subsets@{##}, #0[# + #2, ##]] &[2, 1], Tr@# == i &] // Column
питон
206181 персонажаПробный прогон:
источник
while i<1000000:v+=[i];i,j=j,i+j
import itertools as z
удалите символы новой строки после двоеточий, вставьте ихy=input()
вx,y,v
строку и удалите лишний пробел после заключительногоif
утверждения.Скала, 171
источник
C #, 376 байт
Ungolfed:
Метод
B
возвращает значениеIEnumerable
, представляющее весь (бесконечный) набор Фибоначчи. Второй метод, учитывая числоn
, просматривает первыеn
числа Фибоначчи (здесь огромный перебор), находит все возможные подмножества (набор мощностей), а затем фильтрует до подмножеств, чья сумма точноn
, и затем печатает.источник
APL (75)
Менее конкурентоспособен, чем хотелось бы, в основном из-за формата вывода.
Вывод:
Объяснение:
I←⎕
: читать ввод, хранить вI
.⍳2
: начиная со списка1 2
,{⍵,+/¯2↑⍵}
: добавить сумму двух последних элементов в список,⍣{I<⊃⌽⍺}
: beforeI
меньше, чем последний элемент списка.F←
: сохранить вF
(это числа Фибоначчи от1
доI
).N←⍴F
: сохранить количество чисел Фибоначчи вN
.↓⍉(N⍴2)⊤⍳2*N
: получить числа от1
до2^N
, как биты.S←/∘F¨
: использовать каждый из них как битовую маскуF
, хранить вS
.I=+/¨S
: для каждого подсписка вS
, посмотрите, равна ли его суммаI
.S/⍨
: выберите их изS
. (Теперь у нас есть все списки чисел Фибоначчи, которые суммируются сI
.){
...}¨
: для каждого из них:,'+',⍪⍵
: добавьте+
перед каждым номером,1↓
: убери первый+
,⎕TC[2]
: добавить дополнительный перевод строки,⎕←
и вывод.источник
Haskell - 127
После многих итераций я получил следующий код:
Я мог бы сохранить, может быть, один символ, обманув и добавив дополнительный «0+» перед каждой выходной строкой.
Я хочу поделиться другой версией (длина 143), которую я придумал, пытаясь сыграть в гольф предыдущее решение. Я никогда раньше не злоупотреблял операторами и кортежами так сильно:
Тестовые случаи, 256:
и 1000:
Некоторые данные об эффективности, так как кто-то имел этот материал:
источник
05AB1E , 19 байт (не конкурирует)
Попробуйте онлайн!
Рассчитывает все возможные суммы для любой данной
n
. Пример вывода на 1000:источник