47 lines
1.5 KiB
Python
47 lines
1.5 KiB
Python
import re
|
|
from dataclasses import dataclass
|
|
from typing import Optional, Dict, List, Tuple
|
|
|
|
|
|
@dataclass
|
|
class AlmanacMap:
|
|
destination: int
|
|
source: int
|
|
length: int
|
|
|
|
def is_mapped(self, source: int) -> bool:
|
|
return self.source <= source < self.source + self.length
|
|
|
|
def mapped_value(self, source: int) -> Optional[int]:
|
|
if not self.is_mapped(source):
|
|
return None
|
|
return self.destination + (source - self.source)
|
|
|
|
|
|
def extract(input_file: str) -> Tuple[List[int], Dict[str, List[AlmanacMap]]]:
|
|
seeds = []
|
|
maps = {
|
|
"seed-to-soil": [],
|
|
"soil-to-fertilizer": [],
|
|
"fertilizer-to-water": [],
|
|
"water-to-light": [],
|
|
"light-to-temperature": [],
|
|
"temperature-to-humidity": [],
|
|
"humidity-to-location": [],
|
|
}
|
|
|
|
with open(input_file) as input:
|
|
current_map = {}
|
|
while line := input.readline():
|
|
if match := re.match("seeds: (.*)", line):
|
|
for seed in match.group(1).split(" "):
|
|
seeds.append(int(seed))
|
|
continue
|
|
if match := re.match("([a-z-]+) map:", line):
|
|
current_map = maps[match.group(1)]
|
|
continue
|
|
if match := re.match("([\d ]+)", line):
|
|
destination, source, length = match.group(1).split(" ")
|
|
current_map.append(AlmanacMap(destination=int(destination), source=int(source), length=int(length)))
|
|
return seeds, maps
|