Solve 2022 Day 22 pt 1-2

This is how far I got the Dec 2022 run in Elixir.

Had no idea what so ever for pt 2, so I had to
solve it by the solutions thread in the subreddit.

At first, I wondered if circular values would be the
case. It was not.

Apparently, modular arithmetics are what I lack
knowledge about.

Not entirely sure what to call the operator, it is
either a greatest common divisor or a least common
nominator.

What it actually does is to reduce the numbers by
modulo for pt 2, which will keep them low and faster
to compute.

My math is rusty.
This commit is contained in:
Anders Englöf Ytterström 2025-11-29 12:38:32 +01:00
parent f610c96257
commit 7498e79226

View file

@ -0,0 +1,74 @@
from copy import deepcopy
from collections import defaultdict
from output import ints
def solve(data):
M = []
for md in data.split("\n\n"):
m = {}
starting_items, operation, divisor, if_true, if_false = md.splitlines()[1:]
m["items"] = ints(starting_items)
m["if_false"] = ints(if_false)[0]
m["if_true"] = ints(if_true)[0]
m["divisor"] = ints(divisor)[0]
m["operation_values"] = operation.split()[-3:]
M.append(m)
p12 = []
# Part 2 resolver.
#
# Not sure what to call this, so I go for Greatest Common
# Divisor. Had to look for hints at subreddit to find it out.
# It basically fasten up the computation speed by keeping
# the numbers low.
#
# Apparently, this is common Modular arithmetic:
# https://en.wikipedia.org/wiki/Modular_arithmetic
gcd = 1
for d in [m["divisor"] for m in M]:
gcd *= d
for rounds, wld in [(20, True), (10_000, False)]:
B = defaultdict(int)
MM = deepcopy(M)
for _ in range(rounds):
for i, m in enumerate(MM):
while m["items"]:
wl = m["items"].pop(0)
B[i] += 1
x, y, z = m["operation_values"]
x = int(wl) if x == "old" else int(x)
z = int(wl) if z == "old" else int(z)
match y:
case "+":
wl = x + z
case "*":
wl = x * z
if wld:
wl = wl // 3
else:
wl = wl % gcd
if wl % m["divisor"] == 0:
MM[m["if_true"]]["items"].append(wl)
else:
MM[m["if_false"]]["items"].append(wl)
a, b, *_ = sorted(B.values(), reverse=True)
p12.append(a * b)
p1, p2 = p12
return p1, p2
def _state(M):
return tuple([(tuple(m["items"])) for m in M])
if __name__ == "__main__":
with open("./input/11.txt", "r") as f:
inp = f.read().strip()
p1, p2 = solve(inp)
print(p1)
print(p2)
assert p1 == 50616
assert p2 == 11309046332