2023/day05.py

57 lines
1.3 KiB
Python
Raw Normal View History

2023-12-06 00:12:34 +00:00
import fileinput
import sys
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)
def transform_ranges(map, ranges):
for start, length in ranges:
# find the start of the range
2023-12-06 00:37:59 +00:00
(dst_start, src_start, len) = next(
(dst, src, len)
for (dst, src, len) in map
if src <= start < (src + len)
)
2023-12-06 00:12:34 +00:00
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)])
2023-12-06 00:42:20 +00:00
def do_the_thing(maps, ranges):
for map in maps:
ranges = transform_ranges(map, ranges)
return min(ranges)[0]
2023-12-06 00:12:34 +00:00
2023-12-06 00:42:20 +00:00
def main():
input = fileinput.input()
2023-12-06 00:12:34 +00:00
2023-12-06 00:42:20 +00:00
seeds = [int(seed) for seed in next(input).split()[1:]]
next(input)
next(input)
2023-12-06 00:12:34 +00:00
2023-12-06 00:42:20 +00:00
maps = [list(parse_map(input)) for _ in range(7)]
2023-12-06 00:12:34 +00:00
2023-12-06 00:42:20 +00:00
part1 = do_the_thing(maps, ((seed, 1) for seed in seeds))
part2 = do_the_thing(maps, zip(*[iter(seeds)] * 2))
2023-12-06 00:12:34 +00:00
2023-12-06 00:42:20 +00:00
print(part1, part2)
2023-12-06 00:12:34 +00:00
2023-12-06 00:42:20 +00:00
main()