def generator(clue: Clue) -> Iterator[int]: min_value = 10**(clue.length - 1) max_value = 10**clue.length primes = generators.prime_generator() for prime in primes: for power in itertools.count(min_power): result = prime**power if result >= min_value: if result >= max_value: if power == min_power: return break yield result
def make_min_max_factor_table() -> Sequence[Tuple[int, int]]: primes = tuple( itertools.takewhile(lambda x: x < 315, generators.prime_generator())) primes_set = set(primes) min_max_factor = [(0, 0)] * 100000 min_max_factor[1] = (1, 1) for value in range(2, len(min_max_factor)): if value % 10000 == 0: print(value) if value in primes_set: min_max_factor[value] = (value, value) else: factor = next((x for x in primes if value % x == 0), None) if not factor: min_max_factor[value] = (value, value) else: fmin, fmax = min_max_factor[value // factor] min_max_factor[value] = min(fmin, factor), max(fmax, factor) return min_max_factor
def set_up_tables( ) -> Tuple[Sequence[int], Sequence[int], Sequence[int], Sequence[int]]: max_value = 100_000 primes = tuple( itertools.takewhile(lambda x: x < max_value, generators.prime_generator())) primes_set = set(primes) prime_info = [(1, 1, 0)] * max_value prime_count = [0] * max_value factor_count = [0] * max_value rsequence_count = [0] * max_value # R square_count = [0] * max_value # S factor_count[1] = 1 for value in range(2, max_value): if value in primes_set: multiplier, smallest_prime, exponent = 1, value, 1 # 1 * value ^ 1 else: smallest_prime = next(i for i in primes if value % i == 0) parent = value // smallest_prime p_multiplier, p_smallest_prime, p_exponent = prime_info[parent] if smallest_prime == p_smallest_prime: multiplier, exponent = p_multiplier, p_exponent + 1 else: multiplier, exponent = parent, 1 prime_info[value] = multiplier, smallest_prime, exponent prime_count[value] = prime_count[multiplier] + 1 factor_count[value] = factor_count[multiplier] * (exponent + 1) rsequence_count[value] = factor_count[ value] - 1 if value % 2 else rsequence_count[value // 2] if value % 2: square_count[value] = factor_count[value] // 2 elif value % 4: square_count[value] = 0 else: square_count[value] = factor_count[value // 4] // 2 return prime_count, factor_count, rsequence_count, square_count
7 ?146? 8 ?65?0 9 ?66?0 10 ?849? 11 ?9?60 12 ?95?0 13 ?3?50 14 351?? 15 ??780 16 ??890 17 566?? 18 491?? """ primes = list( itertools.takewhile(lambda x: x < 1000, generators.prime_generator())) class Solver208(ConstraintSolver): clue_primes: Sequence[Tuple[int, int]] @staticmethod def run() -> None: solver = Solver208() solver.solve() def __init__(self) -> None: self.clue_primes = self.__get_clue_primes() clue_list = self.make_clue_list() super(Solver208, self).__init__(clue_list)
def make_clue_list(info: str) -> Sequence[Clue]: clues = [] for line in info.splitlines(): if not line: continue match = re.fullmatch(r'(\d+) (\d) (.*)', line) assert match # We don't care about the location. We just care about the length clue = Clue(match.group(1), True, (1, 1), int(match.group(2)), expression=match.group(3)) clues.append(clue) return clues primes = list(itertools.takewhile(lambda x: x * x < 10_000_000, generators.prime_generator())) primes_set = frozenset(primes) squares_set = frozenset(i * i for i in primes) @functools.lru_cache(maxsize=None) def is_legal_value(clue_value: ClueValue) -> bool: value = int(clue_value) if not 1000 <= value <= 9_999_999: return False factor = next((p for p in primes if value % p == 0), None) if not factor: return False if factor ** 5 == value: return True temp = value // factor
generators.BASE = 16 CUBES = {i ** 3 for i in range(1, 50) if i ** 3 <= 0xFFFF} SQUARES = {i ** 2 for i in range(1, 0x100)} TWO_CUBES_DELTA = { value for i in range(1, 0x100) for j in range(1, i) for value in [i*i*i - j*j*j] if value <= 0xFFFF } TWO_CUBES_SUM = { value for i in range(1, 0x100) for j in range(1, i) for value in [i*i*i + j*j*j] if value <= 0xFFFF } PRIMES = tuple(itertools.takewhile(lambda x: x < 0xFFF, generators.prime_generator())) def ix(n: int) -> ClueValue: return ClueValue(hex(n)[2:]) def xi(s: str) -> int: return int(s, 16) def digit_sum(value: ClueValue) -> int: return sum(xi(d) for d in value) def max_prime_factor(value: int) -> int: