# Вычисление рекурсией (медленное) Решение по формуле, используя рекурсию: ```js run function fib(n) { return n <= 1 ? n : fib(n - 1) + fib(n - 2); } alert( fib(3) ); // 2 alert( fib(7) ); // 13 // fib(77); // не запускаем, подвесит браузер ``` При больших значениях `n` оно будет работать очень медленно. Например, `fib(77)` уже будет вычисляться очень долго. Это потому, что функция порождает обширное дерево вложенных вызовов. При этом ряд значений вычисляется много раз. Например, посмотрим на отрывок вычислений: ```js no-beautify ... fib(5) = fib(4) + fib(3) fib(4) = fib(3) + fib(2) ... ``` Здесь видно, что значение `fib(3)` нужно одновременно и для `fib(5)` и для `fib(4)`. В коде оно будет вычислено два раза, совершенно независимо. Можно это оптимизировать, запоминая уже вычисленные значения, получится гораздо быстрее. Альтернативный вариант -- вообще отказаться от рекурсии, а вместо этого в цикле начать с первых значений `1`, `2`, затем из них получить `fib(3)`, далее `fib(4)`, затем `fib(5)` и так далее, до нужного значения. Это решение будет наиболее эффективным. Попробуйте его написать. # Алгоритм вычисления в цикле Будем идти по формуле слева-направо: ```js no-beautify var a = 1, b = 1; // начальные значения var c = a + b; // 2 /* переменные на начальном шаге: a b c 1, 1, 2 */ ``` Теперь следующий шаг, присвоим `a` и `b` текущие 2 числа и получим новое следующее в `c`: ```js no-beautify a = b, b = c; c = a + b; /* стало так (ещё число): a b c 1, 1, 2, 3 */ ``` Следующий шаг даст нам ещё одно число последовательности: ```js no-beautify a = b, b = c; c = a + b; /* стало так (ещё число): a b c 1, 1, 2, 3, 5 */ ``` Повторять в цикле до тех пор, пока не получим нужное значение. Это гораздо быстрее, чем рекурсия, хотя бы потому что ни одно из чисел не вычисляется дважды. P.S. Этот подход к вычислению называется [динамическое программирование снизу-вверх](http://ru.wikipedia.org/wiki/%D0%94%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5). # Код для вычисления в цикле ```js run function fib(n) { var a = 1, b = 1; for (var i = 3; i <= n; i++) { var c = a + b; a = b; b = c; } return b; } alert( fib(3) ); // 2 alert( fib(7) ); // 13 alert( fib(77) ); // 5527939700884757 ``` Цикл здесь начинается с `i=3`, так как первое и второе числа Фибоначчи заранее записаны в переменные `a=1`, `b=1`.