56 lines
1.8 KiB
Python
56 lines
1.8 KiB
Python
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))
|