Advent of Code 2022 day 21
Again, relatively straightforward. Part 2 wasn’t a great deal more complicated.
I couldn’t figure out quickly a way to use eval
so hand-coded each case for
the four different operands, but hey ho.
Part 1
def parse(data, value): if value.isnumeric(): return int(value) elif value.count(" ") == 2: x, operand, y = value.split(" ") if operand == "+": return parse(data, data[x]) + parse(data, data[y]) elif operand == "-": return parse(data, data[x]) - parse(data, data[y]) elif operand == "*": return parse(data, data[x]) * parse(data, data[y]) elif operand == "/": return int(parse(data, data[x]) / parse(data, data[y])) def calculate(data): return parse(data, data["root"]) with open("21.txt") as f: lines = f.read().splitlines() data = { line.split(": ")[0]: line.split(": ")[1] for line in lines } print(calculate(data))
Part 2
def in_tree(data, key, looking_for): if key == looking_for: return True elif data[key].count(" ") == 2: x, _, y = data[key].split(" ") return in_tree(data, x, looking_for) or in_tree(data, y, looking_for) def parse(data, key): if key == "root": x, _, y = data[key].split() if in_tree(data, x, looking_for="humn"): return reverse_calc(data, parse(data, y), x) elif in_tree(data, y, looking_for="humn"): return reverse_calc(data, parse(data, x), y) elif data[key].isnumeric(): return int(data[key]) elif data[key].count(" ") == 2: x, operand, y = data[key].split(" ") if operand == "+": return parse(data, x) + parse(data, y) elif operand == "-": return parse(data, x) - parse(data, y) elif operand == "*": return parse(data, x) * parse(data, y) elif operand == "/": return int(parse(data, x) / parse(data, y)) def reverse_calc(data, value, key): if key == "humn": return value elif data[key].isnumeric(): return int(data[key]) elif data[key].count(" ") == 2: x, operand, y = data[key].split(" ") in_x = in_tree(data, x, "humn") if operand == "+": if in_x: return reverse_calc(data, value-parse(data, y), x) else: return reverse_calc(data, value-parse(data, x), y) elif operand == "-": if in_x: return reverse_calc(data, value+parse(data, y), x) else: return reverse_calc(data, parse(data, x)-value, y) elif operand == "*": if in_x: return reverse_calc(data, int(value/parse(data, y)), x) else: return reverse_calc(data, int(value/parse(data, x)), y) elif operand == "/": if in_x: return reverse_calc(data, value*parse(data, y), x) else: return reverse_calc(data, int(parse(data, x)/value), y) def calculate(data): return parse(data, "root") with open("21.txt") as f: lines = f.read().splitlines() data = { line.split(": ")[0]: line.split(": ")[1] for line in lines } print(calculate(data))