Елементи послідовності перших n Фібоначчі


11

Існує добре відомий питання тут , що просить короткі (найменш символів) генератор послідовності Фібоначчі.

Мені хотілося б знати, чи може хтось генерувати лише перші N елементів, послідовності поля, за дуже короткий простір. Я намагаюся зробити це в python, але мене цікавить будь-яка коротка відповідь, будь-якою мовою. Функція F (N) генерує перші N елементів послідовності, або повертає їх як повернення функції, або друкує їх.

Цікаво, що здається, що відповіді на код-гольф починаються з 1 1 2, а не з 0 1 1 2. Це конвенція щодо коду-гольфу чи взагалі програмування? (У Вікіпедії сказано, що послідовність поля починається з нуля.)

Зразок пітона (перші 5 елементів):

def f(i,j,n):
    if n>0:
        print i;
        f(j,i+j,n-1)
f(1,1,5)

1
Я думаю, що це занадто схоже на пов'язане питання. Більшість рішень там може бути легко модифіковано для обробки першого випадку.
Хаммар

3
Скрізь, де я бачив, основні випадки визначаються як F_0 = 0, F_1 = 1або еквівалентно F_1 = 1, F_2 = 1. Різниця полягає в тому, чи потрібно ви запускати послідовність з індексу 0 (більш поширеного в програмуванні) або 1 (більш поширеного в математиці).
хаммар

1
А визначення F_0 = 0, F_1 = 1має певну користь у простоті матричного подання [[1 1][1 0]]^n = [[F_{n+1} F_n][F_n F_{n-1}]].
Пітер Тейлор

1
@ Peeter: Тепер, коли є вагомий привід віддати перевагу одному перед іншим (я давно вважав за краще 0, 1 з естетичної точки зору, але не вважаю, що вони наполягають на собі).
dmckee --- кошеня колишнього модератора

1
Я усвідомлюю, що це досить старий виклик на даний момент, але зауважте, що ви прийняли відповідь, яка не найкоротша. Оскільки це змагання з кодового гольфу, найкоротша відповідь повинна бути тією, що позначена як прийнята.
Олексій А.

Відповіді:


39

С

Не турбував підрахунок, але ось цікавий приклад:

f(n){return n<4?1:f(--n)+f(--n);}
main(a,b){for(scanf("%d",&b);a++<=b;printf("%d ",f(a)));}

Доказ це працює.


Я дуже пишаюся цим: мені стало нудно, тому я переставив свій код (з кількома невеликими доповненнями), щоб зробити його там, де кожен рядок представляє значення у послідовності Фібоначчі.

                         #                                // 1
                         f                                // 1
                         //                               // 2
                        (n)                               // 3
                       {/**/                              // 5
                      return n                            // 8
                    <2 ? 1:f(--n)                         // 13
                +f(--n); } main(a, b)                     // 21
          {a = 0, b = 0;scanf("%d",&b); for(              // 34
;a < b; a+=1) { int res = f(a); printf("%d ", res); } }   // 55

Доказ це працює.


Приємно. 90 символів (без нового рядка). Збережіть 2 байти: a++<=b-> a++-bі return--n<3?1:f(n)+f(n-1). Крім того, ви можете уникнути, scanfякщо вам потрібно буде n argc.
угорен

Любіть це! Це чудовий приклад, коли невизначена поведінка впорядкування двох екземплярів одного і --nтого ж виразу не має значення. Блискуче!
Тодд Леман

До речі, я вважаю, що ваш 4насправді має бути 3. Як написано на даний момент <4, створена послідовність становить 1, 1, 1, 2, 3, 5, 8 ... Це занадто багато 1-х.
Тодд Леман

Крім того, якщо ви хочете правильно обробити нульовий елемент послідовності, ви можете додати 2 символи та змінити код наreturn n<3?n>0:f(--n)+f(--n);
Todd Lehman

6

Хаскелл (26)

