Neural Sync Active
Week 4: Nested Iterations
Registry Synced
Week 4: Nested Iterations
2118 words
11 min read
Reading compass
Now · 1. Motivation: Beyond Single Pass
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
| Problem | What We Need | Why Single Pass Won't Work |
|---|---|---|
| Same birthday? | Do any two students share a birthday? | We need to check every pair |
| Find matching pairs | Which students can be study partners? | Need to evaluate each pair |
| Find duplicates | Are there duplicate values? | A single pass only sees one at a time |
| Basket analysis | Which 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
pseudoOuter loop: For each card X in the deck Inner loop: For each card Y in the deck Compare X and Y
(Diagram)
Pseudocode Structure
sqlInitialize 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)
sqlshared = [] 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)
| ID | Birthday |
|---|---|
| A | 45 |
| B | 120 |
| C | 45 |
| D | 200 |
| E | 120 |
Trace:
| Outer X | Inner Comparisons | Matches 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:
pseudofor 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:
pseudoComparisons: 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.
| Aspect | Sequential Iterations | Nested Iterations |
|---|---|---|
| Pattern | Loop, then another loop | Loop inside a loop |
| Relationship | Element ↔ Aggregate | Element ↔ Element |
| Number of operations | O(N) + O(N) = O(2N) | O(N²) |
| Example | Average, below-average students | Birthday paradox, matches |
| Cost | Grows linearly with N | Grows 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):
pseudoTotal comparisons = N × N = N²
With Self-Comparison Removed
pseudoTotal comparisons = N × N - N = N × (N - 1)
With Duplicate Pairs Removed (Each Pair Once)
pseudoTotal comparisons = N × (N - 1) / 2
Step-by-Step Derivation
For N = 5:
| Formula Step | Calculation | Result |
|---|---|---|
| N × N | 5 × 5 | 25 |
| Remove self (N) | 25 - 5 | 20 |
| Remove duplicates (÷2) | 20 ÷ 2 | 10 |
Visualization for N = 5
(Diagram)
7. The Comparison Formula
The General Formula
For N objects, the number of unique pairwise comparisons is:
This is also written as:
Growth Table
| N | N(N-1) | N(N-1)/2 | Growth Type |
|---|---|---|---|
| 5 | 20 | 10 | — |
| 10 | 90 | 45 | 4.5× |
| 20 | 380 | 190 | 19× |
| 50 | 2450 | 1225 | 245× |
| 100 | 9900 | 4950 | 990× |
| 1000 | 999,000 | 499,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
- Total possible ordered pairs: N × N
- Remove pairs with self: N × N - N = N × (N-1)
- 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 AnswerA 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 Answer28×(8−1)=28×7=256=28Answer: 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
| Step | Count |
|---|---|
| All possible ordered pairs (N²) | 100 |
| Self-comparisons (N) | 10 |
| After removing self: N(N-1) | 90 |
| After removing duplicates: N(N-1)/2 | 45 |
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 X | Y in remaining | Match? | 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 AnswersqlClosePairs = [] 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 AnswerCards 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
| Approach | Formula | Count |
|---|---|---|
| Naive (all pairs) | N × N | 10,000 |
| Optimized (each pair once) | N(N-1)/2 | 4,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 Answersql// 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)/6For 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 AnswerNested 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:
- Binning (Topic 08) — Group items first, compare only within groups
- Sorting — Sort first, then adjacent items tell you what you need
- Using dictionaries — Key-value lookups can replace pairwise comparisons
- 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 X | Value | Y candidates | Matches Found |
|---|---|---|---|
| Card 1 | 7 | [2, 7, 4, 2] | Card 3 matches (7=7) |
| Card 2 | 2 | [7, 4, 2] | Card 5 matches (2=2) |
| Card 3 | 7 | [4, 2] | None |
| Card 4 | 4 | [2] | None |
| Card 5 | 2 | [] | 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 AnswerFor N=100 students:
| Task | Approach | Comparisons |
|---|---|---|
| Find average | Sequential (single pass) | 100 |
| Find most similar pair | Nested (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
| Course | Topic | Connection |
|---|---|---|
| BSCS1002 (Python) | Week 6 — Nested Loops | for inside for |
| BSCS2002 (PDSA) | Week 4 — Complexity | O(N²) complexity analysis |
| BSCS2002 (PDSA) | Week 5 — Sorting | Sorting to avoid nested loops |
Next Topic: 08 — Binning & Complexity IntroductionQuiz Tip: Know the formula N(N-1)/2 cold — you'll need it for Quiz 2! Join Discord PreviousSide Effects of ProceduresNextBinning & Complexity Introduction