#! /usr/bin/env python3 operators = { "+": lambda x, y: x + y, "-": lambda x, y: x - y, "*": lambda x, y: x * y, "/": lambda x, y: x / y, } def evaluate(s): num_s = "" num = None left_num = None op = None s = s+" " inner = None level = 0 for c in s: # print(f"reading {c} level {level} left: {left_num} inner: {inner}") if c == ")": # print("close paren") level -= 1 if level == 0: # print("eval inner", inner) num = evaluate(inner) # print(f"finished evaluating {inner}, Result was: {num}") inner = None else: inner += c elif c == "(": # Start to read innner # print("start reading inner paren") if inner is None: inner = "" else: inner += c level += 1 pass elif inner is not None: inner += c # print("append to inner paren", inner) elif c.isnumeric(): num_s += c elif c == " " and num_s: # print("got number") num = int(num_s) num_s = "" elif c in operators: op = operators[c] if num is not None and left_num is None: # print(f"putting {num} on left") left_num = num num = None # Evaluate if left_num is not None and num is not None: # print(f"evaluating {left_num} {op} {num}") left_num = op(left_num, num) # print(f"new left is {left_num}") num = None op = None return left_num or 0 def part1(): # r = evaluate("1 + (2 * 3)") # r = evaluate("1 + (2 * 3) + (4 * (5 + 6))") # r = evaluate("1 + 2 * 3 + 4 * 5 + 6") # r = evaluate("((2 + 4 * 9) * (6 + 9 * 8 + 6) + 6) + 2 + 4 * 2") # print(r) # return total = 0 with open("input.txt") as f: for line in f: line.strip() v = evaluate(line) print(v) total += v print("sum: ", total) if __name__ == "__main__": part1()