I think I found a decently short solution for part 2 in python:
DIGITS = {
'one': '1',
'two': '2',
'three': '3',
'four': '4',
'five': '5',
'six': '6',
'seven': '7',
'eight': '8',
'nine': '9',
}
def find_digit(word: str) -> str:
for digit, value in DIGITS.items():
if word.startswith(digit):
return value
if word.startswith(value):
return value
return ''
total = 0
for line in puzzle.split('\n'):
digits = [
digit for i in range(len(line))
if (digit := find_digit(line[i:]))
]
total += int(digits[0] + digits[-1])
print(total)
It simply finds all possible digits and then locates the last one through the reverse indexing. It’s not efficient because there’s no shortcircuiting, but there’s no need to search the strings backwards, which is nice. Python’s startswith method is also hiding a lot of that other implementations have done explicitly.