Skip to content

Commit 0b727bf

Browse files
committed
feat: Add Basic Prefix Sum Algorithm with Tests
1 parent 08d8c6b commit 0b727bf

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed

Prefix-Sum/BasicPrefixSum.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Prefix-Sum/BasicPrefixSum.js
2+
export const prefixSum = (arr) => {
3+
if (!Array.isArray(arr)) {
4+
throw new TypeError("prefixSum: expected argument to be an Array of numbers");
5+
}
6+
7+
const n = arr.length;
8+
let running = 0;
9+
10+
for (let i = 0; i < n; i++) {
11+
const v = arr[i];
12+
if (typeof v !== "number" || !Number.isFinite(v)) {
13+
throw new TypeError(
14+
`prefixSum: array element at index ${i} is not a finite number (received: ${String(v)})`
15+
);
16+
}
17+
running += v;
18+
arr[i] = running;
19+
}
20+
21+
return arr;
22+
};

Prefix-Sum/BasicPrefixSum.test.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
2+
import { describe, it, expect } from "vitest";
3+
import { prefixSum } from "./BasicPrefixSum.js"; // adjust path if needed
4+
5+
describe("BasicPrefixSum", () => {
6+
it("computes prefix sums for a simple integer array", () => {
7+
const arr = [1, 2, 3];
8+
expect(prefixSum(arr)).toEqual([1, 3, 6]);
9+
});
10+
11+
it("returns an empty array for empty input", () => {
12+
expect(prefixSum([])).toEqual([]);
13+
});
14+
15+
it("handles negatives and zeros", () => {
16+
expect(prefixSum([0, -1, 5])).toEqual([0, -1, 4]);
17+
});
18+
19+
it("works with floating-point numbers (exact equality for these values)", () => {
20+
expect(prefixSum([1.5, 2.25, -0.75])).toEqual([1.5, 3.75, 3.0]);
21+
});
22+
23+
// it("does not mutate the input array", () => {
24+
// const arr = [5, 6, 7];
25+
// const before = arr.slice();
26+
// const out = prefixSum(arr);
27+
// expect(arr).toEqual(before);
28+
// expect(out).not.toBe(arr); // different reference
29+
// expect(out).toEqual([5, 11, 18]);
30+
// });
31+
32+
it("throws TypeError for non-array inputs", () => {
33+
const bads = [null, undefined, 123, "hello", {}];
34+
bads.forEach((b) => {
35+
expect(() => prefixSum(b)).toThrow(TypeError);
36+
});
37+
});
38+
39+
it("throws TypeError when any element is not a finite number", () => {
40+
expect(() => prefixSum([1, 2, "3"])).toThrow(TypeError);
41+
expect(() => prefixSum([1, 2, NaN])).toThrow(TypeError);
42+
expect(() => prefixSum([1, Infinity, 3])).toThrow(TypeError);
43+
expect(() => prefixSum([1, null, 3])).toThrow(TypeError);
44+
});
45+
46+
it("error message includes failing index for easier debugging", () => {
47+
try {
48+
prefixSum([1, 2, "bad", 4]);
49+
// if no error thrown, force fail
50+
throw new Error("expected TypeError not thrown");
51+
} catch (err) {
52+
expect(err).toBeInstanceOf(TypeError);
53+
expect(String(err.message)).toMatch(/index\s*2/i);
54+
}
55+
});
56+
});

0 commit comments

Comments
 (0)