from collections.abc import Iterator
import itertools
import pathlib
import string

PRIORITY = {v: i for i, v in enumerate(string.ascii_letters, start=1)}

def parse(f: pathlib.Path) -> Iterator[str]:
    yield from f.read_text().splitlines()

def parse_line_blocks(f: pathlib.Path, block_size: int) -> Iterator[list[str]]:
    lines = f.read_text().splitlines()
    for chunk_offset in range(0, len(lines), block_size):
        yield lines[chunk_offset:chunk_offset + block_size]

def get_compartments(truck: str) -> tuple[str, str]:
    half_way = len(truck) // 2
    return truck[:half_way], truck[half_way:]

def get_shared(*args: str) -> str:
    shared = set.intersection(*map(set, args))
    return shared.pop()

def get_truck_shared_letter(truck: str) -> str:
    return get_shared(*get_compartments(truck))

def get_priority(char: str) -> int:
    return PRIORITY[char]

def part_1(f: pathlib.Path) -> int:
    shared = map(get_truck_shared_letter, parse(f))
    return sum(map(get_priority, shared))

def part_2(f: pathlib.Path) -> int:
    truck_blocks = parse_line_blocks(f, block_size=3)
    return sum(get_priority(get_shared(*block)) for block in truck_blocks)

if __name__ == '__main__':
    input_file = pathlib.Path(__file__).parent / 'input.txt'
    print(f'Part 1: {part_1(input_file)}')
    print(f'Part 2: {part_2(input_file)}')


  1. Each line in the input file represents a truck.
  2. Lowercase a through z have "priority" of 1 through 26.
  3. Uppercase A through Z have "priority" of 27 through 52.

First part

  1. Divide each truck (string) into two equal string (first half, second half).
  2. Find the single character that exists in both the first and the second part.
  3. Find that character's priority.
  4. Return the sum of all the priorities.

Second part

  1. Each time, read 3 trucks from the file.
  2. Find the shared character between all these 3 trucks.
  3. Find that single character priority.
  4. Return the sum of all the priorities.
  • 2
    \$\begingroup\$ Just out of curiosity, where do you see "trucks" in the description? I read the problem as involving elves carrying rucksacks (backpacks/bags). Your code looks very good though. \$\endgroup\$
    – ggorlen
    Dec 3, 2022 at 19:08
  • \$\begingroup\$ Oops. LOL, so rucksacks it is XD. Thanks for the compliment :) \$\endgroup\$
    – Infinity
    Dec 3, 2022 at 21:36


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.