Example #1
0
 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
Example #2
0
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
Example #3
0
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
Example #4
0
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)
Example #5
0

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: