improved day03

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

View file

@ -6,50 +6,47 @@ 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.
""" It is assumed, that we are given a valid item
Returns the priority given to each item. """
It is assumed, that we are given a valid item if 'a' <= char and char <= 'z':
""" return ord(char) - ord('a') + 1
num = ord(char) if 'A' <= char and char <= 'Z':
if ord('a') <= num and num <= ord('z'): return ord(char) - ord('A') + 27
return num - ord('a') + 1 raise Exception(f"Unknown char: {char}")
if ord('A') <= num and num <= ord('Z'):
return num - ord('A') + 27
raise Exception(f"Unknown char: {char}")
@staticmethod
def find_double(rucksack: str) -> int:
"""
Finds the priority of the one item in both compartments.
It is assumed that there is only one such item
"""
half = len(rucksack) // 2
first = rucksack[:half]
second = rucksack[half:]
for item in first:
if item in second:
return Rucksack.priority(item)
raise Exception("No double item")
@staticmethod def find_double(rucksack: str) -> str:
def find_common(group: tuple[str, ...]) -> int: """
""" Finds the one item in both compartments.
Finds the one item in all three rucksacks given. It is assumed that there is only one such item
It is assumed that there is only one such item and group has exactly three rucksacks """
""" half = len(rucksack) // 2
for item in group[0]: first = rucksack[:half]
if item in group[1] and item in group[2]: second = rucksack[half:]
return Rucksack.priority(item) for item in first:
raise Exception("No common item found") if item in second:
return item
raise Exception("No double item")
def find_common_item(group: tuple[str, str, str]) -> str:
"""
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
"""
first, second, third = group
for item in first:
if item in second and item in third:
return item
raise Exception("No common item found")