summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlonkaars <loek@pipeframe.xyz>2023-12-06 21:35:04 +0100
committerlonkaars <loek@pipeframe.xyz>2023-12-06 21:35:04 +0100
commitda68ad27aecdbd19ce234eacd854d300848fed7c (patch)
treecfbc824c026cac07c3cb6e5a81995a4e8a72ccc5
parentb36e0aeb8eea55d8378da4577225f27a8ca47403 (diff)
day 5 part 2
-rwxr-xr-x05/main.py101
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
+