66 lines
2.1 KiB
Python
66 lines
2.1 KiB
Python
import re
|
|
from dataclasses import dataclass
|
|
from typing import Optional, Dict, List, Tuple, OrderedDict as OrderedDictType
|
|
from collections import OrderedDict
|
|
|
|
|
|
@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], OrderedDictType[str, List[AlmanacMap]]]:
|
|
seeds = []
|
|
maps = OrderedDict(
|
|
("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
|
|
|
|
|
|
def next_maps(a_map: AlmanacMap, map_type: str, maps: OrderedDictType[str, AlmanacMap]) -> List[AlmanacMap]:
|
|
mini = a_map.destination
|
|
maxi = a_map.destination + a_map.length
|
|
maps_next_level = list(
|
|
filter(
|
|
lambda m: m.destination <= maxi and (m.destination + m.length) >= mini,
|
|
maps[maps.keys().index(map_type) + 1],
|
|
)
|
|
)
|
|
return maps_next_level
|
|
|
|
|
|
def seed_to_location_map(maps):
|
|
seed_to_location = []
|
|
for seed_group in maps["seed-to-soil"]:
|
|
return seed_to_location
|