import random from typing import List, Dict, Any, Tuple def weighted_sample_6(weights: Dict[int, float]) -> List[int]: """ 가중 확률 샘플링으로 중복 없이 6개 번호 추출. weights: {1: w1, 2: w2, ..., 45: w45} """ pool = list(range(1, 46)) chosen: List[int] = [] for _ in range(6): total = sum(weights[n] for n in pool) r = random.random() * total acc = 0.0 for n in pool: acc += weights[n] if acc >= r: chosen.append(n) pool.remove(n) break return chosen def calc_metrics(numbers: List[int]) -> Dict[str, Any]: nums = sorted(numbers) s = sum(nums) odd = sum(1 for x in nums if x % 2 == 1) even = len(nums) - odd mn, mx = nums[0], nums[-1] rng = mx - mn # 1-10, 11-20, 21-30, 31-40, 41-45 buckets = { "1-10": 0, "11-20": 0, "21-30": 0, "31-40": 0, "41-45": 0, } for x in nums: if 1 <= x <= 10: buckets["1-10"] += 1 elif 11 <= x <= 20: buckets["11-20"] += 1 elif 21 <= x <= 30: buckets["21-30"] += 1 elif 31 <= x <= 40: buckets["31-40"] += 1 else: buckets["41-45"] += 1 return { "sum": s, "odd": odd, "even": even, "min": mn, "max": mx, "range": rng, "buckets": buckets, } def calc_recent_overlap(numbers: List[int], draws: List[Tuple[int, List[int]]], last_k: int) -> Dict[str, Any]: """ draws: [(drw_no, [n1..n6]), ...] 오름차순 last_k: 최근 k회 기준 중복 """ if last_k <= 0: return {"last_k": 0, "repeats": 0, "repeated_numbers": []} recent = draws[-last_k:] if len(draws) >= last_k else draws recent_set = set() for _, nums in recent: recent_set.update(nums) repeated = sorted(set(numbers) & recent_set) return { "last_k": len(recent), "repeats": len(repeated), "repeated_numbers": repeated, }