feat(patterns): pattern taxonomy + is_optimal

This commit is contained in:
2025-09-08 16:03:14 +01:00
parent 291b4aabd6
commit 91e48f5239
28 changed files with 1434 additions and 26 deletions

View File

@@ -0,0 +1,104 @@
name: Topological Sort
slug: topological-sort
difficulty_level: 3
pattern_type: algorithm
display_order: 22
description: >
Order vertices in a directed acyclic graph (DAG) such that for every
edge u -> v, vertex u comes before v in the ordering.
when_to_use: |
- Course prerequisites / task dependencies
- Build order / compilation order
- Detecting cycles in directed graphs
- Any problem with "do A before B" constraints
metaphor: |
Imagine getting dressed: you must put on underwear before pants, socks
before shoes. Topological sort finds a valid order that respects all
"must come before" rules. If there's a cycle (shirt requires jacket,
jacket requires shirt), no valid order exists.
core_concept: |
Two main approaches:
**Kahn's Algorithm (BFS):** Start with nodes having no incoming edges
(in-degree 0). Process them, remove their edges, repeat. If all nodes
processed, valid order exists.
**DFS-based:** Do DFS, add nodes to result when backtracking (post-order).
Reverse at end. Cycle exists if we revisit a node in current path.
code_template: |
from collections import deque
def topological_sort_bfs(n: int, edges: list[tuple[int, int]]) -> list[int]:
"""Kahn's algorithm - returns empty list if cycle exists."""
# Build adjacency list and in-degree count
graph = [[] for _ in range(n)]
in_degree = [0] * n
for u, v in edges: # u -> v (u must come before v)
graph[u].append(v)
in_degree[v] += 1
# Start with nodes having no prerequisites
queue = deque([i for i in range(n) if in_degree[i] == 0])
result = []
while queue:
node = queue.popleft()
result.append(node)
for neighbor in graph[node]:
in_degree[neighbor] -= 1
if in_degree[neighbor] == 0:
queue.append(neighbor)
# If we processed all nodes, valid topological order exists
return result if len(result) == n else []
recognition_signals:
- "prerequisites"
- "dependencies"
- "ordering tasks"
- "course schedule"
- "build order"
- "detect cycle in directed graph"
- "do X before Y"
common_mistakes:
- title: Forgetting Cycle Detection
description: |
Assuming input is always a valid DAG. Must check if all nodes were
processed (BFS) or if back-edge exists (DFS).
fix: |
BFS: Check `len(result) == n`. DFS: Track "visiting" state separately
from "visited."
- title: Wrong Edge Direction
description: |
Confusing "A depends on B" vs "A must come before B." These are
opposite edge directions.
fix: |
Clarify: If A depends on B, edge is B -> A (B comes before A).
variations:
- name: Course Schedule (cycle detection)
description: Return true/false if valid ordering exists
example: "course-schedule"
- name: Course Schedule II (find order)
description: Return the actual ordering
example: "course-schedule-ii"
- name: Alien Dictionary
description: Infer ordering from sorted alien words
example: "alien-dictionary"
related_patterns:
- bfs
- dfs
prerequisite_patterns:
- bfs
- dfs