0% found this document useful (0 votes)
4 views62 pages

NodeJS Questions

The document outlines a series of Node.js coding challenges, categorized by difficulty (easy, medium, hard), with specific problems such as enhancing array prototypes, creating a counter function, implementing sleep functionality, and performing array reduce transformations. Each challenge includes examples, constraints, and sample test cases to validate the solutions. Additionally, hidden test cases are provided to further ensure robustness of the implementations.

Uploaded by

nivetha.soumi20
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views62 pages

NodeJS Questions

The document outlines a series of Node.js coding challenges, categorized by difficulty (easy, medium, hard), with specific problems such as enhancing array prototypes, creating a counter function, implementing sleep functionality, and performing array reduce transformations. Each challenge includes examples, constraints, and sample test cases to validate the solutions. Additionally, hidden test cases are provided to further ensure robustness of the implementations.

Uploaded by

nivetha.soumi20
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Node.

js Coding Challenges1

[Link] Coding Challenges


Practice Problems with Sample & Hidden Test Cases
Easy · Medium · Hard | Vitest format

🟢 EASY LEVEL

E-01. Array Prototype Last


Write code that enhances all arrays such that you can call the [Link]() method on any array and it
will return the last element. If there are no elements in the array, it should return -1.
You may assume the array is the output of [Link].
🟢 Examples
Example 1:
Input: nums = [null, {}, 3]
Output: 3
Explanation: Calling [Link]() should return the last element: 3.

Example 2:
Input: nums = []
Output: -1
Explanation: Because there are no elements, return -1.

🟢 Constraints
• arr is a valid JSON array
• 0 <= [Link] <= 1000
🟢 Sample Test Cases

Sample Test Cases — At a Glance


# Input / Setup Expected Output
1 returns last element of a normal expect([null, {}, 3].last()).toBe(3)
array

2 returns -1 for an empty array expect([].last()).toBe(-1)

3 returns single element expect([42].last()).toBe(42)

4 works with string elements expect(["a", "b", "c"].last()).toBe("c")

import { describe, expect, it } from "vitest";


import { arrayPrototypeLast } from "./solutions/e01-array-prototype-
last";
[Link] Coding Challenges2

describe("E-01 · Array Prototype Last", () => {


it("returns last element of a normal array", () => {
expect([null, {}, 3].last()).toBe(3);
});

it("returns -1 for an empty array", () => {


expect([].last()).toBe(-1);
});

it("returns single element", () => {


expect([42].last()).toBe(42);
});

it("works with string elements", () => {


expect(["a", "b", "c"].last()).toBe("c");
});
});

🟢 Hidden Test Cases

Hidden Test Cases — At a Glance


# Input / Setup Expected Output
1 returns null as last element (falsy expect([1, 2, null].last()).toBe(null)
but valid)

2 returns false as last element expect([true, false].last()).toBe(false)

3 returns 0 as last element (not -1) expect([5, 0].last()).toBe(0)

4 handles a 1000-element array expect([Link]()).toBe(999)


const arr = [Link]({
length: 1000 }, (_, i) => i);

5 handles nested objects as last expect([1, obj].last()).toBe(obj)


element
const obj = { a: 1 };

describe("E-01 · Array Prototype Last — Hidden", () => {


it("returns null as last element (falsy but valid)", () => {
expect([1, 2, null].last()).toBe(null);
});

it("returns false as last element", () => {


expect([true, false].last()).toBe(false);
});

it("returns 0 as last element (not -1)", () => {


expect([5, 0].last()).toBe(0);
});

it("handles a 1000-element array", () => {


const arr = [Link]({ length: 1000 }, (_, i) => i);
expect([Link]()).toBe(999);
});
[Link] Coding Challenges3

it("handles nested objects as last element", () => {


const obj = { a: 1 };
expect([1, obj].last()).toBe(obj);
});
});

E-02. Counter
Given an integer n, return a counter function. This counter function initially returns n and then returns 1
more than the previous value every subsequent time it is called.
🟢 Examples
Example 1:
Input: n = 10, calls = ["call","call","call"]
Output: [10, 11, 12]

Example 2:
Input: n = -2, calls = ["call","call","call","call","call"]
Output: [-2, -1, 0, 1, 2]

🟢 Constraints
• -1000 <= n <= 1000
• 0 <= [Link] <= 1000
• calls[i] === "call"
🟢 Sample Test Cases

Sample Test Cases — At a Glance


# Input / Setup Expected Output
1 starts at n and increments expect(counter()).toBe(10)
const counter = expect(counter()).toBe(11)
createCounter(10); expect(counter()).toBe(12)

2 works with negative start expect([...Array(5)].map(() => counter())).toEqual([-


const counter = 2,-1,0,1,2])
createCounter(-2);

3 works when n = 0 expect(counter()).toBe(0)


const counter = expect(counter()).toBe(1)
createCounter(0);

import { describe, expect, it } from "vitest";


import { createCounter } from "./solutions/e02-counter";

describe("E-02 · Counter", () => {


it("starts at n and increments", () => {
const counter = createCounter(10);
expect(counter()).toBe(10);
[Link] Coding Challenges4

expect(counter()).toBe(11);
expect(counter()).toBe(12);
});

it("works with negative start", () => {


const counter = createCounter(-2);
expect([...Array(5)].map(() => counter())).toEqual([-2,-1,0,1,2]);
});

it("works when n = 0", () => {


const counter = createCounter(0);
expect(counter()).toBe(0);
expect(counter()).toBe(1);
});
});

🟢 Hidden Test Cases

Hidden Test Cases — At a Glance


# Input / Setup Expected Output
1 n = 1000 (upper bound) expect(counter()).toBe(1000)
const counter = expect(counter()).toBe(1001)
createCounter(1000);

2 n = -1000 (lower bound) expect(counter()).toBe(-1000)


const counter =
createCounter(-1000);

3 multiple independent counters expect(a()).toBe(7)


don't interfere expect(b()).toBe(100)
const a = createCounter(5);
const b = createCounter(100);

4 0 calls returns no values expect(typeof counter).toBe("function")


const counter =
createCounter(0);

describe("E-02 · Counter — Hidden", () => {


it("n = 1000 (upper bound)", () => {
const counter = createCounter(1000);
expect(counter()).toBe(1000);
expect(counter()).toBe(1001);
});

it("n = -1000 (lower bound)", () => {


const counter = createCounter(-1000);
expect(counter()).toBe(-1000);
});

it("multiple independent counters don't interfere", () => {


const a = createCounter(5);
const b = createCounter(100);
a(); a();
expect(a()).toBe(7);
expect(b()).toBe(100);
});
[Link] Coding Challenges5

it("0 calls returns no values", () => {


const counter = createCounter(0);
expect(typeof counter).toBe("function");
});
});

E-03. Sleep
Given a positive integer millis, write an asynchronous function that sleeps for millis milliseconds. It can
resolve any value. Note that minor deviation from millis in the actual sleep duration is acceptable.
🟢 Examples
Example 1:
Input: millis = 100
Output: 100 (resolves after ~100 ms)

Example 2:
Input: millis = 200
Output: 200 (resolves after ~200 ms)

🟢 Constraints
• 1 <= millis <= 1000
🟢 Sample Test Cases

Sample Test Cases — At a Glance


# Input / Setup Expected Output
1 resolves after approximately 100 expect([Link]() - t).toBeGreaterThanOrEqual(90)
ms
const t = [Link]();

2 resolves after approximately 200 expect([Link]() - t).toBeGreaterThanOrEqual(190)


ms
const t = [Link]();

3 returns a Promise expect(sleep(50)).toBeInstanceOf(Promise)

import { describe, expect, it } from "vitest";


import { sleep } from "./solutions/e03-sleep";

describe("E-03 · Sleep", () => {


it("resolves after approximately 100 ms", async () => {
const t = [Link]();
await sleep(100);
expect([Link]() - t).toBeGreaterThanOrEqual(90);
});

it("resolves after approximately 200 ms", async () => {


[Link] Coding Challenges6

const t = [Link]();
await sleep(200);
expect([Link]() - t).toBeGreaterThanOrEqual(190);
});

it("returns a Promise", () => {


expect(sleep(50)).toBeInstanceOf(Promise);
});
});

🟢 Hidden Test Cases

Hidden Test Cases — At a Glance


# Input / Setup Expected Output
1 minimum millis = 1 expect([Link]() - t).toBeGreaterThanOrEqual(0)
const t = [Link]();

2 maximum millis = 1000 expect([Link]() - t).toBeGreaterThanOrEqual(990)


const t = [Link]();

3 resolves with any value (undefined expect(result).toBeUndefined()


by default)
const result = await
sleep(50);

4 multiple sleeps are sequential expect([Link]() - t).toBeGreaterThanOrEqual(90)


const t = [Link]();

describe("E-03 · Sleep — Hidden", () => {


it("minimum millis = 1", async () => {
const t = [Link]();
await sleep(1);
expect([Link]() - t).toBeGreaterThanOrEqual(0);
});

it("maximum millis = 1000", async () => {


const t = [Link]();
await sleep(1000);
expect([Link]() - t).toBeGreaterThanOrEqual(990);
});

it("resolves with any value (undefined by default)", async () => {


const result = await sleep(50);
expect(result).toBeUndefined();
});

it("multiple sleeps are sequential", async () => {


const t = [Link]();
await sleep(50);
await sleep(50);
expect([Link]() - t).toBeGreaterThanOrEqual(90);
});
});
[Link] Coding Challenges7

E-04. Array Reduce Transformation


Given an integer array nums, a reducer function fn, and an initial value init, return the final result
obtained by executing fn on each element sequentially. If the array is empty, return init. Solve without
the built-in [Link].
🟢 Examples
Example 1:
Input: nums=[1,2,3,4], fn=sum(accum,curr)=>accum+curr, init=0
Output: 10

Example 2:
Input: nums=[1,2,3,4], fn=(accum,curr)=>accum+curr*curr, init=100
Output: 130

Example 3:
Input: nums=[], fn=any, init=25
Output: 25

🟢 Constraints
• 0 <= [Link] <= 1000
• 0 <= nums[i] <= 1000
• 0 <= init <= 1000
🟢 Sample Test Cases

Sample Test Cases — At a Glance


# Input / Setup Expected Output
1 sums an array from zero expect(reduce([1, 2, 3, 4], fn, 0)).toBe(10)
const fn = (acc: number, cur:
number) => acc + cur;

2 accumulates sum of squares with expect(reduce([1, 2, 3, 4], fn, 100)).toBe(130)


offset init
const fn = (acc: number, cur:
number) => acc + cur * cur;

3 returns init for empty array expect(reduce([], (a, b) => a + b, 25)).toBe(25)

import { describe, expect, it } from "vitest";


import { reduce } from "./solutions/e04-array-reduce";

describe("E-04 · Array Reduce Transformation", () => {


it("sums an array from zero", () => {
const fn = (acc: number, cur: number) => acc + cur;
expect(reduce([1, 2, 3, 4], fn, 0)).toBe(10);
});
[Link] Coding Challenges8

it("accumulates sum of squares with offset init", () => {


const fn = (acc: number, cur: number) => acc + cur * cur;
expect(reduce([1, 2, 3, 4], fn, 100)).toBe(130);
});

it("returns init for empty array", () => {


expect(reduce([], (a, b) => a + b, 25)).toBe(25);
});
});

🟢 Hidden Test Cases

Hidden Test Cases — At a Glance


# Input / Setup Expected Output
1 single element array expect(reduce([7], (a, b) => a + b, 0)).toBe(7)

2 multiplication reducer expect(reduce([1, 2, 3, 4], (a, b) => a * b,


1)).toBe(24)

3 does not use —


[Link]
const original =
[Link];

4 init=1000 with all-1000 array of expect(reduce([1000], (a, b) => a + b,


length 1 1000)).toBe(2000)

describe("E-04 · Array Reduce Transformation — Hidden", () => {


it("single element array", () => {
expect(reduce([7], (a, b) => a + b, 0)).toBe(7);
});

it("multiplication reducer", () => {


expect(reduce([1, 2, 3, 4], (a, b) => a * b, 1)).toBe(24);
});

it("does not use [Link]", () => {


const original = [Link];
[Link] = () => { throw new Error("forbidden"); };
expect(() => reduce([1, 2], (a, b) => a + b, 0)).[Link]();
[Link] = original;
});

it("init=1000 with all-1000 array of length 1", () => {


expect(reduce([1000], (a, b) => a + b, 1000)).toBe(2000);
});
});

