Skip to content

Instantly share code, notes, and snippets.

@live-wire
Created December 21, 2022 07:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save live-wire/cb02d5ecb86aa29056e3126945b4fe1a to your computer and use it in GitHub Desktop.
Save live-wire/cb02d5ecb86aa29056e3126945b4fe1a to your computer and use it in GitHub Desktop.
Advent of code 2022 - Day 21 solution - Python3
# time python 21.py
# python 21.py 0.48s user 0.12s system 79% cpu 0.748 total
#
#
import re
from collections import defaultdict
from sympy import solve
INPUT = '21.input'
memonkey = 'humn'
class Monkey:
def __init__(self, line):
onenum1 = re.match(r'(.*): (.+) (.) (.+)', line)
onenum2 = re.match(r'(.*): (\d+)', line)
self.dep = set()
if onenum1:
self.name = onenum1.group(1)
self.expr = onenum1.group(2) + onenum1.group(3) + onenum1.group(4)
self.dep.add(onenum1.group(2))
self.dep.add(onenum1.group(4))
elif onenum2:
self.name = onenum2.group(1)
self.expr = int(onenum2.group(2))
else:
print("ERROR", line)
def fill(self, depname, depval):
if depname in self.dep:
self.dep.remove(depname)
self.expr = self.expr.replace(depname, str(depval))
if len(self.dep) == 0:
self.expr = eval(self.expr)
return self.expr
return None
def fill2(self, depname, depval):
if depname in self.dep:
self.dep.remove(depname)
self.expr = self.expr.replace(depname, str(depval))
if len(self.dep) == 0 and memonkey not in self.expr:
self.expr = eval(self.expr)
return self.expr
return None
def __str__(self):
return f'{self.name}: {self.expr}'
def __repr__(self):
return self.__str__()
def main(lines):
monkeys = {}
dep = defaultdict(set)
root = None
for line in lines:
line = line.strip()
m = Monkey(line)
monkeys[m.name] = m
if m.name == 'root':
root = m
for d in m.dep:
dep[d].add(m.name)
while len(root.dep) > 0:
mkeys = list(monkeys.keys())
# print(mkeys)
for mname in mkeys:
m = monkeys[mname]
# print(mname, m.dep, m.expr)
if len(m.dep) == 0:
for dependant in dep[mname]:
monkeys[dependant].fill(mname, m.expr)
del dep[mname]
del monkeys[mname]
print(int(root.expr))
def main2(lines):
memonkey = 'humn'
monkeys = {}
dep = defaultdict(set)
root = None
for line in lines:
line = line.strip()
m = Monkey(line)
monkeys[m.name] = m
if m.name == memonkey:
m.expr = memonkey
elif m.name == 'root':
root = m
m.expr = m.expr.replace('+', '==')
m.expr = m.expr.replace('*', '==')
m.expr = m.expr.replace('-', '==')
m.expr = m.expr.replace('/', '==')
for d in m.dep:
dep[d].add(m.name)
while len(root.dep) > 0:
mkeys = list(monkeys.keys())
# print(mkeys)
for mname in mkeys:
m = monkeys[mname]
# print(mname, m.dep, m.expr)
if len(m.dep) == 0:
for dependant in dep[mname]:
monkeys[dependant].fill2(mname, f'({m.expr})')
del dep[mname]
del monkeys[mname]
# print(root.expr)
tosolve = root.expr.replace(memonkey, 'x')
tosolve = tosolve[1:-1]
tosolve = tosolve.replace(')==(', '-')
# print(tosolve)
sol = solve(tosolve)
print(int(sol[0]))
if __name__ == '__main__':
with open(INPUT) as f:
lines = f.readlines()
print("PART-1")
main(lines)
print("PART-2")
main2(lines)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment