diff --git a/day_07/program.py b/day_07/program.py index 66f171d..c66d735 100755 --- a/day_07/program.py +++ b/day_07/program.py @@ -1,15 +1,73 @@ #!/usr/bin/env python3 -# https://adventofcode.com/2024/day/ +# 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") + # 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__':