from itertools import islice
factor_a, factor_b = 16807, 48271
def generator(start, factor, mod=1):
value = start
while True:
value *= factor
value %= 2147483647
if value % mod == 0:
yield value
def count_matches(gen_a, gen_b, limit=4 * 10**7):
return sum(
1 for a, b in islice(zip(gen_a, gen_b), limit) if a & 0xFFFF == b & 0xFFFF
)
test_gen_a, test_gen_b = generator(65, factor_a), generator(8921, factor_b)
tests = [
(1092455, 430625591),
(1181022009, 1233683848),
(245556042, 1431495498),
(1744312007, 137874439),
(1352636452, 285222916),
]
for expected_a, expected_b in tests:
assert (next(test_gen_a), next(test_gen_b)) == (expected_a, expected_b)
tests = [
(1352636452, 1233683848),
(1992081072, 862516352),
(530830436, 1159784568),
(1980017072, 1616057672),
(740335192, 412269392),
]
test_gen_a, test_gen_b = generator(65, factor_a, 4), generator(8921, factor_b, 8)
for expected_a, expected_b in tests:
assert (next(test_gen_a), next(test_gen_b)) == (expected_a, expected_b)
test_gen_a, test_gen_b = generator(65, factor_a), generator(8921, factor_b)
assert count_matches(test_gen_a, test_gen_b) == 588
test_gen_a, test_gen_b = generator(65, factor_a, 4), generator(8921, factor_b, 8)
assert count_matches(test_gen_a, test_gen_b, 5 * 10**6) == 309
import aocd
data = aocd.get_data(day=15, year=2017)
start_a, start_b = (int(line.rpartition(" ")[-1]) for line in data.splitlines())
print(
"Part 1:", count_matches(generator(start_a, factor_a), generator(start_b, factor_b))
)
Part 1: 573
print(
"Part 2:",
count_matches(
generator(start_a, factor_a, 4), generator(start_b, factor_b, 8), 5 * 10**6
),
)
Part 2: 294