improved day03

This commit is contained in:
Ruediger Ludwig 2022-12-03 09:07:45 +01:00
parent c95e1d02ec
commit 3a8ded02ae

View file

@ -6,33 +6,29 @@ day_num = 3
def part1(lines: Iterator[str]) -> int: def part1(lines: Iterator[str]) -> int:
return sum(Rucksack.find_double(line) for line in lines) return sum(priority(find_double(line)) for line in lines)
def part2(lines: Iterator[str]) -> int: def part2(lines: Iterator[str]) -> int:
groups = [lines] * 3 groups = zip(lines, lines, lines, strict=True)
zipped = zip(*groups, strict=True) return sum(priority(find_common_item(group)) for group in groups)
return sum(Rucksack.find_common(group) for group in zipped)
class Rucksack: def priority(char: str) -> int:
@staticmethod
def priority(char: str) -> int:
""" """
Returns the priority given to each item. Returns the priority given to each item.
It is assumed, that we are given a valid item It is assumed, that we are given a valid item
""" """
num = ord(char) if 'a' <= char and char <= 'z':
if ord('a') <= num and num <= ord('z'): return ord(char) - ord('a') + 1
return num - ord('a') + 1 if 'A' <= char and char <= 'Z':
if ord('A') <= num and num <= ord('Z'): return ord(char) - ord('A') + 27
return num - ord('A') + 27
raise Exception(f"Unknown char: {char}") raise Exception(f"Unknown char: {char}")
@staticmethod
def find_double(rucksack: str) -> int: def find_double(rucksack: str) -> str:
""" """
Finds the priority of the one item in both compartments. Finds the one item in both compartments.
It is assumed that there is only one such item It is assumed that there is only one such item
""" """
half = len(rucksack) // 2 half = len(rucksack) // 2
@ -40,16 +36,17 @@ class Rucksack:
second = rucksack[half:] second = rucksack[half:]
for item in first: for item in first:
if item in second: if item in second:
return Rucksack.priority(item) return item
raise Exception("No double item") raise Exception("No double item")
@staticmethod
def find_common(group: tuple[str, ...]) -> int: def find_common_item(group: tuple[str, str, str]) -> str:
""" """
Finds the one item in all three rucksacks given. Finds the one item in all three rucksacks given.
It is assumed that there is only one such item and group has exactly three rucksacks It is assumed that there is only one such item and group has exactly three rucksacks
""" """
for item in group[0]: first, second, third = group
if item in group[1] and item in group[2]: for item in first:
return Rucksack.priority(item) if item in second and item in third:
return item
raise Exception("No common item found") raise Exception("No common item found")