Quiz 2

Week 4: Nested Iterations

2118 words
11 min read
Python Week 1: the first filter for runtime behavior
Visual companion
Python
Type and operator map

Python Week 1: the first filter for runtime behavior

View
Revision summary

What this note is really saying

Short form

# Week 4: Nested Iterations > **BSCS1001 — IIT Madras BS Degree** **Prerequisite:** Week 2 (Single Iteration), Week 3 (Procedures) **Cross-links:** BSCS1002-Python (Week 6 — Nested Loops), BSCS2002-PDSA (Week 4 — Complexity) ## 1. Motivation: Beyond Single Pass So far, we've done **single-pass iterations** — pick ea...

Week 4: Nested Iterations

BSCS1001 — IIT Madras BS Degree Prerequisite: Week 2 (Single Iteration), Week 3 (Procedures) Cross-links: BSCS1002-Python (Week 6 — Nested Loops), BSCS2002-PDSA (Week 4 — Complexity)

1. Motivation: Beyond Single Pass

So far, we've done single-pass iterations — pick each card once, update variables. But what if we need to compare every card with every other card?

Problems That Need Pairwise Comparison

ProblemWhat We NeedWhy Single Pass Won't Work
Same birthday?Do any two students share a birthday?We need to check every pair
Find matching pairsWhich students can be study partners?Need to evaluate each pair
Find duplicatesAre there duplicate values?A single pass only sees one at a time
Basket analysisWhich items are often bought together?Need item-item relationships
💡 Key Insight: Single-pass iteration relates each card to an aggregate (sum, max, count). Nested iteration relates each card to every other card.

2. What are Nested Iterations?

A nested iteration is a loop inside another loop. For each card in the outer loop, we go through ALL cards in the inner loop.

Visual Pattern

pseudo
Outer loop: For each card X in the deck
    Inner loop: For each card Y in the deck
        Compare X and Y
(Diagram)

Pseudocode Structure

sql
Initialize results
while (Pile 1 has more cards) {
    Pick a card X from Pile 1
    Move X to Pile 2
    // Inner iteration
    while (Pile 2 has cards before X) {   // or process all other cards
        Pick a card Y
        Compare X with Y
    }
}

A Concrete Example

sql
// Find all pairs of students (X, Y) such that X != Y
Pairs = []
while (Pile 1 has more cards) {
    Pick a card X from Pile 1
    Move X to Pile 2
    // Compare X with every card in Pile 2 (already processed cards)
    while (Pile 2 has more cards before X) {
        Pick a card Y from Pile 2 (not X)
        Pairs = Pairs ++ [(X.Id, Y.Id)]
    }
}

3. The Birthday Paradox Problem

This is the classic problem used to introduce nested iterations.

Problem

Given a list of students and their dates of birth, find all pairs of students who share the same birthday.

Naive Approach (Without Binning)

sql
shared = []
while (Pile 1 has more cards) {
    Pick a card X from Pile 1
    Move X to Pile 2
    // Compare X's birthday with all remaining cards
    for each card Y in Pile 1 {
        if (X.Dob == Y.Dob) {
            shared = shared ++ [(X.Id, Y.Id)]
        }
    }
}

Tracing the Birthday Paradox

Dataset: 5 students with birthdays (as day-of-year numbers)
IDBirthday
A45
B120
C45
D200
E120
Trace:
Outer XInner ComparisonsMatches Found
A (45)B(120), C(45), D(200), E(120)A-C (both 45)
B (120)C(45), D(200), E(120)B-E (both 120)
C (45)D(200), E(120)C-A would be match, but A is in Pile 2
D (200)E(120)None
E (120)(none left)None
Result: Two pairs share birthdays: (A, C) and (B, E)
Why not count C-A? Because A-C was already counted when X=A. Counting C-A would double-count. By only comparing X with cards still in Pile 1 (after X), we count each pair exactly once.

4. Naive Approach: Comparing All Pairs

If we compare every card with every other card (including self and reversed comparisons), the pseudocode looks like:
pseudo
for each card X in the deck {
    for each card Y in the deck {
        if (X != Y) {
            Compare X and Y
        }
    }
}

Visualizing All Pairs

For 5 elements A, B, C, D, E:
pseudo
Comparisons:
A with A (self) — skip
A with B, A with C, A with D, A with E  (4 comparisons)
B with A, B with B (self), B with C, B with D, B with E  (4 comparisons, but B-A is duplicate)
C with A, C with B, C with C (self), C with D, C with E  (4 comparisons, duplicates)
D with A, D with B, D with C, D with D (self), D with E  (4 comparisons, duplicates)
E with A, E with B, E with C, E with D, E with E (self)  (4 comparisons, duplicates)

