diff --git a/2024/07/part 1 solution.py b/2024/07/part 1 solution.py new file mode 100644 index 0000000..be8910d --- /dev/null +++ b/2024/07/part 1 solution.py @@ -0,0 +1,76 @@ +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: + 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) \ No newline at end of file diff --git a/2024/07/part 2 solution.py b/2024/07/part 2 solution.py new file mode 100644 index 0000000..1677874 --- /dev/null +++ b/2024/07/part 2 solution.py @@ -0,0 +1,82 @@ +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) \ No newline at end of file