Add fibonacci Binet's formula.

This commit is contained in:
Oleksii Trekhleb 2018-09-15 09:17:19 +03:00
parent a23400380d
commit 51d67e7eac
7 changed files with 58 additions and 36 deletions

View File

@ -61,7 +61,7 @@ a set of rules that precisely define a sequence of operations.
* **Math**
* `B` [Bit Manipulation](src/algorithms/math/bits) - set/get/update/clear bits, multiplication/division by two, make negative etc.
* `B` [Factorial](src/algorithms/math/factorial)
* `B` [Fibonacci Number](src/algorithms/math/fibonacci)
* `B` [Fibonacci Number](src/algorithms/math/fibonacci) - classic and closed-form versions.
* `B` [Primality Test](src/algorithms/math/primality-test) (trial division method)
* `B` [Euclidean Algorithm](src/algorithms/math/euclidean-algorithm) - calculate the Greatest Common Divisor (GCD)
* `B` [Least Common Multiple](src/algorithms/math/least-common-multiple) (LCM)

View File

@ -17,4 +17,4 @@ The Fibonacci spiral: an approximation of the golden spiral created by drawing c
## References
[Wikipedia](https://en.wikipedia.org/wiki/Fibonacci_number)
- [Wikipedia](https://en.wikipedia.org/wiki/Fibonacci_number)

View File

@ -1,23 +0,0 @@
import fibonacciClosedForm from '../fibonacciClosedForm';
describe('fibonacciClosedForm', () => {
it('should calculate fibonacci correctly', () => {
expect(fibonacciClosedForm(1)).toBe(1);
expect(fibonacciClosedForm(2)).toBe(1);
expect(fibonacciClosedForm(3)).toBe(2);
expect(fibonacciClosedForm(4)).toBe(3);
expect(fibonacciClosedForm(5)).toBe(5);
expect(fibonacciClosedForm(6)).toBe(8);
expect(fibonacciClosedForm(7)).toBe(13);
expect(fibonacciClosedForm(8)).toBe(21);
expect(fibonacciClosedForm(20)).toBe(6765);
expect(fibonacciClosedForm(30)).toBe(832040);
expect(fibonacciClosedForm(50)).toBe(12586269025);
expect(fibonacciClosedForm(70)).toBe(190392490709135);
expect(fibonacciClosedForm(71)).toBe(308061521170129);
expect(fibonacciClosedForm(72)).toBe(498454011879264);
expect(fibonacciClosedForm(73)).toBe(806515533049393);
expect(fibonacciClosedForm(74)).toBe(1304969544928657);
expect(fibonacciClosedForm(75)).toBe(2111485077978050);
});
});

View File

@ -19,5 +19,7 @@ describe('fibonacciNth', () => {
expect(fibonacciNth(73)).toBe(806515533049393);
expect(fibonacciNth(74)).toBe(1304969544928657);
expect(fibonacciNth(75)).toBe(2111485077978050);
expect(fibonacciNth(80)).toBe(23416728348467685);
expect(fibonacciNth(90)).toBe(2880067194370816120);
});
});

View File

@ -0,0 +1,31 @@
import fibonacciNthClosedForm from '../fibonacciNthClosedForm';
describe('fibonacciClosedForm', () => {
it('should throw an error when trying to calculate fibonacci for not allowed positions', () => {
const calculateFibonacciForNotAllowedPosition = () => {
fibonacciNthClosedForm(76);
};
expect(calculateFibonacciForNotAllowedPosition).toThrow();
});
it('should calculate fibonacci correctly', () => {
expect(fibonacciNthClosedForm(1)).toBe(1);
expect(fibonacciNthClosedForm(2)).toBe(1);
expect(fibonacciNthClosedForm(3)).toBe(2);
expect(fibonacciNthClosedForm(4)).toBe(3);
expect(fibonacciNthClosedForm(5)).toBe(5);
expect(fibonacciNthClosedForm(6)).toBe(8);
expect(fibonacciNthClosedForm(7)).toBe(13);
expect(fibonacciNthClosedForm(8)).toBe(21);
expect(fibonacciNthClosedForm(20)).toBe(6765);
expect(fibonacciNthClosedForm(30)).toBe(832040);
expect(fibonacciNthClosedForm(50)).toBe(12586269025);
expect(fibonacciNthClosedForm(70)).toBe(190392490709135);
expect(fibonacciNthClosedForm(71)).toBe(308061521170129);
expect(fibonacciNthClosedForm(72)).toBe(498454011879264);
expect(fibonacciNthClosedForm(73)).toBe(806515533049393);
expect(fibonacciNthClosedForm(74)).toBe(1304969544928657);
expect(fibonacciNthClosedForm(75)).toBe(2111485077978050);
});
});

View File

@ -1,11 +0,0 @@
/**
* Calculate fibonacci number at specific position using closed form function.
*
* @param n n-th number of fibonacci sequence (must be number from 1(inclusive) to 75(inclusive))
* @return {number}
*/
export default function fibonacciClosedForm(n) {
const sqrt5 = Math.sqrt(5);
const phi = (1 + sqrt5) / 2;
return Math.floor((phi ** n) / sqrt5 + 0.5);
}

View File

@ -0,0 +1,23 @@
/**
* Calculate fibonacci number at specific position using closed form function (Binet's formula).
* @see: https://en.wikipedia.org/wiki/Fibonacci_number#Closed-form_expression
*
* @param {number} position - Position number of fibonacci sequence (must be number from 1 to 75).
* @return {number}
*/
export default function fibonacciClosedForm(position) {
const topMaxValidPosition = 75;
// Check that position is valid.
if (position < 1 || position > topMaxValidPosition) {
throw new Error(`Can't handle position smaller than 1 or greater than ${topMaxValidPosition}`);
}
// Calculate √5 to re-use it in further formulas.
const sqrt5 = Math.sqrt(5);
// Calculate φ constant (≈ 1.61803).
const phi = (1 + sqrt5) / 2;
// Calculate fibonacci number using Binet's formula.
return Math.floor((phi ** position) / sqrt5 + 0.5);
}