Optimized: Avoid Self-Comparison and Duplicates

sql
// Only compare each pair ONCE
while (Pile 1 has more cards) {
    Pick a card X from Pile 1
    Move X to Pile 2
    // Compare X only with cards REMAINING in Pile 1
    for each card Y in Pile 1 {
        Compare X and Y
    }
}
For 5 elements: A-B, A-C, A-D, A-E, B-C, B-D, B-E, C-D, C-E, D-E = 10 comparisons (not 25).

5. Sequential vs Nested Iterations

Sequential (Non-Nested) Iterations

Two iterations one after another:
pseudo
// First iteration: Compute average
Sum = 0, Count = 0
for each card X {
    Sum = Sum + X.Marks
    Count = Count + 1
}
Average = Sum / Count
// Second iteration: Find below-average students
BelowAvg = []
for each card X {
    if (X.Marks < Average) {
        BelowAvg = BelowAvg ++ [X.Id]
    }
}
Relationship: Each element is related to the aggregate of all elements.
AspectSequential IterationsNested Iterations
PatternLoop, then another loopLoop inside a loop
RelationshipElement ↔ AggregateElement ↔ Element
Number of operationsO(N) + O(N) = O(2N)O(N²)
ExampleAverage, below-average studentsBirthday paradox, matches
CostGrows linearly with NGrows quadratically with N

When to Use Each

(Diagram)

6. Counting Comparisons

Without Optimization (All Pairs)

If we compare every card with every card (including self):
pseudo
Total comparisons = N × N = N²

With Self-Comparison Removed

pseudo
Total comparisons = N × N - N = N × (N - 1)

With Duplicate Pairs Removed (Each Pair Once)

pseudo
Total comparisons = N × (N - 1) / 2

Step-by-Step Derivation

For N = 5:
Formula StepCalculationResult
N × N5 × 525
Remove self (N)25 - 520
Remove duplicates (÷2)20 ÷ 210

Visualization for N = 5

(Diagram)

7. The Comparison Formula

The General Formula

For N objects, the number of unique pairwise comparisons is:
Comparisons=N×(N1)2\text{Comparisons} = \frac{N \times (N-1)}{2}
This is also written as:
(N2)=N!2!(N2)!=N(N1)2\binom{N}{2} = \frac{N!}{2!(N-2)!} = \frac{N(N-1)}{2}

Growth Table

NN(N-1)N(N-1)/2Growth Type
52010
1090454.5×
2038019019×
5024501225245×
10099004950990×
1000999,000499,500~100,000×
10000~100M~50M~10,000,000×

Why This Matters

(Diagram) The nested iteration grows quadratically (N²), while single-pass grows linearly (N). For large datasets, nested iterations become impractical — which is why binning (next topic) is crucial.

Derivation from First Principles

  1. Total possible ordered pairs: N × N
  2. Remove pairs with self: N × N - N = N × (N-1)
  3. Each unordered pair counted twice: N × (N-1) / 2

Alternative Derivation

  • First element compares with N-1 others
  • Second element compares with N-2 others (already compared with first)
  • Third element compares with N-3 others
  • ...
  • Last element compares with 0 others Sum: (N-1) + (N-2) + (N-3) + ... + 1 + 0 = N × (N-1) / 2

8. Practice Questions

Basic Questions

