advent-of-code/2020/18/prog.py

56 lines
1.8 KiB
Python
Raw Permalink Normal View History

2023-08-02 11:39:56 +02:00
import re
calc_re = re.compile(r'(\d+) ([+*]) (\d+)')
def get_input(sample = False, part = 1):
with open(f'sample_p{part}' if sample else 'input', 'r') as f:
return [line.strip() for line in f.readlines()]
def find_closing_bracket_starting_at(index: int, string: str):
open_br = 0
for i, c in enumerate(string[index:], start=index):
if c == "(":
open_br += 1
elif c == ")":
open_br -= 1
if open_br == 0:
return i
def evaluate_advanced(calc: str):
starting_bracket = calc.find("(")
if starting_bracket != -1:
end_bracket = find_closing_bracket_starting_at(starting_bracket, calc)
return evaluate_advanced(calc[:starting_bracket] + str(evaluate_advanced(calc[starting_bracket+1:end_bracket])) + calc[end_bracket+1:])
additions = [external_group for external_group, internal_group in re.findall(r'((\d+ \+ )+\d+)', calc)]
for add in additions:
calc = calc.replace(add, str(eval(add)), 1)
return eval(calc)
def evaluate_l2r(calc: str):
starting_bracket = calc.find("(")
if starting_bracket != -1:
end_bracket = find_closing_bracket_starting_at(starting_bracket, calc)
return evaluate_l2r(calc[:starting_bracket] + str(evaluate_l2r(calc[starting_bracket+1:end_bracket])) + calc[end_bracket+1:])
match = calc_re.match(calc)
first, operation, second = match.groups()
first, second = int(first), int(second)
rest = calc[match.end():]
if operation == "+":
new = first + second
elif operation == "*":
new = first * second
return new if len(rest) == 0 else evaluate_l2r(str(new) + rest)
def get_result(inp: list, part = 1):
return sum((evaluate_l2r(op) if part == 1 else evaluate_advanced(op)) for op in inp)
if __name__ == "__main__":
print(get_result(get_input(), part = 2))