Bird
Raised Fist0
DSA Typescriptprogramming~20 mins

Why Recursion Exists and What Loops Cannot Express Cleanly in DSA Typescript - Challenge Your Understanding

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Recursion Mastery
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
Output of Recursive Factorial Function
What is the output of the following TypeScript code that uses recursion to calculate factorial?
DSA Typescript
function factorial(n: number): number {
  if (n <= 1) return 1;
  return n * factorial(n - 1);
}
console.log(factorial(4));
A120
B10
C24
D6
Attempts:
2 left
💡 Hint
Think about how factorial multiplies numbers from n down to 1.
🧠 Conceptual
intermediate
2:00remaining
Why Recursion Can Express Tree Traversals More Cleanly Than Loops
Why is recursion often preferred over loops when traversing tree structures?
ARecursion naturally handles branching by calling itself for each child, while loops require manual stack management.
BLoops are faster than recursion for trees, so recursion is avoided.
CRecursion cannot be used for trees because it causes infinite loops.
DLoops automatically traverse all nodes without extra code.
Attempts:
2 left
💡 Hint
Think about how trees have multiple branches and how recursion calls itself for each branch.
🔧 Debug
advanced
2:00remaining
Identify the Error in Recursive Fibonacci Implementation
What error does the following TypeScript code produce when run?
DSA Typescript
function fib(n: number): number {
  if (n === 0) return 0;
  if (n === 1) return 1;
  return fib(n - 1) + fib(n - 2);
}
console.log(fib(-1));
AStack overflow error due to infinite recursion
BReturns 0 without error
CReturns 1 without error
DSyntax error
Attempts:
2 left
💡 Hint
Consider what happens when n is negative in the recursive calls.
🚀 Application
advanced
2:00remaining
Using Recursion to Flatten Nested Arrays
Which option correctly outputs the flattened array from a nested array using recursion in TypeScript?
DSA Typescript
const nested = [1, [2, [3, 4], 5], 6];
function flatten(arr: any[]): number[] {
  let result: number[] = [];
  for (const el of arr) {
    if (Array.isArray(el)) {
      result = result.concat(flatten(el));
    } else {
      result.push(el);
    }
  }
  return result;
}
console.log(flatten(nested));
A[1, 2, [3, 4], 5, 6]
B[1, [2, [3, 4], 5], 6]
C[[1, 2, 3, 4, 5, 6]]
D[1, 2, 3, 4, 5, 6]
Attempts:
2 left
💡 Hint
Flattening means removing all nested arrays and putting all elements in one list.
🧠 Conceptual
expert
2:00remaining
Why Some Problems Cannot Be Cleanly Solved Using Loops Alone
Which statement best explains why recursion is necessary for some problems instead of just using loops?
ALoops are always slower and less memory efficient than recursion.
BSome problems have self-similar structures that require the function to call itself with smaller inputs, which loops cannot express naturally.
CLoops cannot be nested, so they cannot handle complex problems.
DRecursion uses less code but cannot solve problems loops can.
Attempts:
2 left
💡 Hint
Think about problems like tree traversals or divide-and-conquer algorithms.

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

  1. Step 1: Understand recursion's nature

    Recursion breaks a problem into smaller versions of itself, which loops cannot express naturally.
  2. Step 2: Compare loops and recursion

    Loops repeat fixed steps but cannot easily handle problems defined by self-similar subproblems like tree traversals.
  3. Final Answer:

    Because recursion can express problems with self-similar subproblems naturally -> Option A
  4. 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

  1. 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.
  2. 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.
  3. Final Answer:

    function factorial(n: number): number { if (n <= 1) return 1; else return n * factorial(n - 1); } -> Option D
  4. 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

  1. Step 1: Trace recursive calls

    printNumbers(3) calls printNumbers(2), which calls printNumbers(1), then printNumbers(0) returns immediately.
  2. Step 2: Understand console.log order

    After reaching base case, console.log prints n while unwinding: prints 1, then 2, then 3.
  3. Final Answer:

    1 2 3 -> Option B
  4. 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

  1. Step 1: Identify missing base case

    The function calls itself without stopping condition, causing infinite recursion.
  2. Step 2: Add base case to stop recursion

    Adding if (n <= 0) return 0; stops recursion and returns correct sum.
  3. Final Answer:

    Add a base case to stop recursion when n <= 0 -> Option A
  4. 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

  1. Step 1: Understand nested structure

    The array has unknown depth of nested arrays, which loops alone cannot easily handle.
  2. Step 2: Recursion handles unknown depth

    Recursion calls itself on nested arrays, flattening all levels naturally without complex loops.
  3. Final Answer:

    Because recursion naturally handles unknown levels of nesting by calling itself -> Option C
  4. Quick Check:

    Recursion = natural for unknown nested depth [OK]
Hint: Recursion handles unknown nested depth easily [OK]
Common Mistakes:
  • Thinking loops can flatten any nested array easily
  • Believing recursion always uses less memory
  • Assuming loops cannot access array elements
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard