From 6fdf2e641d1d06ff5b1f47ef2a6fe6213015f070 Mon Sep 17 00:00:00 2001 From: Sijmen Date: Wed, 6 Dec 2023 01:12:34 +0100 Subject: [PATCH] Add day 5 --- day05.py | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 day05.py diff --git a/day05.py b/day05.py new file mode 100644 index 0000000..020f553 --- /dev/null +++ b/day05.py @@ -0,0 +1,81 @@ +import fileinput +import sys + +input = fileinput.input() + +seeds = [int(seed) for seed in next(input).split()[1:]] +next(input) +next(input) + + +def parse_map(input): + try: + while line := next(input).strip(): + yield tuple(int(n) for n in line.strip().split()) + next(input) + except StopIteration: + pass + + yield (0, 0, sys.maxsize) + + +seed_to_soil = list(parse_map(input)) +soil_to_fert = list(parse_map(input)) +fert_to_water = list(parse_map(input)) +water_to_light = list(parse_map(input)) +light_to_temp = list(parse_map(input)) +temp_to_humid = list(parse_map(input)) +humid_to_loc = list(parse_map(input)) + + +def transform_ranges(map, ranges): + for start, length in ranges: + # find the start of the range + (dst_start, src_start, len) = next((dst, src, len) for (dst, src, len) in map if src <= start < (src + len)) + + end = start + length + src_end = src_start + len + + # yield the starting range + yield (dst_start + start - src_start, min(src_end, end) - start) + + # if range is not complete, recurse into the rest + if end > src_end: + yield from transform_ranges(map, [(src_end, end - src_end)]) + + +def part1(): + result = sys.maxsize + + for seed in seeds: + soil = next(dst + seed - src for (dst, src, len) in seed_to_soil if src <= seed < (src + len)) + fert = next(dst + soil - src for (dst, src, len) in soil_to_fert if src <= soil < (src + len)) + water = next(dst + fert - src for (dst, src, len) in fert_to_water if src <= fert < (src + len)) + light = next(dst + water - src for (dst, src, len) in water_to_light if src <= water < (src + len)) + temp = next(dst + light - src for (dst, src, len) in light_to_temp if src <= light < (src + len)) + humid = next(dst + temp - src for (dst, src, len) in temp_to_humid if src <= temp < (src + len)) + loc = next(dst + humid - src for (dst, src, len) in humid_to_loc if src <= humid < (src + len)) + result = min(result, loc) + + return result + + +def part2(): + result = sys.maxsize + + for start, len in zip(*(iter(seeds),) * 2): + soils = transform_ranges(seed_to_soil, [(start, len)]) + ferts = transform_ranges(soil_to_fert, soils) + waters = transform_ranges(fert_to_water, ferts) + lights = transform_ranges(water_to_light, waters) + temps = transform_ranges(light_to_temp, lights) + humids = transform_ranges(temp_to_humid, temps) + locs = transform_ranges(humid_to_loc, humids) + + (loc, _) = min(locs) + result = min(result, loc) + + return result + + +print(part1(), part2())