Solve 2019 day 22
This commit is contained in:
89
2019/d22.py
89
2019/d22.py
@@ -4,6 +4,7 @@ from math import gcd
|
||||
data = get_data(__file__)
|
||||
deck = list(range(10007))
|
||||
|
||||
# part 1
|
||||
for line in data.splitlines():
|
||||
if "new stack" in line:
|
||||
deck = list(reversed(deck))
|
||||
@@ -24,30 +25,94 @@ for line in data.splitlines():
|
||||
|
||||
print(deck.index(2019))
|
||||
|
||||
# idea: just follow the index of the target card
|
||||
len = 119315717514047
|
||||
len = 10007
|
||||
index = 2019
|
||||
orig_index = 2019
|
||||
|
||||
|
||||
for i in range(101741582076661):
|
||||
for line in data.splitlines():
|
||||
# figure out how to reverse...
|
||||
index = orig_index
|
||||
for line in data.splitlines():
|
||||
if "new stack" in line:
|
||||
index = len - (index + 1)
|
||||
new_index = len - (index + 1)
|
||||
rev_index = -(new_index - len + 1)
|
||||
assert rev_index == index
|
||||
index = new_index
|
||||
elif "cut" in line:
|
||||
cut, = str_to_ints(line)
|
||||
cut = (len + cut) % len
|
||||
if index >= cut:
|
||||
index = index - cut
|
||||
new_index = index - cut
|
||||
else:
|
||||
index = (len - cut) + index
|
||||
new_index = (len - cut) + index
|
||||
rev_index = (new_index + cut) % len
|
||||
assert rev_index == index
|
||||
index = new_index
|
||||
# calculate index from new_index and store in rev_index
|
||||
elif "increment" in line:
|
||||
n, = str_to_ints(line)
|
||||
assert gcd(n, len) == 1
|
||||
new_index = (n * index) % len
|
||||
m = mod_inverse(n, len)
|
||||
assert (new_index * m) % len == index
|
||||
rev_index = (new_index * m) % len
|
||||
assert rev_index == index
|
||||
index = new_index
|
||||
break
|
||||
|
||||
print(index)
|
||||
assert index == deck.index(2019)
|
||||
|
||||
# check that reverse approach works
|
||||
for line in reversed(data.splitlines()):
|
||||
if "new stack" in line:
|
||||
index = -(index - len + 1)
|
||||
elif "cut" in line:
|
||||
cut, = str_to_ints(line)
|
||||
cut = (len + cut) % len
|
||||
index = (index + cut) % len
|
||||
elif "increment" in line:
|
||||
n, = str_to_ints(line)
|
||||
assert gcd(n, len) == 1
|
||||
m = mod_inverse(n, len)
|
||||
index = (index * m) % len
|
||||
assert index == orig_index
|
||||
|
||||
lines = list(reversed(data.splitlines()))
|
||||
|
||||
# new length of deck
|
||||
len = 119315717514047
|
||||
|
||||
# get expression for one loop using sympy
|
||||
from sympy import symbols, simplify
|
||||
index = symbols("index")
|
||||
expr = index
|
||||
for line in lines:
|
||||
if "new stack" in line:
|
||||
# index = -(index - len + 1)
|
||||
expr = -(expr - len + 1)
|
||||
elif "cut" in line:
|
||||
cut, = str_to_ints(line)
|
||||
cut = (len + cut) % len
|
||||
# index = (index + cut) % len
|
||||
expr = (expr + cut)
|
||||
elif "increment" in line:
|
||||
n, = str_to_ints(line)
|
||||
assert gcd(n, len) == 1
|
||||
m = mod_inverse(n, len)
|
||||
# index = (index * m) % len
|
||||
expr = (expr * m)
|
||||
|
||||
# we can see that expression is in the form (a - b * i) % m
|
||||
expr = simplify(expr % len)
|
||||
coeff_dict = expr.args[0].as_coefficients_dict()
|
||||
a = coeff_dict[1]
|
||||
b = -coeff_dict[index]
|
||||
|
||||
# math
|
||||
n_shuffles = 101741582076661
|
||||
r0 = 2020
|
||||
m = len
|
||||
p = (-b) % m
|
||||
p_t = pow(p, n_shuffles, m)
|
||||
inv_b1 = mod_inverse(b + 1, m)
|
||||
term1 = (p_t * r0) % m
|
||||
term2 = (a * (1 - p_t) * inv_b1) % m
|
||||
r_t = (term1 + term2) % m
|
||||
print(r_t)
|
||||
|
||||
|
||||
@@ -106,13 +106,13 @@ Solutions and utility script for Advent of Code challenges in Python.
|
||||
- Day 16: 36:10
|
||||
- Day 17: 180:00
|
||||
- Day 18: 24:04
|
||||
- Day 19: days, super fun, but hard for me
|
||||
- Day 19: days (super fun, but hard for me)
|
||||
- Day 20:
|
||||
- Day 21: 28:40 (16th - brute force but still not so bad)
|
||||
- Day 22: 185:00 (should not have been so slow but was fun)
|
||||
- Day 23: days
|
||||
- Day 24: days
|
||||
- Day 25:
|
||||
- Day 25: 29:20 (slow)
|
||||
|
||||
## AoC 2019
|
||||
|
||||
@@ -137,7 +137,8 @@ Solutions and utility script for Advent of Code challenges in Python.
|
||||
- Day 19: 40:00 (Way too slow! Oversight error. Come on.)
|
||||
- Day 20: days (Not actually that hard but I struggled for no reason.)
|
||||
- Day 21: days (But it was super fun!)
|
||||
- Day 22:
|
||||
- Day 22: days (Needed some help...)
|
||||
- Day 23:
|
||||
|
||||
## AoC 2020
|
||||
|
||||
|
||||
Reference in New Issue
Block a user