E-05. Function Composition


Given an array of functions [f1, f2, ..., fn], return a new function that is their composition evaluated right-
to-left: fn(x) = f1(f2(...fn(x))). An empty array should return the identity function.
[Link] Coding Challenges9

🟢 Examples
Example 1:
Input: functions = [x=>x+1, x=>x*x, x=>2*x], x = 4
Output: 65 // 2*4=8 → 8*8=64 → 64+1=65

Example 2:
Input: functions = [], x = 42
Output: 42 // identity

🟢 Constraints
• -1000 <= x <= 1000
• 0 <= [Link] <= 1000
• All functions accept and return a single integer
🟢 Sample Test Cases

Sample Test Cases — At a Glance


# Input / Setup Expected Output
1 composes three functions right-to- expect(fn(4)).toBe(65)
left
const fn = compose([x => x +
1, x => x * x, x => 2 * x]);

2 identity for empty array expect(compose([])(42)).toBe(42)

3 single function composition expect(compose([x => x + 10])(5)).toBe(15)

import { describe, expect, it } from "vitest";


import { compose } from "./solutions/e05-function-composition";

describe("E-05 · Function Composition", () => {


it("composes three functions right-to-left", () => {
const fn = compose([x => x + 1, x => x * x, x => 2 * x]);
expect(fn(4)).toBe(65);
});

it("identity for empty array", () => {


expect(compose([])(42)).toBe(42);
});

it("single function composition", () => {


expect(compose([x => x + 10])(5)).toBe(15);
});
});

🟢 Hidden Test Cases

Hidden Test Cases — At a Glance


# Input / Setup Expected Output
1 triple multiply expect(fn(1)).toBe(1000)
[Link] Coding Challenges10

const fn = compose([x => 10 *


x, x => 10 * x, x => 10 *
x]);

2 negative result expect(fn(5)).toBe(-6)


const fn = compose([x => -x,
x => x + 1]);

3 x = -1000 (lower bound) expect(compose([x => x])(-1000)).toBe(-1000)

4 x = 1000 (upper bound) expect(compose([x => x * 2])(1000)).toBe(2000)

describe("E-05 · Function Composition — Hidden", () => {


it("triple multiply", () => {
const fn = compose([x => 10 * x, x => 10 * x, x => 10 * x]);
expect(fn(1)).toBe(1000);
});

it("negative result", () => {


const fn = compose([x => -x, x => x + 1]);
expect(fn(5)).toBe(-6);
});

it("x = -1000 (lower bound)", () => {


expect(compose([x => x])(-1000)).toBe(-1000);
});

it("x = 1000 (upper bound)", () => {


expect(compose([x => x * 2])(1000)).toBe(2000);
});
});

E-06. Filter Elements from Array


Given an integer array arr and a filtering function fn, return a filtered array containing only the elements
for which fn(arr[i], i) evaluates to a truthy value. Solve without [Link].
🟢 Examples
Example 1:
Input: arr=[0,10,20,30], fn=n=>n>10
Output: [20, 30]

Example 2:
Input: arr=[1,2,3], fn=(n,i)=>i===0
Output: [1]

Example 3:
Input: arr=[-2,-1,0,1,2], fn=n=>n+1
Output: [-2, 0, 1, 2] // 0 is falsy
[Link] Coding Challenges11

🟢 Constraints
• 0 <= [Link] <= 1000
• -10^9 <= arr[i] <= 10^9
🟢 Sample Test Cases

Sample Test Cases — At a Glance


# Input / Setup Expected Output
1 filters elements greater than 10 expect(filter([0, 10, 20, 30], n => n >
10)).toEqual([20, 30])

2 filters by index expect(filter([1, 2, 3], (n, i) => i ===


0)).toEqual([1])

3 treats 0 as falsy expect(filter([-2, -1, 0, 1, 2], n => n +


1)).toEqual([-2, 0, 1, 2])

4 empty array returns empty array expect(filter([], n => n > 0)).toEqual([])

import { describe, expect, it } from "vitest";


import { filter } from "./solutions/e06-filter-array";

describe("E-06 · Filter Elements from Array", () => {


it("filters elements greater than 10", () => {
expect(filter([0, 10, 20, 30], n => n > 10)).toEqual([20, 30]);
});

it("filters by index", () => {


expect(filter([1, 2, 3], (n, i) => i === 0)).toEqual([1]);
});

it("treats 0 as falsy", () => {


expect(filter([-2, -1, 0, 1, 2], n => n + 1)).toEqual([-2, 0, 1, 2]);
});

it("empty array returns empty array", () => {


expect(filter([], n => n > 0)).toEqual([]);
});
});

🟢 Hidden Test Cases

Hidden Test Cases — At a Glance


# Input / Setup Expected Output
1 does not use [Link] —
const original =
[Link];

2 all elements pass the filter expect(filter([5, 5, 5], n => n === 5)).toEqual([5, 5,
5])

3 no elements pass the filter expect(filter([1, 2, 3], n => n > 100)).toEqual([])

4 negative numbers filtered correctly expect(filter([-5, -3, 0, 3, 5], n => n >


0)).toEqual([3, 5])
[Link] Coding Challenges12

describe("E-06 · Filter Elements from Array — Hidden", () => {


it("does not use [Link]", () => {
const original = [Link];
[Link] = () => { throw new Error("forbidden"); };
expect(() => filter([1, 2, 3], n => n > 1)).[Link]();
[Link] = original;
});

it("all elements pass the filter", () => {


expect(filter([5, 5, 5], n => n === 5)).toEqual([5, 5, 5]);
});

it("no elements pass the filter", () => {


expect(filter([1, 2, 3], n => n > 100)).toEqual([]);
});

it("negative numbers filtered correctly", () => {


expect(filter([-5, -3, 0, 3, 5], n => n > 0)).toEqual([3, 5]);
});
});

E-07. Apply Transform Over Each Element in Array


Given an integer array arr and a mapping function fn, return a new array where returnedArray[i] =
fn(arr[i], i). Solve without the built-in [Link].
🟢 Examples
Example 1:
Input: arr=[1,2,3], fn=n=>n+1
Output: [2, 3, 4]

Example 2:
Input: arr=[1,2,3], fn=(n,i)=>n+i
Output: [1, 3, 5]

Example 3:
Input: arr=[10,20,30], fn=()=>42
Output: [42, 42, 42]

🟢 Constraints
• 0 <= [Link] <= 1000
• -10^9 <= arr[i] <= 10^9
• fn returns an integer
🟢 Sample Test Cases

Sample Test Cases — At a Glance


[Link] Coding Challenges13

# Input / Setup Expected Output


1 increments each element by 1 expect(map([1, 2, 3], n => n + 1)).toEqual([2, 3, 4])

2 adds index to each element expect(map([1, 2, 3], (n, i) => n + i)).toEqual([1, 3,


5])

3 constant function returns same expect(map([10, 20, 30], () => 42)).toEqual([42, 42,
value for all 42])

4 empty array returns empty array expect(map([], n => n * 2)).toEqual([])

import { describe, expect, it } from "vitest";


import { map } from "./solutions/e07-map-transform";

describe("E-07 · Apply Transform Over Each Element", () => {


it("increments each element by 1", () => {
expect(map([1, 2, 3], n => n + 1)).toEqual([2, 3, 4]);
});

it("adds index to each element", () => {


expect(map([1, 2, 3], (n, i) => n + i)).toEqual([1, 3, 5]);
});

it("constant function returns same value for all", () => {


expect(map([10, 20, 30], () => 42)).toEqual([42, 42, 42]);
});

it("empty array returns empty array", () => {


expect(map([], n => n * 2)).toEqual([]);
});
});

🟢 Hidden Test Cases

Hidden Test Cases — At a Glance


# Input / Setup Expected Output
1 does not use [Link] —
const original =
[Link];

2 single element array expect(map([0], n => n * 100)).toEqual([0])

3 negative numbers expect(map([-3, -2, -1], n => n * n)).toEqual([9, 4,


1])

4 index-based transform on large expect(result[99]).toBe(198)


array
const arr = [Link]({
length: 100 }, (_, i) => i);
const result = map(arr, (n,
i) => n + i);

describe("E-07 · Apply Transform Over Each Element — Hidden", () => {


it("does not use [Link]", () => {
const original = [Link];
[Link] = () => { throw new Error("forbidden"); };
[Link] Coding Challenges14

expect(() => map([1, 2], n => n)).[Link]();


[Link] = original;
});

it("single element array", () => {


expect(map([0], n => n * 100)).toEqual([0]);
});

it("negative numbers", () => {


expect(map([-3, -2, -1], n => n * n)).toEqual([9, 4, 1]);
});

it("index-based transform on large array", () => {


const arr = [Link]({ length: 100 }, (_, i) => i);
const result = map(arr, (n, i) => n + i);
expect(result[99]).toBe(198);
});
});

E-08. Generate Fibonacci Sequence


Write a generator function that returns a generator object which yields the Fibonacci sequence: 0, 1, 1,
2, 3, 5, 8, 13, ...
🟢 Examples
Example 1:
Input: callCount = 5
Output: [0, 1, 1, 2, 3]

Example 2:
Input: callCount = 0
Output: []

🟢 Constraints
• 0 <= callCount <= 50
🟢 Sample Test Cases

Sample Test Cases — At a Glance


# Input / Setup Expected Output
1 generates first 5 Fibonacci expect(result).toEqual([0, 1, 1, 2, 3])
numbers
const gen = fibGenerator();
const result =
[...Array(5)].map(() =>
[Link]().value);

2 zero calls returns no values expect([Link]().done).toBe(false); // generator is


const gen = fibGenerator(); infinite

3 first two values are 0 and 1 expect([Link]().value).toBe(0)


[Link] Coding Challenges15

const gen = fibGenerator(); expect([Link]().value).toBe(1)

import { describe, expect, it } from "vitest";


import { fibGenerator } from "./solutions/e08-fibonacci";

describe("E-08 · Generate Fibonacci Sequence", () => {


it("generates first 5 Fibonacci numbers", () => {
const gen = fibGenerator();
const result = [...Array(5)].map(() => [Link]().value);
expect(result).toEqual([0, 1, 1, 2, 3]);
});

it("zero calls returns no values", () => {


const gen = fibGenerator();
expect([Link]().done).toBe(false); // generator is infinite
});

it("first two values are 0 and 1", () => {


const gen = fibGenerator();
expect([Link]().value).toBe(0);
expect([Link]().value).toBe(1);
});
});

🟢 Hidden Test Cases

Hidden Test Cases — At a Glance


# Input / Setup Expected Output
1 8th value is 13 expect(result).toEqual([0, 1, 1, 2, 3, 5, 8, 13])
const gen = fibGenerator();
const result =
[...Array(8)].map(() =>
[Link]().value);

2 50th call gives correct Fibonacci expect(val).toBe(12586269025)


number
const gen = fibGenerator();
let val;

3 generator never signals done expect([Link]().done).toBe(false)


(infinite)
const gen = fibGenerator();

describe("E-08 · Fibonacci Generator — Hidden", () => {


it("8th value is 13", () => {
const gen = fibGenerator();
const result = [...Array(8)].map(() => [Link]().value);
expect(result).toEqual([0, 1, 1, 2, 3, 5, 8, 13]);
});

it("50th call gives correct Fibonacci number", () => {


const gen = fibGenerator();
let val;
for (let i = 0; i < 50; i++) val = [Link]().value;
[Link] Coding Challenges16

expect(val).toBe(12586269025);
});

it("generator never signals done (infinite)", () => {


const gen = fibGenerator();
for (let i = 0; i < 20; i++) {
expect([Link]().done).toBe(false);
}
});
});

E-09. Allow One Function Call


Given a function fn, return a new function that ensures fn is called at most once. The first call returns
the same result as fn. Every subsequent call returns undefined.
🟢 Examples
Example 1:
Input: fn=(a,b,c)=>a+b+c, calls=[[1,2,3],[2,3,6]]
Output: [{calls:1, value:6}]

Example 2:
Input: fn=(a,b,c)=>a*b*c, calls=[[5,7,4],[2,3,6],[4,6,8]]
Output: [{calls:1, value:140}]

🟢 Constraints
• 1 <= [Link] <= 10
• 1 <= calls[i].length <= 100
🟢 Sample Test Cases

Sample Test Cases — At a Glance


# Input / Setup Expected Output
1 returns result on first call expect(onceFn(1, 2, 3)).toBe(6)
const onceFn = once((a:
number, b: number, c: number)
=> a + b + c);

