Created
December 21, 2022 07:35
-
-
Save live-wire/cb02d5ecb86aa29056e3126945b4fe1a to your computer and use it in GitHub Desktop.
Advent of code 2022 - Day 21 solution - Python3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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