05/23 Phase 20

This commit is contained in:
2026-05-23 16:38:20 -04:00
parent 2553406254
commit ea30c7d838
6 changed files with 423 additions and 5 deletions
+49
View File
@@ -0,0 +1,49 @@
"""
core/wheeling.py
----------------
Full-cover number wheeling.
wheel_count(numbers, k) — C(n, k) ticket count preview
wheel_full(numbers, k) — all C(n, k) sorted combinations
Raises ValueError for invalid inputs or if result exceeds MAX_TICKETS.
"""
from itertools import combinations
from math import comb
MAX_TICKETS = 200
def wheel_count(numbers: list | set, k: int) -> int:
"""Return how many tickets a full wheel would produce (C(n, k))."""
n = len(set(numbers))
if k < 1 or k > n:
return 0
return comb(n, k)
def wheel_full(numbers: list | set, k: int) -> list[list[int]]:
"""
Generate all C(n, k) combinations from *numbers*, each sorted ascending.
Duplicates in input are removed before wheeling.
Raises ValueError if k is out of range or count > MAX_TICKETS.
"""
pool = sorted(set(numbers))
n = len(pool)
if k < 1:
raise ValueError("Pick count must be at least 1.")
if k > n:
raise ValueError(
f"Pick count ({k}) exceeds the number pool size ({n})."
)
count = comb(n, k)
if count > MAX_TICKETS:
raise ValueError(
f"Wheel would produce {count:,} tickets (max {MAX_TICKETS:,}). "
f"Reduce your pool or pick count."
)
return [sorted(combo) for combo in combinations(pool, k)]