diff options
author | lonkaars <loek@pipeframe.xyz> | 2023-12-06 21:35:04 +0100 |
---|---|---|
committer | lonkaars <loek@pipeframe.xyz> | 2023-12-06 21:35:04 +0100 |
commit | da68ad27aecdbd19ce234eacd854d300848fed7c (patch) | |
tree | cfbc824c026cac07c3cb6e5a81995a4e8a72ccc5 /05 | |
parent | b36e0aeb8eea55d8378da4577225f27a8ca47403 (diff) |
day 5 part 2
Diffstat (limited to '05')
-rwxr-xr-x | 05/main.py | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/05/main.py b/05/main.py new file mode 100755 index 0000000..c947ab7 --- /dev/null +++ b/05/main.py @@ -0,0 +1,101 @@ +#!/bin/python3 +import sys +import re + +# i want to throw up + +numbers = [int(x) for x in input().split(":")[1].split()] +seed_ranges = [] +for x in range(0, len(numbers), 2): + seed_ranges.append((numbers[x], numbers[x] + numbers[x+1],)) + +STEPS = [ + 'seed', + 'soil', + 'fertilizer', + 'water', + 'light', + 'temperature', + 'humidity', + 'location', +] + +maps = [] +current_map = {"from": "", "to": ""} +for line in sys.stdin: + line = line.strip() + if len(line) == 0: continue + + if "map:" in line: + current_map["from"], current_map["to"] = line.split()[0].split("-to-") + else: + dest_start, source_start, range_len = [int(x) for x in line.split()] + current_map["src_range"] = (source_start, source_start + range_len,) + current_map["dest_range"] = (dest_start, dest_start + range_len,) + current_map["offset"] = dest_start - source_start + current_map["length"] = range_len + maps.append(dict(current_map)) + +output_ranges = [] +for inital_range in seed_ranges: + ranges = [inital_range] + # print(f"------ NEXT INPUT RANGE SET: {ranges} -------") + for step in STEPS[:-1]: + # print(f"[{step}] {len(ranges)} input ranges: {ranges}") + current_step_maps = [m for m in maps if m["from"] == step] + # print(f"current_step_maps\n\t" + '\n\t'.join([str(d) for d in current_step_maps])) + next_ranges = set() + for range in ranges: + applicable_maps = [m for m in current_step_maps if \ + m["src_range"][0] <= range[0] < m["src_range"][1] or \ + m["src_range"][0] < range[1] <= m["src_range"][1]] + applicable_maps = sorted(applicable_maps, key=lambda d: d["src_range"][0]) + index = range[0] + # print(f"map range {range} using maps\n\t" + '\n\t'.join([str(d) for d in applicable_maps])) + while index < range[1]: + cover_step = 0 + offset = 0 + if len(applicable_maps) == 0: + # print("> no more maps ahead!") + cover_step = range[1] - index + offset = 0 + else: + next_map = applicable_maps[0] + if next_map["src_range"][0] <= index < next_map["src_range"][1]: + # print(f"> {index} in map range") + cover_step = next_map["src_range"][1] - index + offset = next_map["offset"] + applicable_maps.pop(0) + else: + # print("> skipping until next map") + cover_step = next_map["src_range"][0] - index + offset = 0 + + cover_step = min(cover_step, range[1] - index) + next_ranges.add((index + offset, index + cover_step + offset,)) + + # print(f" creating a range with length {cover_step} and offset {offset}:") + # print(f" {(index, index + cover_step,)} -> {(index + offset, index + cover_step + offset,)}") + + index += cover_step + # print(f"> end of input range reached") + # print("\n") + ranges = sorted(list(next_ranges), key=lambda t: t[0]) + output_ranges += ranges + +seed_ranges = sorted(seed_ranges, key=lambda t: t[0]) +output_ranges = sorted(output_ranges, key=lambda t: t[0]) +for range in seed_ranges: + intersections = [m for m in output_ranges if \ + range[0] <= m[0] < range[1] or\ + range[0] < m[1] <= range[1]] + if len(intersections) == 0: continue + intersections = [ + (max(m[0], range[0]), + min(m[1], range[1]),) for m in intersections + ] + intersections = sorted(intersections, key=lambda t: t[0]) + + print(f">> {intersections[0][0]}") + break + |