From 40fd020b397ff5b928ae00c1252142e38cae2752 Mon Sep 17 00:00:00 2001 From: Joe Carpenito Date: Tue, 4 Feb 2025 15:40:39 -0500 Subject: [PATCH 1/8] init memoization example --- README.md | 2 ++ src/main.ts | 2 ++ src/memoization/README.md | 0 src/memoization/index.spec.ts | 0 src/memoization/index.ts | 0 5 files changed, 4 insertions(+) create mode 100644 src/memoization/README.md create mode 100644 src/memoization/index.spec.ts create mode 100644 src/memoization/index.ts diff --git a/README.md b/README.md index e492fd4..1a30889 100644 --- a/README.md +++ b/README.md @@ -16,3 +16,5 @@ Notably, this is an academic exercise. Many of these data structures are redunda - [Hash Table](./src/hash-table) - [Binary Search Tree](./src/binary-tree) - [Binary Heap](./src/binary-heap) (example MIN implementation) +- [AVL Tree](./src/avl-tree) +- [Memoization](./src/memoization/) diff --git a/src/main.ts b/src/main.ts index 5dcd581..74193c6 100644 --- a/src/main.ts +++ b/src/main.ts @@ -4,3 +4,5 @@ export * from './stack' export * from './hash-table' export * from './binary-tree' export * from './binary-heap' +export * from './avl-tree' +export * from './memoization' diff --git a/src/memoization/README.md b/src/memoization/README.md new file mode 100644 index 0000000..e69de29 diff --git a/src/memoization/index.spec.ts b/src/memoization/index.spec.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/memoization/index.ts b/src/memoization/index.ts new file mode 100644 index 0000000..e69de29 From 0ee6fced9f26ed4b46eb2fa5a31e04d8c5cce397 Mon Sep 17 00:00:00 2001 From: Joe Carpenito Date: Tue, 4 Feb 2025 15:57:07 -0500 Subject: [PATCH 2/8] initalize spec definition --- src/memoization/index.spec.ts | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/memoization/index.spec.ts b/src/memoization/index.spec.ts index e69de29..ec42415 100644 --- a/src/memoization/index.spec.ts +++ b/src/memoization/index.spec.ts @@ -0,0 +1,35 @@ +import { describe, it, expect } from 'bun:test' + +describe('Fibonacci Value Retrieval', () => { + it('should return 0 for the first index (0) in the Fibonacci sequence', () => { + expect(fibonacci(0)).toBe(0) + }) + + it('should return 1 for the second index (1) in the Fibonacci sequence', () => { + expect(fibonacci(1)).toBe(1) + }) + + it('should return 1 for the third index (2) in the Fibonacci sequence, as it is the sum of the two preceding numbers (0 and 1)', () => { + expect(fibonacci(2)).toBe(1) + }) + + it('should return 2 for the fourth index (3) in the Fibonacci sequence, as it is the sum of the two preceding numbers (1 and 1)', () => { + expect(fibonacci(3)).toBe(2) + }) + + it('should return 3 for the fifth index (4) in the Fibonacci sequence, as it is the sum of the two preceding numbers (1 and 2)', () => { + expect(fibonacci(4)).toBe(3) + }) + + it('should return 5 for the sixth index (5) in the Fibonacci sequence, as it is the sum of the two preceding numbers (2 and 3)', () => { + expect(fibonacci(5)).toBe(5) + }) + + it('should throw an error for negative indices, as the Fibonacci sequence is not defined for negative numbers', () => { + expect(() => fibonacci(-1)).toThrow('Index cannot be negative') + }) + + it('should return 55 for the eleventh index (10) in the Fibonacci sequence, as it is the sum of the two preceding numbers (21 and 34)', () => { + expect(fibonacci(10)).toBe(55) + }) +}) From fc7e4b6732618a1daee0920caf90302692c3e229 Mon Sep 17 00:00:00 2001 From: Joe Carpenito Date: Tue, 4 Feb 2025 15:57:41 -0500 Subject: [PATCH 3/8] skipp assertions for now --- src/memoization/index.spec.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/memoization/index.spec.ts b/src/memoization/index.spec.ts index ec42415..f81a805 100644 --- a/src/memoization/index.spec.ts +++ b/src/memoization/index.spec.ts @@ -2,34 +2,34 @@ import { describe, it, expect } from 'bun:test' describe('Fibonacci Value Retrieval', () => { it('should return 0 for the first index (0) in the Fibonacci sequence', () => { - expect(fibonacci(0)).toBe(0) + // expect(fibonacci(0)).toBe(0) }) it('should return 1 for the second index (1) in the Fibonacci sequence', () => { - expect(fibonacci(1)).toBe(1) + // expect(fibonacci(1)).toBe(1) }) it('should return 1 for the third index (2) in the Fibonacci sequence, as it is the sum of the two preceding numbers (0 and 1)', () => { - expect(fibonacci(2)).toBe(1) + // expect(fibonacci(2)).toBe(1) }) it('should return 2 for the fourth index (3) in the Fibonacci sequence, as it is the sum of the two preceding numbers (1 and 1)', () => { - expect(fibonacci(3)).toBe(2) + // expect(fibonacci(3)).toBe(2) }) it('should return 3 for the fifth index (4) in the Fibonacci sequence, as it is the sum of the two preceding numbers (1 and 2)', () => { - expect(fibonacci(4)).toBe(3) + // expect(fibonacci(4)).toBe(3) }) it('should return 5 for the sixth index (5) in the Fibonacci sequence, as it is the sum of the two preceding numbers (2 and 3)', () => { - expect(fibonacci(5)).toBe(5) + // expect(fibonacci(5)).toBe(5) }) it('should throw an error for negative indices, as the Fibonacci sequence is not defined for negative numbers', () => { - expect(() => fibonacci(-1)).toThrow('Index cannot be negative') + // expect(() => fibonacci(-1)).toThrow('Index cannot be negative') }) it('should return 55 for the eleventh index (10) in the Fibonacci sequence, as it is the sum of the two preceding numbers (21 and 34)', () => { - expect(fibonacci(10)).toBe(55) + // expect(fibonacci(10)).toBe(55) }) }) From d4e757c3d1fc7d847d84dd4b9f8d9ddc507d5e5b Mon Sep 17 00:00:00 2001 From: Joe Carpenito Date: Wed, 5 Feb 2025 12:06:35 -0500 Subject: [PATCH 4/8] initial implementation of memoized fibonacci number --- src/memoization/index.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/memoization/index.ts b/src/memoization/index.ts index e69de29..3e3528e 100644 --- a/src/memoization/index.ts +++ b/src/memoization/index.ts @@ -0,0 +1,12 @@ +const memo: { [key: number]: number } = {} + +function fibonacci(n: number): number { + if (n <= 1) return n + if (memo[n]) return memo[n] + + memo[n] = fibonacci(n - 1) + fibonacci(n - 2) + return memo[n] +} + +// Example usage: +console.log(fibonacci(10)) // Output: 55 From 0b7fe0f0cabfd5ecc8916479d2ce47934f964935 Mon Sep 17 00:00:00 2001 From: Joe Carpenito Date: Wed, 5 Feb 2025 12:23:10 -0500 Subject: [PATCH 5/8] refactor sequence implementation to meet spec expectations and refine tests --- src/memoization/index.spec.ts | 29 +++++++++++++++-------------- src/memoization/index.ts | 8 +++----- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/src/memoization/index.spec.ts b/src/memoization/index.spec.ts index f81a805..baa4a62 100644 --- a/src/memoization/index.spec.ts +++ b/src/memoization/index.spec.ts @@ -1,35 +1,36 @@ import { describe, it, expect } from 'bun:test' +import { fibonacci } from '.' describe('Fibonacci Value Retrieval', () => { it('should return 0 for the first index (0) in the Fibonacci sequence', () => { - // expect(fibonacci(0)).toBe(0) + expect(fibonacci(0)).toBe(0) }) it('should return 1 for the second index (1) in the Fibonacci sequence', () => { - // expect(fibonacci(1)).toBe(1) + expect(fibonacci(1)).toBe(1) }) - it('should return 1 for the third index (2) in the Fibonacci sequence, as it is the sum of the two preceding numbers (0 and 1)', () => { - // expect(fibonacci(2)).toBe(1) + it('should return 1 for the third index (2) in the Fibonacci sequence, as it is the sum of the two preceding numbers', () => { + expect(fibonacci(2)).toBe(1) }) - it('should return 2 for the fourth index (3) in the Fibonacci sequence, as it is the sum of the two preceding numbers (1 and 1)', () => { - // expect(fibonacci(3)).toBe(2) + it('should return 2 for the fourth index (3) in the Fibonacci sequence, as it is the sum of the two preceding numbers', () => { + expect(fibonacci(3)).toBe(2) }) - it('should return 3 for the fifth index (4) in the Fibonacci sequence, as it is the sum of the two preceding numbers (1 and 2)', () => { - // expect(fibonacci(4)).toBe(3) + it('should return 3 for the fifth index (4) in the Fibonacci sequence, as it is the sum of the two preceding numbers', () => { + expect(fibonacci(4)).toBe(3) }) - it('should return 5 for the sixth index (5) in the Fibonacci sequence, as it is the sum of the two preceding numbers (2 and 3)', () => { - // expect(fibonacci(5)).toBe(5) + it('should return 5 for the sixth index (5) in the Fibonacci sequence, as it is the sum of the two preceding numbers', () => { + expect(fibonacci(5)).toBe(5) }) - it('should throw an error for negative indices, as the Fibonacci sequence is not defined for negative numbers', () => { - // expect(() => fibonacci(-1)).toThrow('Index cannot be negative') + it('should assume 0 for negative indices, as the Fibonacci sequence is not defined for negative numbers', () => { + expect(fibonacci(-1)).toBe(0) }) - it('should return 55 for the eleventh index (10) in the Fibonacci sequence, as it is the sum of the two preceding numbers (21 and 34)', () => { - // expect(fibonacci(10)).toBe(55) + it('should return 55 for the eleventh index (10) in the Fibonacci sequence, as it is the sum of the two preceding numbers', () => { + expect(fibonacci(10)).toBe(55) }) }) diff --git a/src/memoization/index.ts b/src/memoization/index.ts index 3e3528e..5c93747 100644 --- a/src/memoization/index.ts +++ b/src/memoization/index.ts @@ -1,12 +1,10 @@ const memo: { [key: number]: number } = {} -function fibonacci(n: number): number { - if (n <= 1) return n +export const fibonacci = (n: number): number => { + if (n <= 0) return 0 + if (n === 1) return 1 if (memo[n]) return memo[n] memo[n] = fibonacci(n - 1) + fibonacci(n - 2) return memo[n] } - -// Example usage: -console.log(fibonacci(10)) // Output: 55 From 0088a47702e12314ce43c252c6ef3b8f89a884c6 Mon Sep 17 00:00:00 2001 From: Joe Carpenito Date: Wed, 5 Feb 2025 12:31:05 -0500 Subject: [PATCH 6/8] =?UTF-8?q?simplify=20memo=20=F0=9F=A4=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/memoization/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/memoization/index.ts b/src/memoization/index.ts index 5c93747..12a9c32 100644 --- a/src/memoization/index.ts +++ b/src/memoization/index.ts @@ -1,4 +1,4 @@ -const memo: { [key: number]: number } = {} +const memo: number[] = [] export const fibonacci = (n: number): number => { if (n <= 0) return 0 From f59981aa4fb8a798fbcc0ed10938bbd09eafe5cb Mon Sep 17 00:00:00 2001 From: Joe Carpenito Date: Thu, 6 Feb 2025 09:01:30 -0500 Subject: [PATCH 7/8] add docs and clarify method definition and interface --- src/memoization/README.md | 43 +++++++++++++++++++++++++++++++++++++++ src/memoization/index.ts | 26 +++++++++++++++++------ 2 files changed, 63 insertions(+), 6 deletions(-) diff --git a/src/memoization/README.md b/src/memoization/README.md index e69de29..ab23ceb 100644 --- a/src/memoization/README.md +++ b/src/memoization/README.md @@ -0,0 +1,43 @@ +# Fibonacci Function + +This module provides a function to compute the nth Fibonacci number using memoization to optimize performance. + +## Function + +### `fibonacci(position: number): number` + +#### Description + +Computes the nth Fibonacci number using memoization to optimize performance. + +#### Parameters + +- `position` (number): The position in the Fibonacci sequence to compute. If a non-negative integer is provided, it will default to 0. + +#### Returns + +- `number`: The nth Fibonacci number. + +#### Example + +```typescript +import { fibonacci } from './index' + +console.log(fibonacci(0)) // returns 0 +console.log(fibonacci(1)) // returns 1 +console.log(fibonacci(5)) // returns 5 +console.log(fibonacci(10)) // returns 55 +``` + +## Usage + +1. Import the `fibonacci` function from the module. +2. Call the function with the desired position in the Fibonacci sequence. + +## Notes + +- The function uses memoization to store previously computed Fibonacci numbers, which significantly improves performance for large values of `n`. + +## License + +This project is licensed under the MIT License. diff --git a/src/memoization/index.ts b/src/memoization/index.ts index 12a9c32..dbf4165 100644 --- a/src/memoization/index.ts +++ b/src/memoization/index.ts @@ -1,10 +1,24 @@ const memo: number[] = [] -export const fibonacci = (n: number): number => { - if (n <= 0) return 0 - if (n === 1) return 1 - if (memo[n]) return memo[n] +/** + * Computes the nth Fibonacci number using memoization to optimize performance. + * + * @param {number} n - The position in the Fibonacci sequence to compute. If a non-negative integer is provided, it will default to 0. + * @returns {number} - The nth Fibonacci number. + * + * @example + * ```typescript + * fibonacci(0); // returns 0 + * fibonacci(1); // returns 1 + * fibonacci(5); // returns 5 + * fibonacci(10); // returns 55 + * ``` + */ +export const fibonacci = (position: number): number => { + if (position <= 0) return 0 + if (position === 1) return 1 + if (memo[position]) return memo[position] - memo[n] = fibonacci(n - 1) + fibonacci(n - 2) - return memo[n] + memo[position] = fibonacci(position - 1) + fibonacci(position - 2) + return memo[position] } From 8c74e3d159cc9d2cfc512d2a31b5457510c929d2 Mon Sep 17 00:00:00 2001 From: Joe Carpenito Date: Thu, 6 Feb 2025 09:08:57 -0500 Subject: [PATCH 8/8] add note about memoization benefit --- src/memoization/README.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/memoization/README.md b/src/memoization/README.md index ab23ceb..98b95e6 100644 --- a/src/memoization/README.md +++ b/src/memoization/README.md @@ -36,8 +36,4 @@ console.log(fibonacci(10)) // returns 55 ## Notes -- The function uses memoization to store previously computed Fibonacci numbers, which significantly improves performance for large values of `n`. - -## License - -This project is licensed under the MIT License. +- The function uses memoization to store previously computed Fibonacci numbers, which significantly improves performance for large values of `n`. Retrieving a value in the nth position for the first time is `O(2^n)` (expensive), whereas after the initial compute it is memoized and becomes a simple array access for `O(1)` (fast).