-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathday_13_2.py
More file actions
49 lines (37 loc) · 1.4 KB
/
day_13_2.py
File metadata and controls
49 lines (37 loc) · 1.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
from typing import Tuple
import numpy as np
with open('inputs/input_13.txt', 'r') as infile:
ids = infile.read().split()[1]
remainders = {int(k): (i % int(k)) for (i, k) in enumerate(ids.split(',')) if k.isdigit()}
for m in remainders.keys():
for n in remainders.keys():
if m != n:
if np.gcd(m, n) > 1:
print(f'gcd({m},{n}) = {np.gcd(m, n)}')
break
# Since all divisors are pair-wise coprime, the Chinese Remainder Theorem guarantees the existence
# of a solution smaller than their product.
# We compute using this method
# https://en.wikipedia.org/wiki/Chinese_remainder_theorem#Existence_(direct_construction)
# from https://codegolf.stackexchange.com/questions/69582/b%c3%a9zouts-identity
def bezout(a: int, b: int) -> Tuple[int, int]:
r = b
x = a # becomes gcd(a, b)
s = 0
y = 1 # the coefficient of a
t = 1
z = 0 # the coefficient of b
while r:
q = x // r
x, r = r, x % r
y, s = s, y - q * s
z, t = t, z - q * t
return y % (b // x), z % (-a // x)
bezout_v = np.vectorize(bezout, otypes=[np.int64, np.int64])
divisors = np.array(list(remainders.keys()), dtype=np.int64)
remainders = (-np.array(list(remainders.values()), dtype=np.int64)) % divisors
P = divisors.prod()
N = P // divisors
M = bezout_v(N, divisors)[0]
s = ((M * N * remainders) % P).astype(np.int64).sum()
print(int(s % P))