Дивно, але це лише один символ довше рішення J.

f = (`взяти)
s = 0: scanl (+) 1s

Я голю кілька персонажів:

  1. Використання takeяк двійкового оператора;
  2. Використання scanlзамість багатослівного zipWith.

Буквально мені знадобилося близько півгодини, щоб зрозуміти, що тут відбувається, і sце так елегантно, я не знаю, як хтось подумає про таке рішення! Те, що я не знав, - це те, що ви можете sзнову використовувати , визначаючи s. (Я все ще початківець =)
недолік

5

Ось однолінійний Python. Він використовує плаваючу крапку, тому можуть бути такі, nдля яких це вже не точно.

F=lambda n:' '.join('%d'%(((1+5**.5)/2)**i/5**.5+.5)for i in range(n))

F(n)повертає рядок, що містить перші nчисла Фібоначчі, розділені пробілами.


Я думав зробити це, але думав, що це буде занадто довго. Я не думав про використання підлоги. Дуже хороший.
Кріс Харпер

А, формула Біне. Я також використав це, і це точно, принаймні до 59-го числа, якщо ви рахуєте 0 першим. Після цього числа стають занадто великими, і він починає використовувати показники.
elssar

70 символів, 1 рядок, для визначення функції. + 4 + crlf для виклику. Досить добре!
Warren P

5

GolfScript, 16 символів

~0 1@{.2$+}*;;]`

Приклад виводу:

$ ruby golfscript.rb ~/Code/golf/fib.gs <<< "12"
[0 1 1 2 3 5 8 13 21 34 55 89]


4

Scala 71:

def f(c:Int,a:Int=0,b:Int=1):Unit={println(a);if(c>0)f(c-1,b,a+b)};f(9)

відбитки

0
1
1
2
3
5
8
13
21
34

Класно. Я ще навіть не грав зі Скалою. Я спробую сьогодні сьогодні вдома.
Warren P

3

Perl, 29 28 байт

perl -E'say$b+=$;=$b-$;for-pop..--$;' 8
1
1
2
3
5
8
13
21

Пояснення

Це засновано на класичному $b += $a = $b-$aповторенні, яке працює наступним чином:

  • На початку кожен цикл $aмістить F(n-2)і $bміститьF(n)
  • Після $a = $b-$a $aміститьF(n-1)
  • Після $b += $a $bміститьF(n+1)

Проблема тут - ініціалізація. Класичний шлях є, $b += $a = $b-$a || 1але тоді йде послідовність1 2 3 5 ...

Розширивши послідовність поля ліворуч:

... 5 -3 2 -1 1 0 1 1 2 3 5 ...

ви бачите, що правильною відправною точкою є $a = -1і $b = 0. Ініціалізація $ a може поєднуватися з налаштуванням циклу

Нарешті замініть $aна, $;щоб позбутися місця передfor


2

Я можу надати вам дворядове рішення Python. Це поверне їх як список.

f = lambda n: 1 if n < 2 else f(n-1) + f(n-2)
g = lambda m: map(f, range(0,m))

print g(5)

Ви можете роздрукувати їх, додавши ще одну карту, щоб зробити їх рядками, а потім додати з'єднання, але це мені здається непотрібним.

На жаль, я не знаю, як ввести рекурсивну лямбду map, тому я застряг у двох рядках.


Для чого це повернення g(100)? ;)
Містер Лама

@GigaWatt Хе, ОП ніколи не говорив, що це повинно бути розумним. Чи асимптотичний час ходу чимось на зразок O (n (1,62) ^ n)?
Кріс Харпер

Ось один із способів (ви) можете це зробити. Зауважте, що f(n)з n<=0цілими числами, що повертаються, і n>0списками повернень, так що ... можливо, це не ідеально:f = lambda n: map(f, (-x for x in range(0, n))) if n > 0 else -n if n > -2 else f(n+1) + f(n+2)
Dillon Cower

