mirror of
https://github.moeyy.xyz/https://github.com/trekhleb/javascript-algorithms.git
synced 2024-12-25 22:46:20 +08:00
Add fibonacci Binet's formula.
This commit is contained in:
parent
a23400380d
commit
51d67e7eac
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
});
|
||||
});
|
@ -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);
|
||||
});
|
||||
});
|
||||
|
@ -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);
|
||||
});
|
||||
});
|
@ -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);
|
||||
}
|
23
src/algorithms/math/fibonacci/fibonacciNthClosedForm.js
Normal file
23
src/algorithms/math/fibonacci/fibonacciNthClosedForm.js
Normal 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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user