2 returns undefined on subsequent expect(onceFn(2, 3, 6)).toBeUndefined()


calls
const onceFn = once((a:
number, b: number, c: number)
=> a + b + c);

3 only calls the inner function once expect(count).toBe(1)


let count = 0;
const onceFn = once(() => {
count++; return count; });

import { describe, expect, it } from "vitest";


[Link] Coding Challenges17

import { once } from "./solutions/e09-once";

describe("E-09 · Allow One Function Call", () => {


it("returns result on first call", () => {
const onceFn = once((a: number, b: number, c: number) => a + b + c);
expect(onceFn(1, 2, 3)).toBe(6);
});

it("returns undefined on subsequent calls", () => {


const onceFn = once((a: number, b: number, c: number) => a + b + c);
onceFn(1, 2, 3);
expect(onceFn(2, 3, 6)).toBeUndefined();
});

it("only calls the inner function once", () => {


let count = 0;
const onceFn = once(() => { count++; return count; });
onceFn(); onceFn(); onceFn();
expect(count).toBe(1);
});
});

🟢 Hidden Test Cases

Hidden Test Cases — At a Glance


# Input / Setup Expected Output
1 returns falsy value (0) correctly on expect(onceFn()).toBe(0)
first call expect(onceFn()).toBeUndefined()
const onceFn = once(() => 0);

2 works with no arguments expect(onceFn()).toBe("hello")


const onceFn = once(() => expect(onceFn()).toBeUndefined()
"hello");

3 different once instances are expect(f2()).toBe(2)


independent
const f1 = once(() => 1);
const f2 = once(() => 2);

4 works with multiplication expect(onceFn(5, 7, 4)).toBe(140)


const onceFn = once((a: expect(onceFn(2, 3, 6)).toBeUndefined()
number, b: number, c: number) expect(onceFn(4, 6, 8)).toBeUndefined()
=> a * b * c);

describe("E-09 · Allow One Function Call — Hidden", () => {


it("returns falsy value (0) correctly on first call", () => {
const onceFn = once(() => 0);
expect(onceFn()).toBe(0);
expect(onceFn()).toBeUndefined();
});

it("works with no arguments", () => {


const onceFn = once(() => "hello");
expect(onceFn()).toBe("hello");
expect(onceFn()).toBeUndefined();
});
[Link] Coding Challenges18

it("different once instances are independent", () => {


const f1 = once(() => 1);
const f2 = once(() => 2);
f1();
expect(f2()).toBe(2);
});

it("works with multiplication", () => {


const onceFn = once((a: number, b: number, c: number) => a * b * c);
expect(onceFn(5, 7, 4)).toBe(140);
expect(onceFn(2, 3, 6)).toBeUndefined();
expect(onceFn(4, 6, 8)).toBeUndefined();
});
});

E-10. Create Hello World Function


Write a function createHelloWorld. It should return a new function that always returns "Hello World",
regardless of any arguments passed.
🟢 Examples
Example 1:
Input: args = []
Output: "Hello World"

Example 2:
Input: args = [{}, null, 42]
Output: "Hello World"

🟢 Constraints
• 0 <= [Link] <= 10
🟢 Sample Test Cases

Sample Test Cases — At a Glance


# Input / Setup Expected Output
1 returns Hello World with no args expect(f()).toBe("Hello World")
const f = createHelloWorld();

2 ignores arguments and returns expect(f({}, null, 42)).toBe("Hello World")


Hello World
const f = createHelloWorld();

3 returns Hello World on multiple expect(f()).toBe("Hello World")


calls expect(f()).toBe("Hello World")
const f = createHelloWorld();

import { describe, expect, it } from "vitest";


[Link] Coding Challenges19

import { createHelloWorld } from "./solutions/e10-hello-world";

describe("E-10 · Create Hello World Function", () => {


it("returns Hello World with no args", () => {
const f = createHelloWorld();
expect(f()).toBe("Hello World");
});

it("ignores arguments and returns Hello World", () => {


const f = createHelloWorld();
expect(f({}, null, 42)).toBe("Hello World");
});

it("returns Hello World on multiple calls", () => {


const f = createHelloWorld();
expect(f()).toBe("Hello World");
expect(f()).toBe("Hello World");
});
});

🟢 Hidden Test Cases

Hidden Test Cases — At a Glance


# Input / Setup Expected Output
1 ignores string arguments expect(f("bye")).toBe("Hello World")
const f = createHelloWorld();

2 each call to createHelloWorld expect(f1()).toBe("Hello World")


returns an independent function expect(f2()).toBe("Hello World")
const f1 =
createHelloWorld();
const f2 =
createHelloWorld();

3 maximum args (10) still returns expect(f(1,2,3,4,5,6,7,8,9,10)).toBe("Hello World")


Hello World
const f = createHelloWorld();

describe("E-10 · Create Hello World Function — Hidden", () => {


it("ignores string arguments", () => {
const f = createHelloWorld();
expect(f("bye")).toBe("Hello World");
});

it("each call to createHelloWorld returns an independent function", ()


=> {
const f1 = createHelloWorld();
const f2 = createHelloWorld();
expect(f1()).toBe("Hello World");
expect(f2()).toBe("Hello World");
});

it("maximum args (10) still returns Hello World", () => {


const f = createHelloWorld();
expect(f(1,2,3,4,5,6,7,8,9,10)).toBe("Hello World");
[Link] Coding Challenges20

});
});

🟢 MEDIUM LEVEL

M-01. Count the Number of Special Characters


A letter c is called special if it appears both in lowercase and uppercase in word, and every lowercase
occurrence of c appears before the first uppercase occurrence of c. Return the number of special
letters.
🟢 Examples
Example 1:
Input: word = "aaAbcBC"
Output: 3 // a, b, c are special

Example 2:
Input: word = "abc"
Output: 0

Example 3:
Input: word = "AbBCab"
Output: 0 // uppercase appears before lowercase

🟢 Constraints
• 1 <= [Link] <= 2 * 10^5
• word consists of only lowercase and uppercase English letters
🟢 Sample Test Cases

Sample Test Cases — At a Glance


# Input / Setup Expected Output
1 returns 3 for 'aaAbcBC' expect(countSpecialChars("aaAbcBC")).toBe(3)

2 returns 0 when no uppercase expect(countSpecialChars("abc")).toBe(0)


exists

3 returns 0 when uppercase expect(countSpecialChars("AbBCab")).toBe(0)


precedes lowercase

4 returns 1 for 'aA' expect(countSpecialChars("aA")).toBe(1)

import { describe, expect, it } from "vitest";


import { countSpecialChars } from "./solutions/m01-special-chars";

describe("M-01 · Count Special Characters", () => {


it("returns 3 for 'aaAbcBC'", () => {
[Link] Coding Challenges21

expect(countSpecialChars("aaAbcBC")).toBe(3);
});

it("returns 0 when no uppercase exists", () => {


expect(countSpecialChars("abc")).toBe(0);
});

it("returns 0 when uppercase precedes lowercase", () => {


expect(countSpecialChars("AbBCab")).toBe(0);
});

it("returns 1 for 'aA'", () => {


expect(countSpecialChars("aA")).toBe(1);
});
});

🟢 Hidden Test Cases

Hidden Test Cases — At a Glance


# Input / Setup Expected Output
1 single lowercase only expect(countSpecialChars("a")).toBe(0)

2 all uppercase only expect(countSpecialChars("ABC")).toBe(0)

3 all 26 letters special: expect(countSpecialChars(lower + upper)).toBe(26)


abcde...ABCDE...
const lower =
"abcdefghijklmnopqrstuvwxyz";
const upper =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";

4 interleaved where some letters expect(countSpecialChars("aAbB")).toBe(2)


qualify and some don't expect(countSpecialChars("AaBb")).toBe(0)

describe("M-01 · Count Special Characters — Hidden", () => {


it("single lowercase only", () => {
expect(countSpecialChars("a")).toBe(0);
});

it("all uppercase only", () => {


expect(countSpecialChars("ABC")).toBe(0);
});

it("all 26 letters special: abcde...ABCDE...", () => {


const lower = "abcdefghijklmnopqrstuvwxyz";
const upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
expect(countSpecialChars(lower + upper)).toBe(26);
});

it("interleaved where some letters qualify and some don't", () => {


expect(countSpecialChars("aAbB")).toBe(2);
expect(countSpecialChars("AaBb")).toBe(0);
});
});
[Link] Coding Challenges22

M-02. Check if Object Instance of a Class


Write a function that checks if a given value is an instance of a given class or superclass. An object is
an instance if it has access to that class's methods. Handle primitives and undefined gracefully.
🟢 Examples
Example 1:
Input: checkIfInstanceOf(new Date(), Date)
Output: true

Example 2:
Input: checkIfInstanceOf(new Dog(), Animal) // Dog extends Animal
Output: true

Example 3:
Input: checkIfInstanceOf(Date, Date)
Output: false

Example 4:
Input: checkIfInstanceOf(5, Number)
Output: true // primitive has Number methods

🟢 Sample Test Cases

Sample Test Cases — At a Glance


# Input / Setup Expected Output
1 Date instance of Date expect(checkIfInstanceOf(new Date(), Date)).toBe(true)

2 subclass is instance of superclass expect(checkIfInstanceOf(new Dog(),


Animal)).toBe(true)

3 constructor is not instance of itself expect(checkIfInstanceOf(Date, Date)).toBe(false)

4 primitive number is instance of expect(checkIfInstanceOf(5, Number)).toBe(true)


Number

import { describe, expect, it } from "vitest";


import { checkIfInstanceOf } from "./solutions/m02-instanceof";

describe("M-02 · Check instanceof Class", () => {


it("Date instance of Date", () => {
expect(checkIfInstanceOf(new Date(), Date)).toBe(true);
});

it("subclass is instance of superclass", () => {


class Animal {}
[Link] Coding Challenges23

class Dog extends Animal {}


expect(checkIfInstanceOf(new Dog(), Animal)).toBe(true);
});

it("constructor is not instance of itself", () => {


expect(checkIfInstanceOf(Date, Date)).toBe(false);
});

it("primitive number is instance of Number", () => {


expect(checkIfInstanceOf(5, Number)).toBe(true);
});
});

🟢 Hidden Test Cases

Hidden Test Cases — At a Glance


# Input / Setup Expected Output
1 undefined is not instance of expect(checkIfInstanceOf(undefined, Date)).toBe(false)
anything

2 null is not instance of Object expect(checkIfInstanceOf(null, Object)).toBe(false)

3 string primitive is instance of expect(checkIfInstanceOf("hello", String)).toBe(true)


String

4 deep inheritance chain expect(checkIfInstanceOf(new C(), A)).toBe(true)

describe("M-02 · Check instanceof Class — Hidden", () => {


it("undefined is not instance of anything", () => {
expect(checkIfInstanceOf(undefined, Date)).toBe(false);
});

it("null is not instance of Object", () => {


expect(checkIfInstanceOf(null, Object)).toBe(false);
});

it("string primitive is instance of String", () => {


expect(checkIfInstanceOf("hello", String)).toBe(true);
});

it("deep inheritance chain", () => {


class A {}
class B extends A {}
class C extends B {}
expect(checkIfInstanceOf(new C(), A)).toBe(true);
});
});

M-03. Cache with Time Limit


[Link] Coding Challenges24

Write a class with three methods: set(key, value, duration) stores a key with an expiry in ms (returns
true if key already existed and was un-expired, else false). get(key) returns the value or -1 if
expired/missing. count() returns the number of un-expired keys.
🟢 Examples
Example 1:
actions = ["TimeLimitedCache","set","get","count","get"]
values = [[], [1,42,100], [1], [], [1]]
delays = [0, 0, 50, 50, 150]
Output: [null, false, 42, 1, -1]

🟢 Constraints
• 0 <= key, value <= 10^9
• 0 <= duration <= 1000
• 1 <= [Link] <= 100
🟢 Sample Test Cases

Sample Test Cases — At a Glance


# Input / Setup Expected Output
1 set returns false for new key expect([Link](1, 42, 100)).toBe(false)
const cache = new
TimeLimitedCache();

2 get returns value for un-expired expect([Link](1)).toBe(42)


key
const cache = new
TimeLimitedCache();

3 get returns -1 after expiry expect([Link](1)).toBe(-1)


const cache = new
TimeLimitedCache();

4 count returns number of active expect([Link]()).toBe(2)


keys
const cache = new
TimeLimitedCache();

import { describe, expect, it } from "vitest";


