74 lines
2.2 KiB
Python
Executable file
74 lines
2.2 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
|
|
# https://adventofcode.com/2024/day/7
|
|
|
|
def get_lines(filename: str) -> list:
|
|
with open(filename, "r") as file:
|
|
return [line.strip() for line in file.readlines()]
|
|
|
|
|
|
def parse_line(line: str) -> tuple:
|
|
value_str, right_side_str = line.split(": ")
|
|
value = int(value_str)
|
|
right_side = [int(i) for i in right_side_str.split()]
|
|
return value, right_side
|
|
|
|
|
|
def num_to_pattern(i: int, base: int, exponent: int) -> str:
|
|
if i == 0:
|
|
return "0".zfill(exponent)
|
|
nums = []
|
|
while i:
|
|
i, r = divmod(i, base)
|
|
nums.append(str(r))
|
|
return "".join(reversed(nums)).zfill(exponent)
|
|
|
|
|
|
def calculate_equation(right_side: list, pattern: str, operators: list) -> int:
|
|
value = right_side[0]
|
|
for i, op_str in enumerate(pattern):
|
|
op = operators[int(op_str)]
|
|
if op == "*":
|
|
value *= right_side[i + 1]
|
|
elif op == "+":
|
|
value += right_side[i + 1]
|
|
elif op == "|":
|
|
value = int(str(value) + str(right_side[i + 1]))
|
|
else:
|
|
raise NotImplementedError
|
|
return value
|
|
|
|
|
|
def check_validity(left_value: int, right_side: list, operators: list) -> bool:
|
|
base = len(operators)
|
|
exponent = len(right_side) - 1
|
|
for i in range(pow(base, exponent)):
|
|
pattern = num_to_pattern(i, base, exponent)
|
|
right_value = calculate_equation(right_side, pattern, operators)
|
|
if right_value == left_value:
|
|
return True
|
|
return False
|
|
|
|
|
|
def get_total_calibration_result(lines: list, operators: list) -> int:
|
|
sum_values = 0
|
|
count = 0
|
|
for line in lines:
|
|
count += 1
|
|
value, right_side = parse_line(line)
|
|
if check_validity(value, right_side, operators):
|
|
sum_values += int(value)
|
|
return sum_values
|
|
|
|
|
|
def main():
|
|
# lines = get_lines("sample-input.txt")
|
|
lines = get_lines("input.txt")
|
|
total_part1 = get_total_calibration_result(lines, ["+", "*"])
|
|
total_part2 = get_total_calibration_result(lines, ["+", "*", "|"])
|
|
print("Part 1: The total calibration result is:", total_part1)
|
|
print("Part 2: The total calibration result is:", total_part2)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|