Why Recursion Exists and What Loops Cannot Express Cleanly
📖 Scenario: Imagine you have a set of nested boxes, where each box can contain another box inside it, and so on. You want to find the smallest box inside all these nested boxes.This is a real-world example where simple loops struggle to express the problem clearly, but recursion shines by naturally handling the nested structure.
🎯 Goal: You will build a recursive function in TypeScript that finds the smallest number inside a nested structure of boxes. Each box is represented as an object that either holds a number or another box.This project will show why recursion is useful and how it can express problems that loops cannot handle cleanly.
📋 What You'll Learn
Create a nested box structure using objects with exact values
Add a helper variable to track the smallest number found
Write a recursive function called findSmallestBox that finds the smallest number inside nested boxes
Print the smallest number found using console.log
💡 Why This Matters
🌍 Real World
Nested data structures appear in file systems, organizational charts, and JSON data. Recursion helps process these naturally.
💼 Career
Understanding recursion is essential for software developers, especially when working with trees, graphs, and nested data formats.
Progress0 / 4 steps
1
Create the nested box structure
Create a variable called nestedBoxes that represents nested boxes exactly as follows: the outer box contains another box, which contains another box, which finally contains the number 5. Use objects with the property box to nest boxes.
DSA Typescript
Hint
Use objects with a box property to nest boxes inside each other.
2
Add a helper variable to track smallest number
Create a variable called smallest and set it to Infinity to start tracking the smallest number found inside the boxes.
DSA Typescript
Hint
Use let smallest = Infinity; to start with the largest possible number.
3
Write the recursive function to find the smallest number
Write a recursive function called findSmallestBox that takes a parameter box. If box is a number, update smallest if it is smaller. If box is an object with a box property, call findSmallestBox recursively on box.box.
DSA Typescript
Hint
Use typeof to check if box is a number or an object, then recurse accordingly.
4
Call the function and print the smallest number
Call findSmallestBox with nestedBoxes as argument. Then print the value of smallest using console.log(smallest).
DSA Typescript
Hint
Call the recursive function with nestedBoxes and print smallest.
Practice
(1/5)
1. Why do we use recursion instead of loops in some problems?
easy
A. Because recursion can express problems with self-similar subproblems naturally
B. Because loops are slower than recursion in all cases
C. Because recursion uses less memory than loops always
D. Because loops cannot run more than 10 times
Solution
Step 1: Understand recursion's nature
Recursion breaks a problem into smaller versions of itself, which loops cannot express naturally.
Step 2: Compare loops and recursion
Loops repeat fixed steps but cannot easily handle problems defined by self-similar subproblems like tree traversals.
Final Answer:
Because recursion can express problems with self-similar subproblems naturally -> Option A
Quick Check:
Recursion = self-similar problem solving [OK]
Hint: Recursion fits problems breaking into smaller similar parts [OK]
Common Mistakes:
Thinking loops are always faster
Believing recursion always uses less memory
Assuming loops cannot run many times
2. Which of the following is the correct syntax for a recursive function in TypeScript?
easy
A. function factorial(n: number): number { if (n == 0) return 0; else return n + factorial(n + 1); }
B. function factorial(n: number): number { while (n > 1) n = n - 1; return n; }
C. function factorial(n: number): number { for (let i = 1; i <= n; i++) return i; }
D. function factorial(n: number): number { if (n <= 1) return 1; else return n * factorial(n - 1); }
Solution
Step 1: Identify recursive call
function factorial(n: number): number { if (n <= 1) return 1; else return n * factorial(n - 1); } calls factorial inside itself with n-1, which is recursion.
Step 2: Check base case correctness
function factorial(n: number): number { if (n <= 1) return 1; else return n * factorial(n - 1); } returns 1 when n <= 1, preventing infinite calls.
Final Answer:
function factorial(n: number): number { if (n <= 1) return 1; else return n * factorial(n - 1); } -> Option D
Quick Check:
Recursive call with base case = function factorial(n: number): number { if (n <= 1) return 1; else return n * factorial(n - 1); } [OK]
Hint: Look for function calling itself with smaller input [OK]
Common Mistakes:
Missing base case causing infinite recursion
Using loops instead of recursive calls
Incorrect base case values
3. What is the output of this TypeScript code?
function printNumbers(n: number): void {
if (n === 0) return;
printNumbers(n - 1);
console.log(n);
}
printNumbers(3);
medium
A. 3 2 1
B. 1 2 3
C. 3 2 1 0
D. 0 1 2 3
Solution
Step 1: Trace recursive calls
printNumbers(3) calls printNumbers(2), which calls printNumbers(1), then printNumbers(0) returns immediately.
Step 2: Understand console.log order
After reaching base case, console.log prints n while unwinding: prints 1, then 2, then 3.
Final Answer:
1 2 3 -> Option B
Quick Check:
Recursion unwinds printing ascending numbers [OK]
Hint: Recursion prints after call, so output is ascending [OK]
Common Mistakes:
Assuming print before recursive call prints descending
Including 0 in output incorrectly
Confusing order of prints
4. Identify the error in this recursive function and choose the fix:
function sumToN(n: number): number {
return n + sumToN(n - 1);
}
medium
A. Add a base case to stop recursion when n <= 0
B. Change return to console.log to print values
C. Replace recursion with a for loop
D. Remove the parameter n
Solution
Step 1: Identify missing base case
The function calls itself without stopping condition, causing infinite recursion.
Step 2: Add base case to stop recursion
Adding if (n <= 0) return 0; stops recursion and returns correct sum.
Final Answer:
Add a base case to stop recursion when n <= 0 -> Option A
Quick Check:
Base case prevents infinite recursion [OK]
Hint: Always include base case to stop recursion [OK]
Common Mistakes:
Forgetting base case causes stack overflow
Changing return to console.log does not fix recursion
Removing parameter breaks logic
5. You want to flatten a nested array of numbers like [1, [2, [3, 4], 5], 6] into a single array [1, 2, 3, 4, 5, 6]. Why is recursion a better choice than loops here?
hard
A. Because recursion uses less memory than loops for arrays
B. Because loops can only flatten arrays with one level of nesting
C. Because recursion naturally handles unknown levels of nesting by calling itself
D. Because loops cannot access array elements
Solution
Step 1: Understand nested structure
The array has unknown depth of nested arrays, which loops alone cannot easily handle.
Step 2: Recursion handles unknown depth
Recursion calls itself on nested arrays, flattening all levels naturally without complex loops.
Final Answer:
Because recursion naturally handles unknown levels of nesting by calling itself -> Option C