import { TimeLimitedCache } from "./solutions/m03-cache";

describe("M-03 · Cache with Time Limit", () => {


it("set returns false for new key", () => {
const cache = new TimeLimitedCache();
expect([Link](1, 42, 100)).toBe(false);
});

it("get returns value for un-expired key", async () => {


const cache = new TimeLimitedCache();
[Link](1, 42, 200);
await new Promise(r => setTimeout(r, 50));
expect([Link](1)).toBe(42);
});

it("get returns -1 after expiry", async () => {


const cache = new TimeLimitedCache();
[Link] Coding Challenges25

[Link](1, 42, 50);


await new Promise(r => setTimeout(r, 100));
expect([Link](1)).toBe(-1);
});

it("count returns number of active keys", () => {


const cache = new TimeLimitedCache();
[Link](1, 10, 500);
[Link](2, 20, 500);
expect([Link]()).toBe(2);
});
});

🟢 Hidden Test Cases

Hidden Test Cases — At a Glance


# Input / Setup Expected Output
1 set returns true when overwriting expect([Link](1, 50, 300)).toBe(true)
un-expired key
const cache = new
TimeLimitedCache();

2 overwritten key has new value and expect([Link](1)).toBe(99)


duration
const cache = new
TimeLimitedCache();

3 count after expiry is 0 expect([Link]()).toBe(0)


const cache = new
TimeLimitedCache();

4 get on missing key returns -1 expect([Link](999)).toBe(-1)


const cache = new
TimeLimitedCache();

describe("M-03 · Cache with Time Limit — Hidden", () => {


it("set returns true when overwriting un-expired key", async () => {
const cache = new TimeLimitedCache();
[Link](1, 42, 200);
await new Promise(r => setTimeout(r, 40));
expect([Link](1, 50, 300)).toBe(true);
});

it("overwritten key has new value and duration", async () => {


const cache = new TimeLimitedCache();
[Link](1, 42, 50);
await new Promise(r => setTimeout(r, 40));
[Link](1, 99, 200);
await new Promise(r => setTimeout(r, 60));
expect([Link](1)).toBe(99);
});

it("count after expiry is 0", async () => {


const cache = new TimeLimitedCache();
[Link](1, 1, 50);
await new Promise(r => setTimeout(r, 100));
[Link] Coding Challenges26

expect([Link]()).toBe(0);
});

it("get on missing key returns -1", () => {


const cache = new TimeLimitedCache();
expect([Link](999)).toBe(-1);
});
});

M-04. Memoize
Given a function fn, return a memoized version that caches results. The same inputs should never
trigger a second call to fn. Support sum, fib, and factorial functions.
🟢 Examples
Example 1 (sum):
memoizedSum(2, 2) // 4 — calls sum
memoizedSum(2, 2) // 4 — cache hit
getCallCount() // 1

Example 2 (factorial):
memoFactorial(2) // 2
memoFactorial(3) // 6
memoFactorial(2) // 2 — cache hit
getCallCount() // 2

🟢 Constraints
• 0 <= a, b <= 10^5
• 1 <= n <= 10
🟢 Sample Test Cases

Sample Test Cases — At a Glance


# Input / Setup Expected Output
1 caches sum results — same args expect(memo(2, 2)).toBe(4)
not recomputed expect(memo(2, 2)).toBe(4)
let calls = 0; expect(calls).toBe(1)
const sum = (a: number, b:
number) => { calls++; return
a + b; };
const memo = memoize(sum);

2 treats (a,b) and (b,a) as distinct expect(calls).toBe(2)


cache entries
let calls = 0;
const sum = (a: number, b:
number) => { calls++; return
a + b; };
const memo = memoize(sum);

3 memoizes factorial expect(memo(3)).toBe(6)


[Link] Coding Challenges27

let calls = 0; expect(calls).toBe(1)


const fact = (n: number):
number => { calls++; return n
<= 1 ? 1 : n * fact(n-1); };
const memo = memoize(fact);

import { describe, expect, it } from "vitest";


import { memoize } from "./solutions/m04-memoize";

describe("M-04 · Memoize", () => {


it("caches sum results — same args not recomputed", () => {
let calls = 0;
const sum = (a: number, b: number) => { calls++; return a + b; };
const memo = memoize(sum);
expect(memo(2, 2)).toBe(4);
expect(memo(2, 2)).toBe(4);
expect(calls).toBe(1);
});

it("treats (a,b) and (b,a) as distinct cache entries", () => {


let calls = 0;
const sum = (a: number, b: number) => { calls++; return a + b; };
const memo = memoize(sum);
memo(3, 2); memo(2, 3);
expect(calls).toBe(2);
});

it("memoizes factorial", () => {


let calls = 0;
const fact = (n: number): number => { calls++; return n <= 1 ? 1 : n
* fact(n-1); };
const memo = memoize(fact);
expect(memo(3)).toBe(6);
memo(3);
expect(calls).toBe(1);
});
});

🟢 Hidden Test Cases

Hidden Test Cases — At a Glance


# Input / Setup Expected Output
1 caches result for fib(5) = 8 expect(calls).toBe(1)
let calls = 0;
const fib = (n: number):
number => { calls++; return
n<=1 ? n : fib(n-1)+fib(n-2);
};
const memo = memoize(fib);

2 zero sum is cached expect(memo(0, 0)).toBe(0)


let calls = 0; expect(calls).toBe(1)
const sum = (a: number, b:
number) => { calls++; return
a + b; };
const memo = memoize(sum);
[Link] Coding Challenges28

3 different functions have separate expect(add(3, 4)).toBe(7)


caches expect(mul(3, 4)).toBe(12)
const add = memoize((a:
number, b: number) => a + b);
const mul = memoize((a:
number, b: number) => a * b);

describe("M-04 · Memoize — Hidden", () => {


it("caches result for fib(5) = 8", () => {
let calls = 0;
const fib = (n: number): number => { calls++; return n<=1 ? n :
fib(n-1)+fib(n-2); };
const memo = memoize(fib);
memo(5);
expect(calls).toBe(1);
});

it("zero sum is cached", () => {


let calls = 0;
const sum = (a: number, b: number) => { calls++; return a + b; };
const memo = memoize(sum);
expect(memo(0, 0)).toBe(0);
memo(0, 0);
expect(calls).toBe(1);
});

it("different functions have separate caches", () => {


const add = memoize((a: number, b: number) => a + b);
const mul = memoize((a: number, b: number) => a * b);
expect(add(3, 4)).toBe(7);
expect(mul(3, 4)).toBe(12);
});
});

M-05. Snail Traversal


Enhance all arrays with a snail(rowsCount, colsCount) method that transforms a 1D array into a 2D
snail-order matrix. Invalid input (rowsCount * colsCount !== [Link]) returns [].
🟢 Examples
Example 1:
Input: [19,10,3,7,9,8,5,2,1,17,16,14,12,18,6,13,11,20,4,15]
rowsCount=5, colsCount=4
Output: [[19,17,16,15],[10,1,14,4],[3,2,12,20],[7,5,18,11],[9,8,6,13]]

Example 2:
Input: [1,2,3,4], rowsCount=1, colsCount=4
Output: [[1,2,3,4]]

Example 3:
[Link] Coding Challenges29

Input: [1,3], rowsCount=2, colsCount=2


Output: [] // invalid: 2*2 ≠ 2

🟢 Constraints
• 0 <= [Link] <= 250
• 1 <= rowsCount, colsCount <= 250
🟢 Sample Test Cases

Sample Test Cases — At a Glance


# Input / Setup Expected Output
1 produces correct 5x4 snail matrix expect([Link](5,
const nums = 4)[0]).toEqual([19, 17, 16,
[19,10,3,7,9,8,5,2,1,17,16,14,12,18,6,13,11,20,4,15]; 15])

2 single row returns same order expect([1, 2, 3, 4].snail(1,


4)).toEqual([[1, 2, 3, 4]])

3 returns [] for invalid dimensions expect([1, 3].snail(2,


2)).toEqual([])

4 1x1 matrix expect([42].snail(1,


1)).toEqual([[42]])

import { describe, expect, it } from "vitest";


import "./solutions/m05-snail"; // patches [Link]

describe("M-05 · Snail Traversal", () => {


it("produces correct 5x4 snail matrix", () => {
const nums = [19,10,3,7,9,8,5,2,1,17,16,14,12,18,6,13,11,20,4,15];
expect([Link](5, 4)[0]).toEqual([19, 17, 16, 15]);
});

it("single row returns same order", () => {


expect([1, 2, 3, 4].snail(1, 4)).toEqual([[1, 2, 3, 4]]);
});

it("returns [] for invalid dimensions", () => {


expect([1, 3].snail(2, 2)).toEqual([]);
});

it("1x1 matrix", () => {


expect([42].snail(1, 1)).toEqual([[42]]);
});
});

🟢 Hidden Test Cases

Hidden Test Cases — At a Glance


# Input / Setup Expected Output
1 single column (2x1) expect([1, 2].snail(2, 1)).toEqual([[1], [2]])

2 empty array with 1x0 returns [] expect([].snail(1, 0)).toEqual([])


[Link] Coding Challenges30

3 alternating column directions are expect(result).toEqual([[1, 4], [2, 3]])


correct
const result = [1, 2, 3,
4].snail(2, 2);

4 rowsCount * colsCount exactly expect([Link]).toBe(3)


equals length expect(result[0].length).toBe(3)
const arr = [Link]({
length: 9 }, (_, i) => i +
1);
const result = [Link](3,
3);

describe("M-05 · Snail Traversal — Hidden", () => {


it("single column (2x1)", () => {
expect([1, 2].snail(2, 1)).toEqual([[1], [2]]);
});

it("empty array with 1x0 returns []", () => {


expect([].snail(1, 0)).toEqual([]);
});

it("alternating column directions are correct", () => {


const result = [1, 2, 3, 4].snail(2, 2);
// col0 top-down: [1,2], col1 bottom-up: [4,3]
expect(result).toEqual([[1, 4], [2, 3]]);
});

it("rowsCount * colsCount exactly equals length", () => {


const arr = [Link]({ length: 9 }, (_, i) => i + 1);
const result = [Link](3, 3);
expect([Link]).toBe(3);
expect(result[0].length).toBe(3);
});
});

M-06. Flatten Deeply Nested Array


Given a multi-dimensional array arr and a depth n, return a flattened version. Only flatten subarrays
whose nesting depth is less than n. Solve without [Link].
🟢 Examples
Example 1 (n=0, no change):
Input: [1,2,[4,5],[7,[9,10]]], n=0
Output: [1,2,[4,5],[7,[9,10]]]

Example 2 (n=1, one level):


Input: [1,2,[4,5],[7,[9,10]]], n=1
Output: [1,2,4,5,7,[9,10]]
[Link] Coding Challenges31

Example 3 (n=2, two levels):


Input: [[1,2],[3,[4,[5]]]], n=2
Output: [1,2,3,4,[5]]

🟢 Constraints
• 0 <= count of numbers in arr <= 10^5
• 0 <= n <= 1000
🟢 Sample Test Cases

Sample Test Cases — At a Glance


# Input / Setup Expected Output
1 n=0 returns unchanged array expect(flat([1,[2,[3]]], 0)).toEqual([1,[2,[3]]])

2 n=1 flattens one level expect(flat([1,2,[4,5],[7,[9,10]]],


1)).toEqual([1,2,4,5,7,[9,10]])

3 n=2 flattens two levels expect(flat([[1,2],[3,[4,[5]]]],


2)).toEqual([1,2,3,4,[5]])

4 empty array returns empty array expect(flat([], 5)).toEqual([])

import { describe, expect, it } from "vitest";


import { flat } from "./solutions/m06-flatten";

describe("M-06 · Flatten Deeply Nested Array", () => {


it("n=0 returns unchanged array", () => {
expect(flat([1,[2,[3]]], 0)).toEqual([1,[2,[3]]]);
});

it("n=1 flattens one level", () => {


expect(flat([1,2,[4,5],[7,[9,10]]], 1)).toEqual([1,2,4,5,7,[9,10]]);
});

it("n=2 flattens two levels", () => {


expect(flat([[1,2],[3,[4,[5]]]], 2)).toEqual([1,2,3,4,[5]]);
});

it("empty array returns empty array", () => {


expect(flat([], 5)).toEqual([]);
});
});

🟢 Hidden Test Cases

Hidden Test Cases — At a Glance


# Input / Setup Expected Output
1 does not use [Link] —
const original =
[Link];

