Skip to content

Commit ce2439a

Browse files
committed
feat: implement problem 4
1 parent 17ebfa0 commit ce2439a

File tree

8 files changed

+4723
-0
lines changed

8 files changed

+4723
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules
2+
dist
3+
.env

jest.config.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module.exports = {
2+
preset: 'ts-jest',
3+
testEnvironment: 'node',
4+
};

src/problem4/index.test.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { sumToNWithLoop, sumToNWithFormula, sumToNWithRecursion, sumToNMemoRecursion } from "./index";
2+
3+
describe("Sum to N functions", () => {
4+
it("sumToNWithLoop should return correct sum", () => {
5+
expect(sumToNWithLoop(5)).toBe(15);
6+
expect(sumToNWithLoop(0)).toBe(0);
7+
});
8+
9+
it("sumToNWithFormula should return correct sum", () => {
10+
expect(sumToNWithFormula(5)).toBe(15);
11+
expect(sumToNWithFormula(0)).toBe(0);
12+
});
13+
14+
it("sumToNWithRecursion should return correct sum", () => {
15+
expect(sumToNWithRecursion(5)).toBe(15);
16+
expect(sumToNWithRecursion(0)).toBe(0);
17+
});
18+
19+
it("sumToNMemoRecursion should return correct sum", () => {
20+
expect(sumToNMemoRecursion(5)).toBe(15);
21+
expect(sumToNMemoRecursion(0)).toBe(0);
22+
});
23+
24+
it("should throw error if result exceeds Number.MAX_SAFE_INTEGER", () => {
25+
// Find n such that (n * (n + 1)) / 2 > Number.MAX_SAFE_INTEGER
26+
const unsafeN = Math.floor((Math.sqrt(8 * Number.MAX_SAFE_INTEGER + 1) - 1) / 2) + 1;
27+
expect(() => sumToNWithLoop(unsafeN)).toThrow('Result exceeds Number.MAX_SAFE_INTEGER');
28+
expect(() => sumToNWithFormula(unsafeN)).toThrow('Result exceeds Number.MAX_SAFE_INTEGER');
29+
expect(() => sumToNWithRecursion(unsafeN)).toThrow('Result exceeds Number.MAX_SAFE_INTEGER');
30+
expect(() => sumToNMemoRecursion(unsafeN)).toThrow('Result exceeds Number.MAX_SAFE_INTEGER');
31+
});
32+
});

src/problem4/index.ts

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/**
2+
* Iteratively computes the sum from 1 to n using a loop.
3+
*
4+
* Time Complexity: O(n) — Iterates through all numbers from 1 to n.
5+
* Space Complexity: O(1) — Uses constant extra space for sum variable.
6+
*/
7+
export const sumToNWithLoop = (n: number): number => {
8+
/** Check if sum will exceed Number.MAX_SAFE_INTEGER */
9+
if (n > 0 && (n * (n + 1)) / 2 > Number.MAX_SAFE_INTEGER) {
10+
throw new Error('Result exceeds Number.MAX_SAFE_INTEGER');
11+
}
12+
let sum = 0;
13+
for (let i = 1; i <= n; i++) {
14+
sum += i;
15+
}
16+
return sum;
17+
}
18+
19+
20+
/**
21+
* Computes the sum from 1 to n using the mathematical formula.
22+
*
23+
* Time Complexity: O(1) — Direct calculation, no iteration.
24+
* Space Complexity: O(1) — No extra space required.
25+
*
26+
* This is the most optimal approach for this problem.
27+
*/
28+
export const sumToNWithFormula = (n: number): number => {
29+
/** Check if sum will exceed Number.MAX_SAFE_INTEGER */
30+
if (n > 0 && (n * (n + 1)) / 2 > Number.MAX_SAFE_INTEGER) {
31+
throw new Error('Result exceeds Number.MAX_SAFE_INTEGER');
32+
}
33+
return (n * (n + 1)) / 2;
34+
}
35+
36+
37+
/**
38+
* Recursively computes the sum from 1 to n.
39+
*
40+
* Time Complexity: O(n) — Recursion depth is n.
41+
* Space Complexity: O(n) — Call stack grows linearly with n.
42+
*
43+
* Not recommended for large n due to stack overflow risk.
44+
*/
45+
export const sumToNWithRecursion = (n: number): number => {
46+
/** Check if sum will exceed Number.MAX_SAFE_INTEGER */
47+
if (n > 0 && (n * (n + 1)) / 2 > Number.MAX_SAFE_INTEGER) {
48+
throw new Error('Result exceeds Number.MAX_SAFE_INTEGER');
49+
}
50+
if (n === 0) {
51+
return 0;
52+
}
53+
return n + sumToNWithRecursion(n - 1);
54+
}
55+
56+
/**
57+
* Memoized recursive computation of sum from 1 to n.
58+
*
59+
* Time Complexity: O(n) — Each value from 1 to n is computed once.
60+
* Space Complexity: O(n) — Stores results for each n in memoization map and call stack.
61+
*
62+
* Memoization is used to avoid redundant calculations in recursion, improving efficiency.
63+
* This technique is especially useful in problems with overlapping sub-problems.
64+
*/
65+
const memo = new Map<number, number>();
66+
67+
export function sumToNMemoRecursion(n: number): number {
68+
/** Check if sum will exceed Number.MAX_SAFE_INTEGER */
69+
if (n > 0 && (n * (n + 1)) / 2 > Number.MAX_SAFE_INTEGER) {
70+
throw new Error('Result exceeds Number.MAX_SAFE_INTEGER');
71+
}
72+
if (n <= 0) return 0;
73+
74+
if (memo.has(n)) {
75+
return memo.get(n)!;
76+
}
77+
78+
const result = n + sumToNMemoRecursion(n - 1);
79+
memo.set(n, result);
80+
81+
return result;
82+
}

src/problem4/jest.config.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module.exports = {
2+
preset: 'ts-jest',
3+
testEnvironment: 'node',
4+
};

0 commit comments

Comments
 (0)