The seventh day of Advent of Code was yesterday 07/12/2024! If you’re here for the first time today, don’t forget to read the posts about Day 1, Day 2, Day 3, Day 4, Day 5 and Day 6.

I classified the seventh problem as easy (part 1) and easy (part 2).

Tips#

  • Part 1 consists of applying a list of operations on a list of operands.

  • You will have more operands than operators.

  • You can use iter and next to combine lists of different sizes.

  • To generate all combinations between operations by the number of operands, you can use product from itertools.

  • Part 2 is identical to part 1, but with an additional operation.

How much Python do you need to know?#

The chapters refer to my book Introduction to Programming with Python.

  • Lists - Chapter 6
  • Generators, Partial Function Application, zip, itertools - Chapter 8

Answer#

from operator import add, mul
from itertools import product

from aux import read_file_without_blank_lines

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"""


def concatenate_integers(a: int, b: int) -> int:
    return int(str(a) + str(b))


def input_to_matrix(input: list[str]) -> list[list[int]]:
    return [
        [int(n) for n in line.replace(":", "").split()]
        for line in input.splitlines()
        if line
    ]


OPERATORS = [add, mul]

OPERATORS_PART2 = OPERATORS + [concatenate_integers]


def sum_valid(input, operators=OPERATORS) -> int:
    valid = 0
    for result, *operands in input:
        for operations in product(operators, repeat=len(operands) - 1):
            p = iter(operands)
            value = next(p)
            for operand, operation in zip(p, operations):
                value = operation(value, operand)
            if value == result:
                valid += result
                break
    return valid


test_input = input_to_matrix((INPUT))

valid = sum_valid(test_input)
print("Valid (test - part 1):", valid)
assert valid == 3749

input_part_1 = read_file_without_blank_lines("07/input.txt")
valid = sum_valid(input_to_matrix(input_part_1))
print("Valid (part 1):", valid)
assert valid == 7885693428401


valid = sum_valid(test_input, OPERATORS_PART2)
print("Valid (test - part 2):", valid)
assert valid == 11387

valid = sum_valid(input_to_matrix(input_part_1), OPERATORS_PART2)
print("Valid (part 2):", valid)
assert valid == 348360680516005

# Output
# Valid (test - part 1): 3749
# Valid (part 1): 7885693428401
# Valid (test - part 2): 11387
# Valid (part 2): 348360680516005