2 n=1000 fully flattens deeply nested expect(flat(deep, 1000)).toEqual([1])


array
const deep = [[[[[1]]]]];
[Link] Coding Challenges32

3 already flat array stays flat expect(flat([1,2,3], 5)).toEqual([1,2,3])

4 mixed types preserved expect(flat([1,[2,3],4], 1)).toEqual([1,2,3,4])

describe("M-06 · Flatten Deeply Nested Array — Hidden", () => {


it("does not use [Link]", () => {
const original = [Link];
[Link] = () => { throw new Error("forbidden"); };
expect(() => flat([1,[2]], 1)).[Link]();
[Link] = original;
});

it("n=1000 fully flattens deeply nested array", () => {


const deep = [[[[[1]]]]];
expect(flat(deep, 1000)).toEqual([1]);
});

it("already flat array stays flat", () => {


expect(flat([1,2,3], 5)).toEqual([1,2,3]);
});

it("mixed types preserved", () => {


expect(flat([1,[2,3],4], 1)).toEqual([1,2,3,4]);
});
});

M-07. Debounce
Given a function fn and a time t in ms, return a debounced version. A debounced function delays
execution by t ms and cancels if called again within that window. Solve without lodash's _.debounce.
🟢 Examples
Example 1 (t=50):
calls = [{t:50,inputs:[1]}, {t:75,inputs:[2]}]
Output: [{t:125, inputs:[2]}] // call at 50ms cancelled by 75ms call

Example 2 (t=20):
calls = [{t:50,inputs:[1]}, {t:100,inputs:[2]}]
Output: [{t:70, inputs:[1]}, {t:120, inputs:[2]}] // both execute

🟢 Constraints
• 0 <= t <= 1000
• 1 <= [Link] <= 10
🟢 Sample Test Cases

Sample Test Cases — At a Glance


# Input / Setup Expected Output
[Link] Coding Challenges33

1 cancels first call when second expect(results).toEqual([2])


arrives within window
const results: number[] = [];
const fn = debounce((n:
number) => [Link](n),
50);

2 both calls execute when spaced expect(results).toEqual([1, 2])


apart
const results: number[] = [];
const fn = debounce((n:
number) => [Link](n),
20);

3 t=0 executes immediately (next expect(results).toEqual([42])


tick)
const results: number[] = [];
const fn = debounce((n:
number) => [Link](n),
0);

import { describe, expect, it } from "vitest";


import { debounce } from "./solutions/m07-debounce";

describe("M-07 · Debounce", () => {


it("cancels first call when second arrives within window", async () =>
{
const results: number[] = [];
const fn = debounce((n: number) => [Link](n), 50);
fn(1);
await new Promise(r => setTimeout(r, 25));
fn(2);
await new Promise(r => setTimeout(r, 100));
expect(results).toEqual([2]);
});

it("both calls execute when spaced apart", async () => {


const results: number[] = [];
const fn = debounce((n: number) => [Link](n), 20);
fn(1);
await new Promise(r => setTimeout(r, 50));
fn(2);
await new Promise(r => setTimeout(r, 50));
expect(results).toEqual([1, 2]);
});

it("t=0 executes immediately (next tick)", async () => {


const results: number[] = [];
const fn = debounce((n: number) => [Link](n), 0);
fn(42);
await new Promise(r => setTimeout(r, 10));
expect(results).toEqual([42]);
});
});

🟢 Hidden Test Cases

Hidden Test Cases — At a Glance


[Link] Coding Challenges34

# Input / Setup Expected Output


1 passes all arguments to expect(captured).toEqual([1, 2])
debounced call
let captured: number[] = [];
const fn = debounce((...args:
number[]) => { captured =
args; }, 30);

2 third call cancels second, keeps expect(results).toEqual([3])


third
const results: number[] = [];
const fn = debounce((n:
number) => [Link](n),
50);

3 single call always executes expect(called).toBe(true)


let called = false;
const fn = debounce(() => {
called = true; }, 50);

describe("M-07 · Debounce — Hidden", () => {


it("passes all arguments to debounced call", async () => {
let captured: number[] = [];
const fn = debounce((...args: number[]) => { captured = args; }, 30);
fn(1, 2);
await new Promise(r => setTimeout(r, 60));
expect(captured).toEqual([1, 2]);
});

it("third call cancels second, keeps third", async () => {


const results: number[] = [];
const fn = debounce((n: number) => [Link](n), 50);
fn(1);
await new Promise(r => setTimeout(r, 30));
fn(2);
await new Promise(r => setTimeout(r, 30));
fn(3);
await new Promise(r => setTimeout(r, 100));
expect(results).toEqual([3]);
});

it("single call always executes", async () => {


let called = false;
const fn = debounce(() => { called = true; }, 50);
fn();
await new Promise(r => setTimeout(r, 80));
expect(called).toBe(true);
});
});

M-08. Group By
Enhance all arrays with a groupBy(fn) method that returns an object where each key is fn(arr[i]) and
each value is the array of elements that produced that key. Solve without lodash's _.groupBy.
🟢 Examples
[Link] Coding Challenges35

Example 1:
Input: [{id:"1"},{id:"1"},{id:"2"}], fn=item=>[Link]
Output: {"1":[{id:"1"},{id:"1"}],"2":[{id:"2"}]}

Example 2:
Input: [1,2,3,4,5,6,7,8,9,10], fn=n=>String(n>5)
Output: {"true":[6,7,8,9,10],"false":[1,2,3,4,5]}

🟢 Constraints
• 0 <= [Link] <= 10^5
• fn returns a string
🟢 Sample Test Cases

Sample Test Cases — At a Glance


# Input / Setup Expected Output
1 groups by id property expect(result["1"].length).toBe(2)
const arr = expect(result["2"].length).toBe(1)
[{id:"1"},{id:"1"},{id:"2"}];
const result =
[Link]((item: any) =>
[Link]);

2 groups numbers by >5 boolean expect(result["true"]).toEqual([6,7,8,9,10])


const arr = expect(result["false"]).toEqual([1,2,3,4,5])
[1,2,3,4,5,6,7,8,9,10];
const result =
[Link]((n: number) =>
String(n > 5));

3 empty array returns empty object expect([].groupBy((n: any) => n)).toEqual({})

import { describe, expect, it } from "vitest";


import "./solutions/m08-groupby";

describe("M-08 · Group By", () => {


it("groups by id property", () => {
const arr = [{id:"1"},{id:"1"},{id:"2"}];
const result = [Link]((item: any) => [Link]);
expect(result["1"].length).toBe(2);
expect(result["2"].length).toBe(1);
});

it("groups numbers by >5 boolean", () => {


const arr = [1,2,3,4,5,6,7,8,9,10];
const result = [Link]((n: number) => String(n > 5));
expect(result["true"]).toEqual([6,7,8,9,10]);
expect(result["false"]).toEqual([1,2,3,4,5]);
});

it("empty array returns empty object", () => {


expect([].groupBy((n: any) => n)).toEqual({});
});
});
[Link] Coding Challenges36

🟢 Hidden Test Cases

Hidden Test Cases — At a Glance


# Input / Setup Expected Output
1 all elements in same group expect(result["same"]).toEqual([1,2,3])
const result =
[1,2,3].groupBy(() => "same");

2 each element in its own group expect([Link](result).length).toBe(3)


const result =
[1,2,3].groupBy((n: number) =>
String(n));

3 preserves order within groups expect(result["1"]).toEqual([1,1])


const result = expect(result["3"]).toEqual([3,3])
[3,1,2,1,3].groupBy((n: number)
=> String(n));

4 groups by first element of sub- expect(result["1"].length).toBe(2)


arrays expect(result["2"].length).toBe(1)
const result =
[[1,2],[1,3],[2,4]].groupBy((a:
number[]) => String(a[0]));

describe("M-08 · Group By — Hidden", () => {


it("all elements in same group", () => {
const result = [1,2,3].groupBy(() => "same");
expect(result["same"]).toEqual([1,2,3]);
});

it("each element in its own group", () => {


const result = [1,2,3].groupBy((n: number) => String(n));
expect([Link](result).length).toBe(3);
});

it("preserves order within groups", () => {


const result = [3,1,2,1,3].groupBy((n: number) => String(n));
expect(result["1"]).toEqual([1,1]);
expect(result["3"]).toEqual([3,3]);
});

it("groups by first element of sub-arrays", () => {


const result = [[1,2],[1,3],[2,4]].groupBy((a: number[]) =>
String(a[0]));
expect(result["1"].length).toBe(2);
expect(result["2"].length).toBe(1);
});
});

M-09. Promise Time Limit


Given an async function fn and a time t in ms, return a time-limited version. If fn completes within t ms,
resolve with the result. Otherwise reject with "Time Limit Exceeded".
[Link] Coding Challenges37

🟢 Examples
Example 1 (timeout):
fn resolves in 100ms, t=50ms
Output: {"rejected":"Time Limit Exceeded","time":50}

Example 2 (success):
fn resolves in 100ms, t=150ms
Output: {"resolved":25,"time":100}

🟢 Constraints
• 0 <= [Link] <= 10
• 0 <= t <= 1000
• fn returns a Promise
🟢 Sample Test Cases

Sample Test Cases — At a Glance


# Input / Setup Expected Output
1 rejects with Time Limit Exceeded await expect(limited(5)).[Link]("Time Limit
when fn too slow Exceeded")
const fn = async (n: number)
=> {
const limited = timeLimit(fn,
50);

2 resolves normally when fn await expect(limited(5)).[Link](25)


completes in time
const fn = async (n: number)
=> {
const limited = timeLimit(fn,
150);

3 propagates thrown errors await expect(limited()).[Link]("Error")


const fn = async () => {
throw "Error"; };
const limited = timeLimit(fn,
1000);

import { describe, expect, it } from "vitest";


import { timeLimit } from "./solutions/m09-time-limit";

describe("M-09 · Promise Time Limit", () => {


it("rejects with Time Limit Exceeded when fn too slow", async () => {
const fn = async (n: number) => {
await new Promise(r => setTimeout(r, 100));
return n * n;
};
const limited = timeLimit(fn, 50);
await expect(limited(5)).[Link]("Time Limit Exceeded");
});

it("resolves normally when fn completes in time", async () => {


const fn = async (n: number) => {
await new Promise(r => setTimeout(r, 100));
[Link] Coding Challenges38

return n * n;
};
const limited = timeLimit(fn, 150);
await expect(limited(5)).[Link](25);
});

it("propagates thrown errors", async () => {


const fn = async () => { throw "Error"; };
const limited = timeLimit(fn, 1000);
await expect(limited()).[Link]("Error");
});
});

🟢 Hidden Test Cases

Hidden Test Cases — At a Glance


# Input / Setup Expected Output
1 resolves with sum of two args await expect(timeLimit(fn, 150)(5,
const fn = async (a: number, 10)).[Link](15)
b: number) => {

2 t=0 always times out unless fn await expect(timeLimit(fn, 0)()).[Link]("Time


resolves synchronously Limit Exceeded")
const fn = async () => {
await new Promise(r =>
setTimeout(r, 10)); return 1;
};

3 returns correct resolved value on await expect(timeLimit(fn, 200)()).[Link](99)


boundary
const fn = async () => {
await new Promise(r =>
setTimeout(r, 50)); return
99; };

describe("M-09 · Promise Time Limit — Hidden", () => {


it("resolves with sum of two args", async () => {
const fn = async (a: number, b: number) => {
await new Promise(r => setTimeout(r, 120));
return a + b;
};
await expect(timeLimit(fn, 150)(5, 10)).[Link](15);
});

it("t=0 always times out unless fn resolves synchronously", async () =>


{
const fn = async () => { await new Promise(r => setTimeout(r, 10));
return 1; };
await expect(timeLimit(fn, 0)()).[Link]("Time Limit Exceeded");
});

it("returns correct resolved value on boundary", async () => {


const fn = async () => { await new Promise(r => setTimeout(r, 50));
return 99; };
await expect(timeLimit(fn, 200)()).[Link](99);
});
[Link] Coding Challenges39

});

M-10. Nested Array Generator


Given a multi-dimensional array of integers, return a generator object that yields integers in inorder
traversal (left to right, recursively into sub-arrays).
🟢 Examples
Example 1:
Input: arr = [[[6]], [1,3], []]
Output: [6, 1, 3]

Example 2:
Input: arr = []
Output: []

🟢 Constraints
• 0 <= [Link](Infinity).length <= 10^5
• 0 <= each integer <= 10^5
• maxNestingDepth <= 10^5
🟢 Sample Test Cases

Sample Test Cases — At a Glance


# Input / Setup Expected Output
1 yields integers in inorder traversal expect([...{ [[Link]]: () => gen
const gen = }]).toEqual([6, 1, 3])
inorderTraversal([[[6]], [1,
3], []]);

2 empty array yields nothing expect([Link]().done).toBe(true)


const gen =
inorderTraversal([]);

3 flat array yields all elements in expect([Link]().value).toBe(1)


order expect([Link]().value).toBe(2)
const gen = expect([Link]().value).toBe(3)
inorderTraversal([1, 2, 3]);

import { describe, expect, it } from "vitest";


import { inorderTraversal } from "./solutions/m10-nested-generator";

describe("M-10 · Nested Array Generator", () => {


it("yields integers in inorder traversal", () => {
const gen = inorderTraversal([[[6]], [1, 3], []]);
expect([...{ [[Link]]: () => gen }]).toEqual([6, 1, 3]);
});

it("empty array yields nothing", () => {


[Link] Coding Challenges40

const gen = inorderTraversal([]);


expect([Link]().done).toBe(true);
});

it("flat array yields all elements in order", () => {


const gen = inorderTraversal([1, 2, 3]);
expect([Link]().value).toBe(1);
expect([Link]().value).toBe(2);
expect([Link]().value).toBe(3);
});
});

🟢 Hidden Test Cases

Hidden Test Cases — At a Glance


# Input / Setup Expected Output
1 deeply nested single value expect([Link]().value).toBe(42)
const gen = expect([Link]().done).toBe(true)
inorderTraversal([[[[42]]]]);

2 empty sub-arrays are skipped expect([Link]().value).toBe(1)


const gen = expect([Link]().value).toBe(2)
inorderTraversal([[], [1], expect([Link]().done).toBe(true)
[], [2], []]);

3 mix of integers and nested arrays expect(values).toEqual([1, 2, 3, 4])


const values = [];
const gen =
inorderTraversal([1, [2,
[3]], 4]);

describe("M-10 · Nested Array Generator — Hidden", () => {


it("deeply nested single value", () => {
const gen = inorderTraversal([[[[42]]]]);
expect([Link]().value).toBe(42);
expect([Link]().done).toBe(true);
});

it("empty sub-arrays are skipped", () => {


const gen = inorderTraversal([[], [1], [], [2], []]);
expect([Link]().value).toBe(1);
expect([Link]().value).toBe(2);
expect([Link]().done).toBe(true);
});

it("mix of integers and nested arrays", () => {


const values = [];
const gen = inorderTraversal([1, [2, [3]], 4]);
for (const v of gen) [Link](v);
expect(values).toEqual([1, 2, 3, 4]);
});
});
[Link] Coding Challenges41

🟢 HARD LEVEL

H-01. Bowling
Write code to keep track of the score of a bowling game. Implement roll(pins) and score() methods
following proper bowling scoring rules including strikes, spares, and the 10th-frame special case.
🟢 Scoring Rules
Open frame: score = pins knocked down
Spare: 10 + next 1 throw
Strike: 10 + next 2 throws
10th frame: earn 1 or 2 fill balls; total = all pins knocked in that frame
🟢 Example
Frame 1: X (strike) → 10 + 5 + 5 = 20
Frame 2: 5/ (spare) → 5 + 5 + 9 = 19
Frame 3: 90 (open) → 9
Running total: 48

🟢 Sample Test Cases

Sample Test Cases — At a Glance


# Input / Setup Expected Output
1 gutter game scores 0 expect([Link]()).toBe(0)
const game = new
BowlingGame();

2 all ones scores 20 expect([Link]()).toBe(20)


const game = new
BowlingGame();

3 perfect game scores 300 expect([Link]()).toBe(300)


const game = new
BowlingGame();

4 all spares scores 150 expect([Link]()).toBe(150)


const game = new
BowlingGame();

import { describe, expect, it } from "vitest";


import { BowlingGame } from "./solutions/h01-bowling";

describe("H-01 · Bowling", () => {


const rollMany = (game: BowlingGame, pins: number, count: number) => {
for (let i = 0; i < count; i++) [Link](pins);
};

it("gutter game scores 0", () => {


const game = new BowlingGame();
rollMany(game, 0, 20);
expect([Link]()).toBe(0);
});

it("all ones scores 20", () => {


const game = new BowlingGame();
rollMany(game, 1, 20);
[Link] Coding Challenges42

expect([Link]()).toBe(20);
});

it("perfect game scores 300", () => {


const game = new BowlingGame();
rollMany(game, 10, 12);
expect([Link]()).toBe(300);
});

it("all spares scores 150", () => {


const game = new BowlingGame();
rollMany(game, 5, 21);
expect([Link]()).toBe(150);
});
});

🟢 Hidden Test Cases

Hidden Test Cases — At a Glance


# Input / Setup Expected Output
1 strike followed by spare in 10th expect([Link]()).toBe(20)
frame
const game = new
BowlingGame();

2 10th frame three strikes expect([Link]()).toBe(30)


const game = new
BowlingGame();

3 one strike in otherwise open game expect([Link]()).toBe(16 + 54); // 10+3+3 + 18*3


const game = new
BowlingGame();

4 spare in last frame earns one fill expect([Link]()).toBe(15)


ball
const game = new
BowlingGame();

describe("H-01 · Bowling — Hidden", () => {


const rollMany = (game: BowlingGame, pins: number, count: number) => {
for (let i = 0; i < count; i++) [Link](pins);
};

it("strike followed by spare in 10th frame", () => {


const game = new BowlingGame();
rollMany(game, 0, 18);
[Link](10); [Link](3); [Link](7); // 10th: X, 3/
expect([Link]()).toBe(20);
});

it("10th frame three strikes", () => {


const game = new BowlingGame();
rollMany(game, 0, 18);
[Link](10); [Link](10); [Link](10);
expect([Link]()).toBe(30);
});
[Link] Coding Challenges43

it("one strike in otherwise open game", () => {


const game = new BowlingGame();
[Link](10);
rollMany(game, 3, 18);
expect([Link]()).toBe(16 + 54); // 10+3+3 + 18*3
});

it("spare in last frame earns one fill ball", () => {


const game = new BowlingGame();
rollMany(game, 0, 18);
[Link](7); [Link](3); [Link](5);
expect([Link]()).toBe(15);
});
});

H-02. Forth Evaluator


Implement an evaluator for a subset of Forth. Support arithmetic (+, -, *, /), stack ops (DUP, DROP,
SWAP, OVER), and custom word definitions (: word-name definition ;). Words are case-insensitive.
🟢 Examples
1 2 + → stack: [3]
3 DUP + . → 6
: double 2 * ; // define 'double'
5 double . → 10
1 2 SWAP . . → 1 2

🟢 Sample Test Cases

Sample Test Cases — At a Glance


# Input / Setup Expected Output
1 addition expect([Link]).toEqual([3])
const f = new Forth();

2 DUP duplicates top of stack expect([Link]).toEqual([3, 3])


const f = new Forth();

3 SWAP swaps top two elements expect([Link]).toEqual([2, 1])


const f = new Forth();

4 custom word definition expect([Link]).toEqual([10])


const f = new Forth();

import { describe, expect, it } from "vitest";


import { Forth } from "./solutions/h02-forth";

describe("H-02 · Forth Evaluator", () => {


it("addition", () => {
const f = new Forth();
[Link]("1 2 +");
expect([Link]).toEqual([3]);
[Link] Coding Challenges44

});

it("DUP duplicates top of stack", () => {


const f = new Forth();
[Link]("3 DUP");
expect([Link]).toEqual([3, 3]);
});

it("SWAP swaps top two elements", () => {


const f = new Forth();
[Link]("1 2 SWAP");
expect([Link]).toEqual([2, 1]);
});

it("custom word definition", () => {


const f = new Forth();
[Link](": double 2 * ;");
[Link]("5 double");
expect([Link]).toEqual([10]);
});
});

🟢 Hidden Test Cases

Hidden Test Cases — At a Glance


# Input / Setup Expected Output
1 integer division truncates toward expect([Link]).toEqual([3])
zero
const f = new Forth();

2 OVER copies second element to expect([Link]).toEqual([1, 2, 1])


top
const f = new Forth();

3 DROP removes top element expect([Link]).toEqual([1])


const f = new Forth();

4 redefining built-in word in user expect([Link]).toBe(3)


definition
const f = new Forth();

5 words are case-insensitive expect([Link]).toEqual([3, 3, 3, 3])


const f = new Forth();

describe("H-02 · Forth Evaluator — Hidden", () => {


it("integer division truncates toward zero", () => {
const f = new Forth();
[Link]("7 2 /");
expect([Link]).toEqual([3]);
});

it("OVER copies second element to top", () => {


const f = new Forth();
[Link]("1 2 OVER");
expect([Link]).toEqual([1, 2, 1]);
});
[Link] Coding Challenges45

it("DROP removes top element", () => {


const f = new Forth();
[Link]("1 2 DROP");
expect([Link]).toEqual([1]);
});

it("redefining built-in word in user definition", () => {


const f = new Forth();
[Link](": dup dup dup ;");
[Link]("1 dup");
expect([Link]).toBe(3);
});

it("words are case-insensitive", () => {


const f = new Forth();
[Link]("3 dup DUP Dup");
expect([Link]).toEqual([3, 3, 3, 3]);
});
});

H-03. Circular Buffer


Implement a circular (ring) buffer with a fixed capacity. Support read, write, overwrite, and clear. Raise
errors when reading from empty or writing to full buffer (unless using force-write/overwrite).
🟢 Operations
read() — removes and returns oldest element; throws if empty
write(value) — adds element; throws if full
overwrite(value) — force-writes, replacing oldest if full
clear() — empties the buffer
🟢 Sample Test Cases

Sample Test Cases — At a Glance


# Input / Setup Expected Output
1 reads written values in FIFO order expect([Link]()).toBe(1)
const buf = new expect([Link]()).toBe(2)
CircularBuffer(3);

2 throws on write to full buffer —


const buf = new
CircularBuffer(2);

3 throws on read from empty buffer —


const buf = new
CircularBuffer(3);

4 overwrite replaces oldest element expect([Link]()).toBe(2)


when full
const buf = new
CircularBuffer(3);
[Link] Coding Challenges46

import { describe, expect, it } from "vitest";


import { CircularBuffer } from "./solutions/h03-circular-buffer";

describe("H-03 · Circular Buffer", () => {


it("reads written values in FIFO order", () => {
const buf = new CircularBuffer(3);
[Link](1); [Link](2); [Link](3);
expect([Link]()).toBe(1);
expect([Link]()).toBe(2);
});

it("throws on write to full buffer", () => {


const buf = new CircularBuffer(2);
[Link](1); [Link](2);
expect(() => [Link](3)).toThrow();
});

it("throws on read from empty buffer", () => {


const buf = new CircularBuffer(3);
expect(() => [Link]()).toThrow();
});

it("overwrite replaces oldest element when full", () => {


const buf = new CircularBuffer(3);
[Link](1); [Link](2); [Link](3);
[Link](4);
expect([Link]()).toBe(2);
});
});

🟢 Hidden Test Cases

Hidden Test Cases — At a Glance


# Input / Setup Expected Output
1 clear makes buffer empty —
const buf = new
CircularBuffer(3);

2 can write again after read frees expect([Link]()).toBe(2)


space expect([Link]()).toBe(3)
const buf = new
CircularBuffer(2);

3 consecutive overwrites maintain expect([Link]()).toBe(3)


correct order expect([Link]()).toBe(4)
const buf = new expect([Link]()).toBe(5)
CircularBuffer(3);

4 overwrite on non-full buffer acts expect([Link]()).toBe(1)


like write expect([Link]()).toBe(2)
const buf = new
CircularBuffer(3);

describe("H-03 · Circular Buffer — Hidden", () => {


it("clear makes buffer empty", () => {
const buf = new CircularBuffer(3);
[Link] Coding Challenges47

[Link](1); [Link](2);
[Link]();
expect(() => [Link]()).toThrow();
});

it("can write again after read frees space", () => {


const buf = new CircularBuffer(2);
[Link](1); [Link](2);
[Link]();
[Link](3);
expect([Link]()).toBe(2);
expect([Link]()).toBe(3);
});

it("consecutive overwrites maintain correct order", () => {


const buf = new CircularBuffer(3);
[Link](1); [Link](2); [Link](3);
[Link](4); [Link](5);
expect([Link]()).toBe(3);
expect([Link]()).toBe(4);
expect([Link]()).toBe(5);
});

it("overwrite on non-full buffer acts like write", () => {


const buf = new CircularBuffer(3);
[Link](1);
[Link](2);
expect([Link]()).toBe(1);
expect([Link]()).toBe(2);
});
});

H-04. Simple Linked List


Given a range of numbers (song IDs), create a singly linked list. Implement the ability to reverse the list
to play songs in the opposite order. Each node contains data and a pointer to the next node.
🟢 Sample Test Cases

Sample Test Cases — At a Glance


# Input / Setup Expected Output
1 creates a list from a range expect([Link]?.value).toBe(1)
const list = new
LinkedList([1, 2, 3]);

2 reverses the list expect([Link]?.value).toBe(3)


const list = new
LinkedList([1, 2, 3]);
const reversed =
[Link]();

3 single element list reverses to expect([Link]().head?.value).toBe(1)


itself
[Link] Coding Challenges48

const list = new


LinkedList([1]);

4 toArray converts list back to array expect([Link]()).toEqual([1, 2, 3, 4, 5])


const list = new
LinkedList([1, 2, 3, 4, 5]);

import { describe, expect, it } from "vitest";


import { LinkedList, Node } from "./solutions/h04-linked-list";

describe("H-04 · Simple Linked List", () => {


it("creates a list from a range", () => {
const list = new LinkedList([1, 2, 3]);
expect([Link]?.value).toBe(1);
});

it("reverses the list", () => {


const list = new LinkedList([1, 2, 3]);
const reversed = [Link]();
expect([Link]?.value).toBe(3);
});

it("single element list reverses to itself", () => {


const list = new LinkedList([1]);
expect([Link]().head?.value).toBe(1);
});

it("toArray converts list back to array", () => {


const list = new LinkedList([1, 2, 3, 4, 5]);
expect([Link]()).toEqual([1, 2, 3, 4, 5]);
});
});

🟢 Hidden Test Cases

Hidden Test Cases — At a Glance


# Input / Setup Expected Output
1 empty list reverses to expect([Link]().head).toBeNull()
empty list
const list = new
LinkedList([]);

2 reverse twice restores expect([Link]().reverse().toArray()).toEqual([1,2,3,4,5])


original order
const list = new
LinkedList([1, 2, 3,
4, 5]);

3 list length is correct after expect([Link]).toBe(3)


creation
const list = new
LinkedList([10, 20,
30]);

4 reversed list has correct expect([Link]().length).toBe(4)


length
[Link] Coding Challenges49

const list = new


LinkedList([1, 2, 3,
4]);

describe("H-04 · Simple Linked List — Hidden", () => {


it("empty list reverses to empty list", () => {
const list = new LinkedList([]);
expect([Link]().head).toBeNull();
});

it("reverse twice restores original order", () => {


const list = new LinkedList([1, 2, 3, 4, 5]);
expect([Link]().reverse().toArray()).toEqual([1,2,3,4,5]);
});

it("list length is correct after creation", () => {


const list = new LinkedList([10, 20, 30]);
expect([Link]).toBe(3);
});

it("reversed list has correct length", () => {


const list = new LinkedList([1, 2, 3, 4]);
expect([Link]().length).toBe(4);
});
});

H-05. Word Search


Given a square grid of letters and a list of words, return the location of the first and last letter of each
word. Words can be hidden horizontally (L→R, R→L), vertically, and diagonally.
🟢 Example Grid
jefblpepre
camdcimgtc
oivokprjsm
pbwasqroua
rixilelhrs
wolcqlirpc
screeaumgr
alxhpburyi
jalaycalmp
clojurermt

🟢 Sample Test Cases

Sample Test Cases — At a Glance


# Input / Setup Expected Output
1 finds a word hidden left-to-right —
const result =
wordSearch(GRID,
["clojure"]);
[Link] Coding Challenges50

2 returns start and end positions expect([Link](start)).toBe(true)


const result = expect([Link](end)).toBe(true)
wordSearch(GRID,
["clojure"]);
const { start, end } =
result["clojure"];

3 returns undefined for word not in expect(result["zzzzz"]).toBeUndefined()


grid
const result =
wordSearch(GRID, ["zzzzz"]);

import { describe, expect, it } from "vitest";


import { wordSearch } from "./solutions/h05-word-search";

const GRID = [
"jefblpepre", "camdcimgtc", "oivokprjsm", "pbwasqroua",
"rixilelhrs", "wolcqlirpc", "screeaumgr", "alxhpburyi",
"jalaycalmp", "clojurermt"
].map(row => [Link](""));

describe("H-05 · Word Search", () => {


it("finds a word hidden left-to-right", () => {
const result = wordSearch(GRID, ["clojure"]);
expect(result["clojure"]).toBeDefined();
});

it("returns start and end positions", () => {


const result = wordSearch(GRID, ["clojure"]);
const { start, end } = result["clojure"];
expect([Link](start)).toBe(true);
expect([Link](end)).toBe(true);
});

it("returns undefined for word not in grid", () => {


const result = wordSearch(GRID, ["zzzzz"]);
expect(result["zzzzz"]).toBeUndefined();
});
});

🟢 Hidden Test Cases

Hidden Test Cases — At a Glance


# Input / Setup Expected Output
1 finds word hidden right-to-left —
const grid =
[["a","b","c"],["d","e","f"],["g","h","i"]];
const result = wordSearch(grid, ["cba"]);

2 finds word hidden vertically —


const grid =
[["a","x"],["b","x"],["c","x"]];
const result = wordSearch(grid, ["abc"]);

3 finds word hidden diagonally —


const grid =
[["a","x","x"],["x","b","x"],["x","x","c"]];
[Link] Coding Challenges51

const result = wordSearch(grid, ["abc"]);

4 handles multiple words in one call expect(result["zzzzz"]).toBeUndefined()


const result = wordSearch(GRID, ["clojure",
"zzzzz"]);

describe("H-05 · Word Search — Hidden", () => {


it("finds word hidden right-to-left", () => {
const grid = [["a","b","c"],["d","e","f"],["g","h","i"]];
// "cba" right-to-left in row 0
const result = wordSearch(grid, ["cba"]);
expect(result["cba"]).toBeDefined();
});

it("finds word hidden vertically", () => {


const grid = [["a","x"],["b","x"],["c","x"]];
const result = wordSearch(grid, ["abc"]);
expect(result["abc"]).toBeDefined();
});

it("finds word hidden diagonally", () => {


const grid = [["a","x","x"],["x","b","x"],["x","x","c"]];
const result = wordSearch(grid, ["abc"]);
expect(result["abc"]).toBeDefined();
});

it("handles multiple words in one call", () => {


const result = wordSearch(GRID, ["clojure", "zzzzz"]);
expect(result["clojure"]).toBeDefined();
expect(result["zzzzz"]).toBeUndefined();
});
});

H-06. Crypto Square


Implement the square code cipher. Normalize input (lowercase, remove spaces/punctuation), arrange
into a near-square rectangle, read column-by-column to produce the ciphertext, then output as space-
separated chunks.
🟢 Example
Input: "If man was meant to stay on the ground, god would have given us
roots."
Normalized: "ifmanwasmeanttostayonthegroundgodwouldhavegivenusroots" (54
chars)
Rectangle: 7 rows × 8 cols
Output: "imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghn sseoau "

🟢 Sample Test Cases

Sample Test Cases — At a Glance


# Input / Setup Expected Output
[Link] Coding Challenges52

1 encodes classic example expect(cryptoSquare(msg)).toBe(


const msg = "If man was meant
to stay on the ground, god
would have given us roots.";

2 empty string returns empty string expect(cryptoSquare("")).toBe("")

3 single character returns that expect(cryptoSquare("A")).toBe("a")


character

4 strips spaces and punctuation expect(cryptoSquare("Hello,


before encoding World!")).[Link](",")

import { describe, expect, it } from "vitest";


import { cryptoSquare } from "./solutions/h06-crypto-square";

describe("H-06 · Crypto Square", () => {


it("encodes classic example", () => {
const msg = "If man was meant to stay on the ground, god would have
given us roots.";
expect(cryptoSquare(msg)).toBe(
"imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghn sseoau "
);
});

it("empty string returns empty string", () => {


expect(cryptoSquare("")).toBe("");
});

it("single character returns that character", () => {


expect(cryptoSquare("A")).toBe("a");
});

it("strips spaces and punctuation before encoding", () => {


expect(cryptoSquare("Hello, World!")).[Link](",");
});
});

🟢 Hidden Test Cases

Hidden Test Cases — At a Glance


# Input / Setup Expected Output
1 4-char input produces 2x2 expect(cryptoSquare("abcd")).toBe("ac bd")

2 pads last chunks with trailing expect([Link](" ")).toBe(true)


spaces
const result =
cryptoSquare("hello");

3 output chunks are space- expect([Link](" ").length).toBe(2)


separated
const result =
cryptoSquare("abcd");

4 all same characters expect(cryptoSquare("aaaa")).toBe("aa aa")


[Link] Coding Challenges53

describe("H-06 · Crypto Square — Hidden", () => {


it("4-char input produces 2x2", () => {
expect(cryptoSquare("abcd")).toBe("ac bd");
});

it("pads last chunks with trailing spaces", () => {


// 5 chars → 2 rows × 3 cols; last chunk padded
const result = cryptoSquare("hello");
expect([Link](" ")).toBe(true);
});

it("output chunks are space-separated", () => {


const result = cryptoSquare("abcd");
expect([Link](" ").length).toBe(2);
});

it("all same characters", () => {


expect(cryptoSquare("aaaa")).toBe("aa aa");
});
});

H-07. Change (Minimum Coins)


Determine the fewest number of coins needed to make exact change. Given a target amount and
available coin denominations, return the smallest set of coin values that sum to the amount.
🟢 Examples
Amount 15, coins [1,5,10,25,100] → [5, 10]
Amount 40, coins [1,5,10,25,100] → [5, 10, 25]
Amount 12, coins [10,5,2] → [10, 2]

🟢 Sample Test Cases

Sample Test Cases — At a Glance


# Input / Setup Expected Output
1 amount 15 with standard US coins expect(result?.sort()).toEqual([5, 10])
const result = makeChange(15,
[1,5,10,25,100]);

2 amount 40 with standard US coins expect(result?.sort()).toEqual([5, 10, 25])


const result = makeChange(40,
[1,5,10,25,100]);

3 amount 0 returns empty array expect(makeChange(0, [1,5,10])).toEqual([])

4 impossible amount returns null expect(makeChange(3, [2])).toBeNull()

import { describe, expect, it } from "vitest";


import { makeChange } from "./solutions/h07-change";

describe("H-07 · Change (Minimum Coins)", () => {


it("amount 15 with standard US coins", () => {
[Link] Coding Challenges54

const result = makeChange(15, [1,5,10,25,100]);


expect(result?.sort()).toEqual([5, 10]);
});

it("amount 40 with standard US coins", () => {


const result = makeChange(40, [1,5,10,25,100]);
expect(result?.sort()).toEqual([5, 10, 25]);
});

it("amount 0 returns empty array", () => {


expect(makeChange(0, [1,5,10])).toEqual([]);
});

it("impossible amount returns null", () => {


expect(makeChange(3, [2])).toBeNull();
});
});

🟢 Hidden Test Cases

Hidden Test Cases — At a Glance


# Input / Setup Expected Output
1 greedy fails but DP succeeds: expect(result?.length).toBe(2)
amount 6, coins [1,3,4] expect(result?.sort()).toEqual([3, 3])
const result = makeChange(6,
[1,3,4]);

2 single coin denomination exact expect(makeChange(10, [10])).toEqual([10])


match

3 large amount with efficient coins expect(result?.reduce((a,b)=>a+b,0)).toBe(100)


const result =
makeChange(100, [1,5,10,25]);

4 coin larger than amount returns expect(makeChange(3, [5,10])).toBeNull()


null (no 1-coin)

describe("H-07 · Change — Hidden", () => {


it("greedy fails but DP succeeds: amount 6, coins [1,3,4]", () => {
// Greedy picks 4+1+1 (3 coins) but optimal is 3+3 (2 coins)
const result = makeChange(6, [1,3,4]);
expect(result?.length).toBe(2);
expect(result?.sort()).toEqual([3, 3]);
});

it("single coin denomination exact match", () => {


expect(makeChange(10, [10])).toEqual([10]);
});

it("large amount with efficient coins", () => {


const result = makeChange(100, [1,5,10,25]);
expect(result?.reduce((a,b)=>a+b,0)).toBe(100);
});

it("coin larger than amount returns null (no 1-coin)", () => {


[Link] Coding Challenges55

expect(makeChange(3, [5,10])).toBeNull();
});
});

H-08. React (Reactive System)


Implement a basic reactive system with input cells (settable values) and compute cells (values derived
from other cells). When an input changes, values propagate. Compute cells support change-notification
callbacks.
🟢 Concepts
InputCell: setValue(x) updates value and triggers propagation
ComputeCell: value is fn(dependencies); recomputes on dependency change
Callbacks: fire only when a compute cell's stable value actually changes
🟢 Sample Test Cases

Sample Test Cases — At a Glance


# Input / Setup Expected Output
1 input cell stores value expect([Link]).toBe(1)
const r = new Reactor();
const cell = [Link](1);

2 compute cell reflects dependency expect([Link]).toBe(2)


value
const r = new Reactor();
const a = [Link](1);
const b = [Link]([a],
([x]) => x + 1);

3 compute cell updates when input expect([Link]).toBe(10)


changes
const r = new Reactor();
const a = [Link](1);
const b = [Link]([a],
([x]) => x * 2);

4 callback fires on value change expect(changes).toEqual([13])


const r = new Reactor();
const a = [Link](1);
const b = [Link]([a],
([x]) => x + 10);
const changes: number[] = [];

import { describe, expect, it } from "vitest";


import { Reactor } from "./solutions/h08-react";

describe("H-08 · Reactive System", () => {


it("input cell stores value", () => {
const r = new Reactor();
const cell = [Link](1);
expect([Link]).toBe(1);
});
[Link] Coding Challenges56

it("compute cell reflects dependency value", () => {


const r = new Reactor();
const a = [Link](1);
const b = [Link]([a], ([x]) => x + 1);
expect([Link]).toBe(2);
});

it("compute cell updates when input changes", () => {


const r = new Reactor();
const a = [Link](1);
const b = [Link]([a], ([x]) => x * 2);
[Link](5);
expect([Link]).toBe(10);
});

it("callback fires on value change", () => {


const r = new Reactor();
const a = [Link](1);
const b = [Link]([a], ([x]) => x + 10);
const changes: number[] = [];
[Link](val => [Link](val));
[Link](3);
expect(changes).toEqual([13]);
});
});

🟢 Hidden Test Cases

Hidden Test Cases — At a Glance


# Input / Setup Expected Output
1 callback not fired when value expect(changes).toEqual([])
unchanged
const r = new Reactor();
const a = [Link](1);
const b = [Link]([a],
([x]) => x > 0 ? 1 : -1);
const changes: number[] = [];

2 removed callback not called expect(called).toBe(false)


const r = new Reactor();
const a = [Link](1);
const b = [Link]([a],
([x]) => x);
let called = false;
const cb = () => { called =
true; };

3 chain propagation A→B→C expect([Link]).toBe(10)


const r = new Reactor();
const a = [Link](1);
const b = [Link]([a],
([x]) => x + 1);
const c = [Link]([b],
([x]) => x * 2);

4 two computes depending on same expect([Link]).toBe(6)


input both update expect([Link]).toBe(15)
[Link] Coding Challenges57

const r = new Reactor();


const a = [Link](2);
const b = [Link]([a],
([x]) => x + 1);
const c = [Link]([a],
([x]) => x * 3);

describe("H-08 · Reactive System — Hidden", () => {


it("callback not fired when value unchanged", () => {
const r = new Reactor();
const a = [Link](1);
const b = [Link]([a], ([x]) => x > 0 ? 1 : -1);
const changes: number[] = [];
[Link](val => [Link](val));
[Link](5); // b still 1
expect(changes).toEqual([]);
});

it("removed callback not called", () => {


const r = new Reactor();
const a = [Link](1);
const b = [Link]([a], ([x]) => x);
let called = false;
const cb = () => { called = true; };
[Link](cb);
[Link](cb);
[Link](2);
expect(called).toBe(false);
});

it("chain propagation A→B→C", () => {


const r = new Reactor();
const a = [Link](1);
const b = [Link]([a], ([x]) => x + 1);
const c = [Link]([b], ([x]) => x * 2);
[Link](4);
expect([Link]).toBe(10);
});

it("two computes depending on same input both update", () => {


const r = new Reactor();
const a = [Link](2);
const b = [Link]([a], ([x]) => x + 1);
const c = [Link]([a], ([x]) => x * 3);
[Link](5);
expect([Link]).toBe(6);
expect([Link]).toBe(15);
});
});

H-09. Zipper (Binary Tree Navigation)


Implement a zipper for a binary tree — a purely functional data structure that allows navigation and
immutable modification. The zipper holds a tree and a focus pointer. All operations return new zippers.
[Link] Coding Challenges58

🟢 Operations
fromTree(t) — create zipper with focus on root
toTree() — extract the full tree from zipper
value() — get value at focus
left() / right() — move focus to left/right child
up() — move focus to parent
setValue(v) — return new zipper with focus node's value changed
setLeft(t) / setRight(t) — replace left/right subtree
🟢 Sample Test Cases

Sample Test Cases — At a Glance


# Input / Setup Expected Output
1 fromTree gives focus on root value expect([Link]()).toBe(1)
const z =
[Link](tree);

2 left() moves focus to left child expect([Link]()?.value()).toBe(2)


const z =
[Link](tree);

3 right() moves focus to right child expect([Link]()?.value()).toBe(3)


const z =
[Link](tree);

4 up() returns focus to parent expect([Link]()?.up()?.value()).toBe(1)


const z =
[Link](tree);

import { describe, expect, it } from "vitest";


import { Zipper } from "./solutions/h09-zipper";

// Tree: (1 (2 null null) (3 null null))


const tree = { value: 1, left: { value: 2, left: null, right: null },
right: { value: 3, left: null, right: null } };

describe("H-09 · Zipper", () => {


it("fromTree gives focus on root value", () => {
const z = [Link](tree);
expect([Link]()).toBe(1);
});

it("left() moves focus to left child", () => {


const z = [Link](tree);
expect([Link]()?.value()).toBe(2);
});

it("right() moves focus to right child", () => {


const z = [Link](tree);
expect([Link]()?.value()).toBe(3);
});

it("up() returns focus to parent", () => {


const z = [Link](tree);
expect([Link]()?.up()?.value()).toBe(1);
[Link] Coding Challenges59

});
});

🟢 Hidden Test Cases

Hidden Test Cases — At a Glance


# Input / Setup Expected Output
1 setValue returns new zipper without mutating expect([Link]()).toBe(1)
original expect([Link]()).toBe(99)
const z = [Link](tree);
const z2 = [Link](99);

2 toTree after setValue reflects change expect(z?.up()?.toTree().left?.value).toBe(42)


const z =
[Link](tree).left()?.setValue(42);

3 left() on null child returns null expect(z?.left()).toBeNull()


const z = [Link](tree).left(); //
value=2, no children

4 up() at root returns null expect([Link]()).toBeNull()


const z = [Link](tree);

describe("H-09 · Zipper — Hidden", () => {


it("setValue returns new zipper without mutating original", () => {
const z = [Link](tree);
const z2 = [Link](99);
expect([Link]()).toBe(1);
expect([Link]()).toBe(99);
});

it("toTree after setValue reflects change", () => {


const z = [Link](tree).left()?.setValue(42);
expect(z?.up()?.toTree().left?.value).toBe(42);
});

it("left() on null child returns null", () => {


const z = [Link](tree).left(); // value=2, no children
expect(z?.left()).toBeNull();
});

it("up() at root returns null", () => {


const z = [Link](tree);
expect([Link]()).toBeNull();
});
});

H-10. Sliding Puzzle Solver


Given an n×n grid (3 ≤ n ≤ 10) with tiles 1 to n²-1 and one empty tile (0), produce a sequence of tile
moves that transitions the grid to the solved state. Return null if unsolvable.
[Link] Coding Challenges60

🟢 Example
Input: [[1,2,3,4],[5,0,6,8],[9,10,7,11],[13,14,15,12]]
Output: [6,7,11,12] (move tile 6 → then 7 → then 11 → then 12)

🟢 Constraints
• 3 <= n <= 10
• Input will always be valid
• Return null if puzzle is unsolvable
🟢 Sample Test Cases

Sample Test Cases — At a Glance


# Input / Setup Expected Output
1 solves the given example expect(verify(grid,
const grid = slidePuzzle(grid))).toBe(true)
[[1,2,3,4],[5,0,6,8],[9,10,7,11],[13,14,15,12]];

2 already solved grid returns empty moves expect(moves).toEqual([])


const grid = [[1,2,3],[4,5,6],[7,8,0]];
const moves = slidePuzzle(grid);

3 returns null for unsolvable puzzle expect(slidePuzzle(grid)).toBeNull()


const grid = [[2,1,3],[4,5,6],[7,8,0]];

import { describe, expect, it } from "vitest";


import { slidePuzzle } from "./solutions/h10-sliding-puzzle";

const verify = (initial: number[][], moves: number[] | null) => {


if (!moves) return false;
const n = [Link];
const grid = [Link](r => [...r]);
for (const tile of moves) {
let tr = -1, tc = -1, zr = -1, zc = -1;
[Link]((row, r) => [Link]((v, c) => {
if (v === tile) { tr = r; tc = c; }
if (v === 0) { zr = r; zc = c; }
}));
if ([Link](tr-zr)+[Link](tc-zc) !== 1) return false;
grid[zr][zc] = tile; grid[tr][tc] = 0;
}
let ok = true;
[Link]((row, r) => [Link]((v, c) => {
const expected = r*n+c+1 <= n*n-1 ? r*n+c+1 : 0;
if (v !== expected) ok = false;
}));
return ok;
};

describe("H-10 · Sliding Puzzle Solver", () => {


it("solves the given example", () => {
const grid = [[1,2,3,4],[5,0,6,8],[9,10,7,11],[13,14,15,12]];
expect(verify(grid, slidePuzzle(grid))).toBe(true);
});

it("already solved grid returns empty moves", () => {


const grid = [[1,2,3],[4,5,6],[7,8,0]];
[Link] Coding Challenges61

const moves = slidePuzzle(grid);


expect(moves).toEqual([]);
});

it("returns null for unsolvable puzzle", () => {


// Swap 1 and 2 in a solved 3x3 — creates unsolvable state
const grid = [[2,1,3],[4,5,6],[7,8,0]];
expect(slidePuzzle(grid)).toBeNull();
});
});

🟢 Hidden Test Cases

Hidden Test Cases — At a Glance


# Input / Setup Expected Output
1 one move to solve expect(verify(grid,
const grid = [[1,2,3],[4,5,6],[7,0,8]]; moves)).toBe(true)
const moves = slidePuzzle(grid); expect(moves?.length).toBe(1)

2 produces valid move sequence (all tiles adjacent to expect(verify(grid,


blank) moves)).toBe(true)
const grid =
[[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,0,15]];
const moves = slidePuzzle(grid);

3 3x3 scrambled puzzle is solvable if (moves !== null)


const grid = [[4,1,2],[5,0,3],[7,8,6]]; expect(verify(grid,
const moves = slidePuzzle(grid); moves)).toBe(true)

4 n=3 minimum: puzzle with only 2 moves needed expect(verify(grid,


const grid = [[1,2,3],[4,5,6],[0,7,8]]; moves)).toBe(true)
const moves = slidePuzzle(grid);

describe("H-10 · Sliding Puzzle Solver — Hidden", () => {


it("one move to solve", () => {
const grid = [[1,2,3],[4,5,6],[7,0,8]];
const moves = slidePuzzle(grid);
expect(verify(grid, moves)).toBe(true);
expect(moves?.length).toBe(1);
});

it("produces valid move sequence (all tiles adjacent to blank)", () =>


{
const grid = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,0,15]];
const moves = slidePuzzle(grid);
expect(verify(grid, moves)).toBe(true);
});

it("3x3 scrambled puzzle is solvable", () => {


const grid = [[4,1,2],[5,0,3],[7,8,6]];
const moves = slidePuzzle(grid);
if (moves !== null) expect(verify(grid, moves)).toBe(true);
});

it("n=3 minimum: puzzle with only 2 moves needed", () => {


const grid = [[1,2,3],[4,5,6],[0,7,8]];
[Link] Coding Challenges62

const moves = slidePuzzle(grid);


expect(verify(grid, moves)).toBe(true);
});
});

You might also like