Files
advent-of-code-2023/advent_of_code/trebuchet.py
2023-12-16 16:02:06 -08:00

85 lines
2.0 KiB
Python

"Day 1: Trebuchet?!"
import re
number_word_map = {
"one": "1",
"two": "2",
"three": "3",
"four": "4",
"five": "5",
"six": "6",
"seven": "7",
"eight": "8",
"nine": "9",
"zero": "0",
}
decimal_only_pattern = re.compile("[0-9]")
left_decimal_and_words_pattern = re.compile(
"[0-9]|" + "|".join(word for word in number_word_map.keys())
)
right_decimal_and_words_pattern = re.compile(
"[0-9]|" + "|".join(word[::-1] for word in number_word_map.keys())
)
def _recover_calibration_value(
line: str,
left_symbol_pattern: re.Pattern,
right_symbol_pattern: re.Pattern,
symbol_map: dict[str, str],
) -> int:
left_symbol_match = left_symbol_pattern.search(line)
right_symbol_match = right_symbol_pattern.search(line[::-1])
if not left_symbol_match or not right_symbol_match:
raise ValueError(f'The calibration value of line "{line}" is unrecoverable.')
left_symbol = left_symbol_match.group()
right_symbol = right_symbol_match.group()[::-1]
first_digit = symbol_map.get(left_symbol, left_symbol)
second_digit = symbol_map.get(right_symbol, right_symbol)
return int(first_digit + second_digit)
def _recover_all_calibration_values(
input: str,
left_symbol_pattern: re.Pattern,
right_symbol_pattern: re.Pattern,
symbol_map: dict[str, str],
) -> int:
return sum(
_recover_calibration_value(
line,
left_symbol_pattern,
right_symbol_pattern,
symbol_map,
)
for line in input.split("\n")
)
def solve_part_1(input: str) -> str:
return str(
_recover_all_calibration_values(
input,
decimal_only_pattern,
decimal_only_pattern,
{},
)
)
def solve_part_2(input: str) -> str:
return str(
_recover_all_calibration_values(
input,
left_decimal_and_words_pattern,
right_decimal_and_words_pattern,
number_word_map,
)
)