Q1. What is a nested iteration?
Show Answer
A nested iteration is a loop inside another loop. For each iteration of the outer loop, the inner loop runs completely. It's used to compare every pair of elements. Q2. How many comparisons are needed to compare all pairs of 8 elements (each pair once)? Show Answer
8×(81)2=8×72=562=28\frac{8 \times (8-1)}{2} = \frac{8 \times 7}{2} = \frac{56}{2} = 28
Answer: 28 comparisons Q3. Compare sequential iterations vs nested iterations in terms of what relationship they establish. Show Answer
  • Sequential iterations: Establish relationship between an element and the aggregate (e.g., comparing a student's mark to the class average)
  • Nested iterations: Establish relationship between element and element (e.g., comparing two students' birthdays) Q4. For N=10, how many pairwise comparisons are saved by avoiding self-comparison and duplicates? Show Answer
StepCount
All possible ordered pairs (N²)100
Self-comparisons (N)10
After removing self: N(N-1)90
After removing duplicates: N(N-1)/245
Saved: 100 - 45 = 55 comparisons

Intermediate Questions

Q5. Trace the birthday paradox algorithm for dataset:
  • A: DOB=50, B: DOB=50, C: DOB=120, D: DOB=200, E: DOB=50 How many matches are found?
Show Answer
Outer XY in remainingMatch?pairs
A (50)B(50)✅ A-B(A,B)
A (50)C(120)
A (50)D(200)
A (50)E(50)✅ A-E(A,E)
B (50)C(120)
B (50)D(200)
B (50)E(50)✅ B-E(B,E)
C (120)D(200)
C (120)E(50)
D (200)E(50)
Result: 3 matching pairs: (A,B), (A,E), (B,E) Q6. Write pseudocode to find all pairs of students whose total marks differ by less than 10. Show Answer
sql
ClosePairs = []
while (Pile 1 has more cards) {
    Pick a card X from Pile 1
    Move X to Pile 2

    for each card Y in Pile 1 {
        diff = X.Total - Y.Total
        if (diff < 0) {
            diff = -diff    // Absolute value
        }
        if (diff < 10) {
            ClosePairs = ClosePairs ++ [(X.Id, Y.Id)]
        }
    }
}
Q7. Why do we only compare X with cards REMAINING in Pile 1, not with cards in Pile 2 as well?
Show Answer
Cards in Pile 2 have already been processed as X in a previous outer iteration. For example, when X=A compared with B, we recorded pair (A,B). Later, when X=B, if we also compared with A (in Pile 2), we'd record (B,A) — which is the same pair. By only comparing with cards remaining in Pile 1, we count each pair exactly once. Q8. If N=100, how many comparisons does the naive nested approach (including self and duplicates) make, compared to the optimized approach? Show Answer
ApproachFormulaCount
Naive (all pairs)N × N10,000
Optimized (each pair once)N(N-1)/24,950
The optimized approach makes less than half the comparisons (avoids self and halves for duplicates).

Advanced Questions

Q9. Design an algorithm to find all triples of students who share the same birthday. How many comparisons would this require?
Show Answer
sql
// Find all triples with same birthday
Triples = []
while (Pile 1 has more cards) {
    Pick a card X from Pile 1
    Move X to Pile 2

    while (Pile 1 has cards before current position) { ... }
    // Actually, we'd need THREE nested loops for triples:

    for each card Y where Y is after X {
        for each card Z where Z is after Y {
            if (X.Dob == Y.Dob AND Y.Dob == Z.Dob) {
                Triples = Triples ++ [(X.Id, Y.Id, Z.Id)]
            }
        }
    }
}
Number of triples: C(N,3) = N(N-1)(N-2)/6
For N=10: 10×9×8/6 = 120 triples to check. Q10. Explain why nested iterations are called "costly" and when you should consider alternatives. Show Answer
Nested iterations are costly because they require O(N²) comparisons. For a dataset of 1 million students, comparing all pairs would require ~500 billion operations — completely impractical.
Alternatives to consider:
  1. Binning (Topic 08) — Group items first, compare only within groups
  2. Sorting — Sort first, then adjacent items tell you what you need
  3. Using dictionaries — Key-value lookups can replace pairwise comparisons
  4. Sampling — If exact answer isn't needed, approximate with samples
Rule of thumb: If you see nested loops over the same dataset, ask: "Can I avoid this?" Q11. Trace the execution for finding duplicates (same value) in [7, 2, 7, 4, 2] using the optimized nested approach. Show Answer
Outer XValueY candidatesMatches Found
Card 17[2, 7, 4, 2]Card 3 matches (7=7)
Card 22[7, 4, 2]Card 5 matches (2=2)
Card 37[4, 2]None
Card 44[2]None
Card 52[]None
Duplicate pairs found: (1,3) and (2,5) — both 7s and both 2s. Q12. Compare the number of comparisons for sequential vs nested approaches to find the average AND the most similar pair of students. Show Answer
For N=100 students:
TaskApproachComparisons
Find averageSequential (single pass)100
Find most similar pairNested (all pairs)4,950
Takeaway: Finding the average is 50× faster than finding the most similar pair for N=100. For N=1000, the gap is ~500×. Always prefer sequential when possible!

📚 Cross-References

CourseTopicConnection
BSCS1002 (Python)Week 6 — Nested Loopsfor inside for
BSCS2002 (PDSA)Week 4 — ComplexityO(N²) complexity analysis
BSCS2002 (PDSA)Week 5 — SortingSorting to avoid nested loops

Quiz Tip: Know the formula N(N-1)/2 cold — you'll need it for Quiz 2! Join Discord PreviousSide Effects of ProceduresNextBinning & Complexity Introduction
Document outline

Keep your place and jump directly to a heading.

Table of Contents
System Normal // Awaiting Context

Intelligence Hub

Navigate the knowledge graph to generate context. The Hub adapts dynamically to surface backlinks, related notes, and metadata insights.