До речі, ви пропустили перше 0у своїй відповіді. Зміна fповернення n if n < 2- один спосіб вирішення. :)
Dillon Cower

@DC Мені подобається ваше рішення. Досить креативний. Так, я почав свій початок з 1, 1, тому що я завжди це вчив. Я зрозумів, що змінити це досить просто.
Кріс Харпер

2

Пітон (78 символів)

Я використовував формулу Binet, щоб обчислити номери напруженості -

[(1 + sqrt (5)) ^ n- (1-sqrt (5) ^ n] / [(2 ^ n) sqrt (5)]

Тут не так вже й мало відповідей, але хлопчик, це швидко

n=input()
i=1
x=5**0.5
while i<=n:
    print ((1+x)**i-(1-x)**i)/((2**i)*x)
    i+=1

1
Пітон (12 годин): print"11235":)
Джоел Корнетт

Ви можете поголити 2 символи, позбувшись круглих дужок 2**i. **мають вищий пріоритет, ніж*
Джоел Корнетт

Другий термін у формулі бінет починається невеликим і лише стає меншим. Ви можете залишити його повністю і просто округлити результат першого терміна на найближче ціле число замість цього (або додати 0,5 і округлити вниз)
Тон Євангелія

2

Схема

Це оптимізовано за допомогою хвостової рекурсії:

(define (fib n)
  (let fib ([n n] [a 0] [b 1])
    (if (zero? n) (list a)
        (cons a (fib (- n 1) b (+ a b))))))


2

J, 25 символів

Я усвідомлюю, що рішення J - це, мабуть, не те, про що ви хочете, але ось все одно. :-)

