diff --git a/Maths/JacobsthalNumber.js b/Maths/JacobsthalNumber.js new file mode 100644 index 0000000000..580fd2cecd --- /dev/null +++ b/Maths/JacobsthalNumber.js @@ -0,0 +1,27 @@ +/** + * @function jacobsthalNumber + * @description Jacobsthal numbers are a sequence where each number is + * the sum of the previous number and twice the number before that. + * Sequence: 0, 1, 1, 3, 5, 11, 21, 43, 85, 171... + * @param {number} n - The position in the Jacobsthal sequence (0-indexed) + * @returns {number} - The nth Jacobsthal number + * @see https://en.wikipedia.org/wiki/Jacobsthal_number + * @example jacobsthalNumber(0) => 0 + * @example jacobsthalNumber(4) => 5 + * @example jacobsthalNumber(6) => 21 + */ +const jacobsthalNumber = (n) => { + if (!Number.isInteger(n) || n < 0) { + throw new TypeError('Input must be a non-negative integer') + } + if (n === 0) return 0 + if (n === 1) return 1 + let a = 0 + let b = 1 + for (let i = 2; i <= n; i++) { + ;[a, b] = [b, b + 2 * a] + } + return b +} + +export { jacobsthalNumber } diff --git a/Maths/test/JacobsthalNumber.test.js b/Maths/test/JacobsthalNumber.test.js new file mode 100644 index 0000000000..a637c10db4 --- /dev/null +++ b/Maths/test/JacobsthalNumber.test.js @@ -0,0 +1,47 @@ +import { jacobsthalNumber } from '../JacobsthalNumber.js' + +describe('jacobsthalNumber', () => { + test('jacobsthalNumber(0) returns 0', () => { + expect(jacobsthalNumber(0)).toBe(0) + }) + + test('jacobsthalNumber(1) returns 1', () => { + expect(jacobsthalNumber(1)).toBe(1) + }) + + test('jacobsthalNumber(2) returns 1', () => { + expect(jacobsthalNumber(2)).toBe(1) + }) + + test('jacobsthalNumber(3) returns 3', () => { + expect(jacobsthalNumber(3)).toBe(3) + }) + + test('jacobsthalNumber(4) returns 5', () => { + expect(jacobsthalNumber(4)).toBe(5) + }) + + test('jacobsthalNumber(5) returns 11', () => { + expect(jacobsthalNumber(5)).toBe(11) + }) + + test('jacobsthalNumber(6) returns 21', () => { + expect(jacobsthalNumber(6)).toBe(21) + }) + + test('jacobsthalNumber(7) returns 43', () => { + expect(jacobsthalNumber(7)).toBe(43) + }) + + test('jacobsthalNumber(8) returns 85', () => { + expect(jacobsthalNumber(8)).toBe(85) + }) + + test('throws TypeError for negative input', () => { + expect(() => jacobsthalNumber(-1)).toThrow(TypeError) + }) + + test('throws TypeError for float input', () => { + expect(() => jacobsthalNumber(1.5)).toThrow(TypeError) + }) +})