76 lines
1.6 KiB
Python
76 lines
1.6 KiB
Python
from collections.abc import Iterable
|
|
from pathlib import Path
|
|
|
|
|
|
def find_all(needle: str, haystack: str) -> Iterable[int]:
|
|
start = 0
|
|
index = haystack.find(needle, start)
|
|
while index >= 0:
|
|
yield index
|
|
start = index + 1
|
|
index = haystack.find(needle, start)
|
|
|
|
|
|
def numberfy(s: str) -> str:
|
|
nums = {
|
|
"one": 1,
|
|
"two": 2,
|
|
"three": 3,
|
|
"four": 4,
|
|
"five": 5,
|
|
"six": 6,
|
|
"seven": 7,
|
|
"eight": 8,
|
|
"nine": 9,
|
|
}
|
|
|
|
result = [""] * len(s)
|
|
for num_s, num_i in nums.items():
|
|
for index in find_all(num_s, s):
|
|
result[index] = str(num_i)
|
|
|
|
for i, c in enumerate(s):
|
|
if c.isnumeric():
|
|
result[i] = c
|
|
|
|
return "".join(result)
|
|
|
|
|
|
def part1(path: Path) -> int:
|
|
total = 0
|
|
with path.open() as f:
|
|
for line in f:
|
|
first: str = ""
|
|
last: str = ""
|
|
for c in line:
|
|
if not c.isnumeric():
|
|
continue
|
|
if not first:
|
|
first = c
|
|
continue
|
|
last = c
|
|
if not last:
|
|
last = first
|
|
line_total = int(first+last)
|
|
total += line_total
|
|
|
|
return total
|
|
|
|
|
|
def part2(path: Path) -> int:
|
|
total = 0
|
|
with path.open() as f:
|
|
for line in f:
|
|
line_nums = numberfy(line)
|
|
line_total = int(line_nums[0]+line_nums[-1])
|
|
total += line_total
|
|
|
|
return total
|
|
|
|
|
|
if __name__ == "__main__":
|
|
input = Path("input.txt")
|
|
|
|
print("part 1", part1(input))
|
|
print("part 2", part2(input))
|