0 1(],+/&(_2&{.))@[&0~2-~

Використання:

    0 1(],+/&(_2&{.))@[&0~2-~ 6
0 1 1 2 3 5
    0 1(],+/&(_2&{.))@[&0~2-~ 10
0 1 1 2 3 5 8 13 21 34

Як це працює:

Починаючи справа (тому що програми J читаються справа наліво),

2-~ 6~Оператор змінює аргумент дієслова , так це те ж саме,6-2

На даний момент ігноруючи розділ у дужках, 0 1(...)@[&0~ xприймає в дужках дієслово і виконує його xразів, використовуючи список 0 1як свій вхід - ~знову повертає аргументи тут, даючи x (...)@[&0 ] 0 1, тобто я можу зберегти введення в кінці функції.

Всередині дужок - виделка, ],+/&(_2&{.)яка складається з трьох дієслів - ], ,і +/&(_2&{.).

Вилка бере три дієслова a b cі використовує їх так: (x a y) b (x c y)де xі yє аргументами вилки. Це ,центральне дієслово у цій вилці та приєднується до результатів x ] yта x +/&(_2&{.) yразом.

]повертає лівий аргумент без змін, так що x ] yоцінюється на x.

+/&(_2&{.)бере два останні елементи з даного списку (_2&{.)- в даному випадку 0 1- і потім додає їх разом +/(вони &просто виконують роль клею).

Після того, як дієслово оперує, як тільки результат повертається для наступного запуску, генеруючи послідовність.


2

TI-Basic, 43 символи

:1→Y:0→X
:For(N,1,N
:Disp X
:Y→Z
:X+Y→Y
:Z→X
:End

Цей код можна безпосередньо вставити в основну програму або зробити в окрему програму, на яку посилається перша.


Це перше рішення TI-BASIC, яке я коли-небудь бачив тут, яке не було мною :) +1
Timtech

Також зауважте для інших людей, що нові рядки тут не враховуються, оскільки їх можна видалити.
Тімтех

Щойно я отримав калькулятор клавіатури великого гіганта-qwerty TI-92. Дякую за це.
Warren P

2

APL (33)

{⍎'⎕','←0,1',⍨'←A,+/¯2↑A'⍴⍨9×⍵-2}

Використання:

   {⍎'⎕','←0,1',⍨'←A,+/¯2↑A'⍴⍨9×⍵-2}7
0 1 1 2 3 5 8

Чи символ поля - частина APL чи відсутній гліф?
Warren P

@WarrenP: Якщо ви маєте на увазі четвертого символу зліва, це називається "квадроциклом", і він повинен виглядати так. Повинно бути лише один ящик.
marinus


1

Powershell - 35 символів

Powershell приймає трубопровідний вхід , так що я в переконанні , що n |в n | <mycode>не повинно бути проти мого рахунку, але замість цього лише частина ініціювання «функції» на мові.

Перше рішення передбачає, що ми починаємо з 0:

%{for($2=1;$_--){($2=($1+=$2)-$2)}}

Друге рішення передбачає, що ми можемо почати з 1:

%{for($2=1;$_--){($1=($2+=$1)-$1)}}

Приклад виклику: 5 | %{for($2=1;$_--){($1=($2+=$1)-$1)}}

Врожайність:

1
1
2
3
5

Цікаво відзначити , що спроби уникнути накладних витрат на for()петлі в результаті однієї і тієї ж кількість символів: %{$2=1;iex('($1=($2+=$1)-$1);'*$_)}.


1

Пітон, 43 ч

Ось три принципово різні одноклайєри, які не використовують формулу Біне.

f=lambda n:reduce(lambda(r,a,b),c:(r+[b],a+b,a),'.'*n,([],1,0))[0]
f=lambda n:map(lambda x:x.append(x[-1]+x[-2])or x,[[0,1]]*n)[0]
def f(n):a=0;b=1;exec'print a;a,b=b,a+b;'*n

Я ніколи reduceтак жорстоко не зловживав .


1
+1 за reduceзловживання
Warren P

1

DC, 32 символи:

Це насправді завжди показуватиме два перші 1, тому функція працює лише так, як очікувалося для N> = 2 .

?2-sn1df[dsa+plarln1-dsn0<q]dsqx

C, 75 символів:

Не так круто, як прийнята відповідь, але коротша і швидше:

main(n,t,j,i){j=0,i=scanf("%d",&n);while(n--)t=i,i=j,printf("%d\n",j+=t);}
Додатково:

CL, 64 символи:

Один з моїх найбільш використовуваних закладок цього семестру має цікавий приклад, який коротший, ніж у багатьох інших з них, і це просто пряме виклик loopмакросу - в основному, лише одне твердження! Зняв його для всього пробілу, який я міг:

(loop repeat n for x = 0 then y and y = 1 then(+ x y)collect y)

Досить короткий, приємний і читабельний! Для читання введення n (включаючи навколишні пробіли) можна замінити (read), додавши 3 символи.


Чи mainприймає ... чи чотири аргументи?
кіт

1
Це займає стільки, скільки ви даєте. У цьому випадку це просто (ab) використовується для визначення декількох змінних, які будуть використані пізніше :)
daniero

1

ФАЙЗ, 28 байт

0 1- 1 10[$][@@$@+$." "@1-]#

Ви можете генерувати -1, використовуючи, 1_а не0 1 -
12Me21

1

Пітон 2, 38 байт

Удосконалення щодо раніше розміщеного рішення:

a=b=1
exec'print a;a,b=b,a+b;'*input()

Для цього використовується execі множення рядків, щоб уникнути циклів.

Пітон 3, 46 байт

Не так ефективно в Python 3:

a=b=1
exec('print(a);a,b=b,a+b;'*int(input()))

Перейшовши на Python 2, ви можете зберегти 9 байт: Спробуйте це в Інтернеті! Можливо, ви можете додати версію Python 2 до своєї відповіді.
Стівен

@Stephen Добрий момент! Оновлено.
Рассел Шварц

0

C99, 58 символів

Наступна функція заповнює масив цілих чисел з першими nзначеннями з послідовності Фібоначчі, починаючи з 0.

void f(int*a,int n){for(int p=0,q=1;n--;q+=*a++)*a=p,p=q;}

Тестовий джгут, взявши nза аргумент командного рядка:

#include <stdlib.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
     int n = (argc > 1) ? atoi(argv[1]) : 1;
     int a[n];
     f(a, n);
     for (int i = 0; i < n; ++i)
          printf("%d\n", a[i]);
}


0

PHP, 87

function f($n,$a=array(0,1)){echo' '.$a[0];$n>0?f(--$n,array($a[1],array_sum($a))):'';}

Використання array_sumта рекурсивна функція для генерування серій.

Наприклад:

 $ php5 fibo.php 9
 0 1 1 2 3 5 8 13 21 34 


0

Скала, 65 символів

(Seq(1,0)/:(3 to 9)){(s,_)=>s.take(2).sum+:s}.sorted map println

Це друкує, наприклад, перші 9 чисел Фібоначчі. Для більш корисної версії, яка бере довжину послідовності від введення консолі, потрібно 70 символів:

(Seq(1,0)/:(3 to readInt)){(s,_)=>s.take(2).sum+:s}.sorted map println

Обережно використання діапазону обмежує це значеннями Int.



0

Луа, 85 байт

Я вивчаю Lua, тому хотів би додати цю мову до пулу.

function f(x)
    return (x<3) and 1 or f(x-1)+f(x-2)
end
for i=1,io.read() do
    print(f(i))
end

і все це займало 85 символів, параметр як аргумент командного рядка. Ще один хороший момент - це легко читати.


0

ФАЙЛ, 20 символів

^1@[1-$][@2ø+$.\9,]#

Введення має бути в стеці перед запуском цього.


0

Pyt , 3 байти

ř⁻Ḟ

Спробуйте в Інтернеті!

ř створює масив [1, 2, 3, ..., x]
⁻ Декрементує кожен елемент один раз (як Ḟ 0 індексується)
Ḟ для кожного елемента в х перетворює його у його еквівалентний рівень


0

машинний код x86 - 379 байт

Версія з заголовками ELF набрала 484 байти:

00000000: 7f45 4c46 0101 0100 0000 0000 0000 0000  .ELF............
00000010: 0200 0300 0100 0000 c080 0408 3400 0000  ............4...
00000020: 0000 0000 0000 0000 3400 2000 0200 2800  ........4. ...(.
00000030: 0000 0000 0100 0000 0000 0000 0080 0408  ................
00000040: 0000 0000 e401 0000 0010 0000 0500 0000  ................
00000050: 0010 0000 0100 0000 0000 0000 0090 0408  ................
00000060: 0000 0000 0000 0000 0000 1000 0600 0000  ................
00000070: 0010 0000 0000 0000 0000 0000 0000 0000  ................
00000080: 51b9 0090 0408 8801 31c0 ba01 0000 00eb  Q.......1.......
00000090: 0351 89c1 31c0 89c3 43b0 04cd 8031 c099  .Q..1...C....1..
000000a0: 4259 c300 0000 0000 0000 0000 0000 0000  BY..............
000000b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000c0: 31c0 9942 b903 9004 08c6 4101 0ac6 4102  1..B......A...A.
000000d0: 01c6 4103 013a 7103 0f84 ff00 0000 3a71  ..A..:q.......:q
000000e0: 0374 2680 4103 050f b641 036b c008 0041  .t&.A....A.k...A
000000f0: 048a 4104 e887 ffff ff80 6904 30c6 4103  ..A.......i.0.A.
00000100: 0183 e903 3a71 0375 da8a 4104 e86f ffff  ....:q.u..A..o..
00000110: ff3a 7106 0f84 ba00 0000 0fb6 4105 8841  .:q.........A..A
00000120: 060f b641 0788 4105 0fb6 4107 0041 06c6  ...A..A...A..A..
00000130: 4107 003a 7106 0f84 8800 0000 c641 0701  A..:q........A..
00000140: fe49 063a 7106 0f84 7800 0000 c641 0702  .I.:q...x....A..
00000150: fe49 063a 7106 0f84 6800 0000 c641 0703  .I.:q...h....A..
00000160: fe49 063a 7106 0f84 5800 0000 c641 0704  .I.:q...X....A..
00000170: fe49 063a 7106 744c c641 0705 fe49 063a  .I.:q.tL.A...I.:
00000180: 7106 7440 c641 0706 fe49 063a 7106 7434  q.t@.A...I.:q.t4
00000190: c641 0707 fe49 063a 7106 7428 c641 0708  .A...I.:q.t(.A..
000001a0: fe49 063a 7106 741c c641 0709 fe49 063a  .I.:q.t..A...I.:
000001b0: 7106 7410 fe41 08fe 4109 fe49 060f b641  q.t..A..A..I...A
000001c0: 0688 4107 c641 0601 83c1 033a 7106 0f85  ..A..A.....:q...
000001d0: 46ff ffff 3a71 030f 8501 ffff ffb3 0031  F...:q.........1
000001e0: c040 cd80                                .@..

Версія без заголовка (саме цю, яку слід оцінювати):

00000000: 67c6 4101 0a67 c641 0201 67c6 4103 0167  g.A..g.A..g.A..g
00000010: 3a71 030f 842a 0167 3a71 0374 2e67 8041  :q...*.g:q.t.g.A
00000020: 0305 6667 0fb6 4103 666b c008 6700 4104  ..fg..A.fk..g.A.
00000030: 678a 4104 e80d 0167 8069 0430 67c6 4103  g.A....g.i.0g.A.
00000040: 0166 83e9 0367 3a71 0375 d267 8a41 04e8  .f...g:q.u.g.A..
00000050: f200 673a 7106 0f84 df00 6667 0fb6 4105  ..g:q.....fg..A.
00000060: 6788 4106 6667 0fb6 4107 6788 4105 6667  g.A.fg..A.g.A.fg
00000070: 0fb6 4107 6700 4106 67c6 4107 0067 3a71  ..A.g.A.g.A..g:q
00000080: 060f 84a3 0067 c641 0701 67fe 4906 673a  .....g.A..g.I.g:
00000090: 7106 0f84 9200 67c6 4107 0267 fe49 0667  q.....g.A..g.I.g
000000a0: 3a71 060f 8481 0067 c641 0703 67fe 4906  :q.....g.A..g.I.
000000b0: 673a 7106 0f84 7000 67c6 4107 0467 fe49  g:q...p.g.A..g.I
000000c0: 0667 3a71 0674 6167 c641 0705 67fe 4906  .g:q.tag.A..g.I.
000000d0: 673a 7106 7452 67c6 4107 0667 fe49 0667  g:q.tRg.A..g.I.g
000000e0: 3a71 0674 4367 c641 0707 67fe 4906 673a  :q.tCg.A..g.I.g:
000000f0: 7106 7434 67c6 4107 0867 fe49 0667 3a71  q.t4g.A..g.I.g:q
00000100: 0674 2567 c641 0709 67fe 4906 673a 7106  .t%g.A..g.I.g:q.
00000110: 7416 67fe 4108 67fe 4109 67fe 4906 6667  t.g.A.g.A.g.I.fg
00000120: 0fb6 4106 6788 4107 67c6 4106 0166 83c1  ..A.g.A.g.A..f..
00000130: 0367 3a71 060f 8521 ff67 3a71 030f 85d6  .g:q...!.g:q....
00000140: fe00 0000 6651 66b9 7801 0000 6788 0166  ....fQf.x...g..f
00000150: 31c0 66ba 0100 0000 eb05 6651 6689 c166  1.f.......fQf..f
00000160: 31c0 6689 c366 43b0 04cd 8066 31c0 6699  1.f..fC....f1.f.
00000170: 6642 6659 c300 0000 0000 00              fBfY.......

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.