Files
advent_of_code/2024/07/part 2 solution.py
T
2024-12-07 11:28:45 +00:00

82 lines
2.6 KiB
Python

import logging
# Configure logging
logging.basicConfig(filename='debug.log', level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
testing = 1
if not testing:
with open(r"2024/07/input.txt", "r") as file:
input = file.read()
else:
input = '''190: 10 19
3267: 81 40 27
83: 17 5
156: 15 6
7290: 6 8 6 15
161011: 16 10 13
192: 17 8 14
21037: 9 7 18 13
292: 11 6 16 20'''
# first we organise the input to something more usable
input = input.split('\n')
#print(input)
input = [x.split(': ') for x in input if x.strip()]
#print(input)
input = [(int(x[0]), list(map(int, x[1].split()))) for x in input]
#print(input)
# # Find and print the largest target number
# largest_target = max(input.keys())
# print(f'The largest target number is: {largest_target}')
OPERATORS = ['+', '*', '|']
def generate_expressions(numbers, current_expr=""):
if len(numbers) == 1:
yield current_expr + str(numbers[0])
else:
for operator in OPERATORS:
if operator == '|' and len(numbers) > 1:
# Concatenate the current number with the next number
concatenated_number = int(str(numbers[0]) + str(numbers[1]))
new_expr = current_expr + str(concatenated_number)
yield from generate_expressions(numbers[2:], new_expr)
elif len(numbers) > 1:
new_expr = current_expr + str(numbers[0]) + operator
yield from generate_expressions(numbers[1:], new_expr)
def evaluate_left_to_right(expr):
tokens = expr.split()
total = int(tokens[0])
i = 1
while i < len(tokens):
operator = tokens[i]
next_number = int(tokens[i + 1])
if operator == '+':
total += next_number
elif operator == '*':
total *= next_number
i += 2
return total
correct_results = []
for target, numbers in input:
logging.info(f'Processing target: {target} with numbers: {numbers}')
for expr in generate_expressions(numbers):
expr_with_spaces = expr.replace('+', ' + ').replace('*', ' * ')
result = evaluate_left_to_right(expr_with_spaces)
if int(result) == int(target):
correct_results.append(target)
logging.info(f'Tried {expr} = {result} matches {target}')
# we can break here because we only need to find one correct expression
break
else:
pass
logging.info(f'Tried {expr} = {result}, but target is {target}')
print(f'Sum of correct results: {sum(correct_results)}')
# too low 2501605300634
# print(2501605300634 - 2501605301465)