diff --git a/day05.py b/day05.py index 48bbd26..6e0819e 100644 --- a/day05.py +++ b/day05.py @@ -1,6 +1,7 @@ from __future__ import annotations from dataclasses import dataclass from itertools import chain +import bisect import regex as re @@ -8,37 +9,65 @@ import regex as re from aoc import Aoc2, AocSameParser -@dataclass class Map: - source: str - dest: str - start_source: int - start_dest: int - id_range: int + def __init__(self, group: list[str]) -> None: + self.maps = [] - @staticmethod - def from_group(group: list[str]) -> list[Map]: - header_match = re.match(r"(?P[^-]*)-to-(?P[^ ]*) map:", group[0]) - if header_match is None: - raise RuntimeError(f'Could not parse "{group[0]}" as group header') - - source = header_match["source"] - dest = header_match["dest"] - - maps = [] for line in group[1:]: - start_source, start_dest, id_range = [ + start_dest, start_source, id_range = [ int(d) for d in re.findall(r"\d+", line) ] - maps.append(Map(source, dest, start_source, start_dest, id_range)) - return maps + bisect.insort(self.maps, (start_source, start_dest, id_range)) + + def __getitem__(self, x: int) -> int: + print(f"In {x}") + for (source, dest, rnge) in self.maps: + print(f"Source {source}") + if x >= source and x < source + rnge: + return dest + (x - source) + return x + # index = bisect.bisect_left(self.maps, (x+1,0,0)) + # index -= 1 + # if index < 0: + # return x + # + # source, dest, id_range = self.maps[index] + # if x < source + id_range: + # return dest + (x - source) + # return x + + + + def __repr__(self) -> str: + l = [] + for k, v, x in self.maps: + l.append(f"{k} - {k + x}: {v} - {v + x}") + return f"Map({', '.join(l)})" @dataclass class Problem: seeds: list[int] - maps: list[Map] + maps: dict[tuple[str,str],Map] + def convert(self, cat_from: str, cat_to:str, value: int) -> int: + target = cat_from + output_value = value + while target != cat_to: + new_target= list(filter(lambda fromto: fromto[0] == target, self.maps.keys()))[0][1] + print(f"{target}({output_value})") + output_value = self.maps[(target, new_target)][output_value] + print(f"{new_target}({output_value})") + target = new_target + return output_value + + @staticmethod + def parse_header(line: str) -> tuple[str, str]: + header_match = re.match(r"(?P[^-]*)-to-(?P[^ ]*) map:", line) + if header_match is None: + raise RuntimeError(f'Could not parse "{line}" as group header') + + return header_match["source"], header_match["dest"] @staticmethod def from_input(inpt: str) -> Problem: lines = inpt.splitlines() @@ -53,7 +82,7 @@ class Problem: groups.append([]) else: groups[-1].append(line) - maps = list(chain.from_iterable(Map.from_group(group) for group in groups)) + maps = {Problem.parse_header(group[0]): Map(group[1:]) for group in groups} return Problem(seeds, maps) @@ -64,16 +93,24 @@ class Day05(AocSameParser[Problem], Aoc2[Problem, Problem]): def parseinput(self, inpt: str) -> Problem: return Problem.from_input(inpt) - def part1(self, inpt: Problem) -> None: - print(inpt) + def part1(self, inpt: Problem) -> int: + return min(inpt.convert("seed", "location", x) for x in inpt.seeds) + + + def part2(self, inpt: Problem) -> int: + print(inpt.maps[("light", "temperature")]) + print(inpt.convert("seed", "location", 82)) + # seed_iter = iter(inpt.seeds) + # seeds = [] + # for start, rnge in zip(seed_iter, seed_iter): + # seeds.extend(range(start,start+rnge)) + # print([inpt.convert("seed", "location", x) for x in seeds]) - def part2(self, inpt: Problem) -> None: - pass def main(): day5 = Day05() - day5.run_example_1() + day5.run_example_2() if __name__ == "__main__":