Day 05 (optimized)
This commit is contained in:
@@ -3,29 +3,10 @@ from typing import List, Tuple
|
|||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
|
|
||||||
lines = (x.strip() for x in open("input.txt"))
|
lines = (x.strip() for x in open("input.txt"))
|
||||||
seeds = ()
|
seeds = list(int(y) for y in next(lines)[7:].split(" "))
|
||||||
current_map = "undef"
|
curr_map = None
|
||||||
maps = {}
|
|
||||||
map_names = []
|
|
||||||
|
|
||||||
for line in lines:
|
def items_to_map(value: List[Tuple[int, int, int]]):
|
||||||
match line:
|
|
||||||
case "" | "\n":
|
|
||||||
continue
|
|
||||||
case x if x.startswith("seeds: "):
|
|
||||||
rest = x[len("seeds: "):]
|
|
||||||
seeds = tuple(int(y) for y in rest.split(" "))
|
|
||||||
case x if x.endswith(" map:"):
|
|
||||||
rest = x[:-len(" map:")]
|
|
||||||
current_map = rest
|
|
||||||
maps[current_map] = []
|
|
||||||
map_names.append(current_map)
|
|
||||||
case x if len(x) and x[0].isdigit():
|
|
||||||
maps[current_map].append(tuple(int(y) for y in x.split(" ")))
|
|
||||||
case _:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def parse_map(value: List[Tuple[int, int, int]]):
|
|
||||||
curr = 0
|
curr = 0
|
||||||
out = []
|
out = []
|
||||||
for dest, src, size in sorted(value, key=lambda x: x[1]):
|
for dest, src, size in sorted(value, key=lambda x: x[1]):
|
||||||
@@ -37,36 +18,43 @@ def parse_map(value: List[Tuple[int, int, int]]):
|
|||||||
out.append((curr, 0))
|
out.append((curr, 0))
|
||||||
return out
|
return out
|
||||||
|
|
||||||
maps = {name: parse_map(value) for name, value in maps.items()}
|
def iter_maps(lines):
|
||||||
|
next_items = []
|
||||||
|
for line in lines:
|
||||||
|
if len(line) and line[0].isdigit():
|
||||||
|
next_items.append(tuple(int(y) for y in line.split(" ")))
|
||||||
|
elif len(next_items):
|
||||||
|
yield items_to_map(next_items)
|
||||||
|
next_items = []
|
||||||
|
if len(next_items):
|
||||||
|
yield items_to_map(next_items)
|
||||||
|
|
||||||
|
|
||||||
def find_largest_smaller_value(sorted_list, x):
|
def find_largest_smaller_value(sorted_list, x):
|
||||||
low, high = 0, len(sorted_list)
|
low, high = 0, len(sorted_list)
|
||||||
|
|
||||||
while low < high - 1:
|
while low < high - 1:
|
||||||
mid = (low + high) // 2
|
mid = (low + high) // 2
|
||||||
if sorted_list[mid][0] <= x:
|
if sorted_list[mid][0] <= x:
|
||||||
low = mid
|
low = mid
|
||||||
else:
|
else:
|
||||||
high = mid
|
high = mid
|
||||||
|
|
||||||
return sorted_list[low], low
|
return sorted_list[low], low
|
||||||
|
|
||||||
|
|
||||||
def merge_list(curr_map, next_map):
|
def merge_maps(curr_map, next_map):
|
||||||
next_mapping = []
|
merged_map = []
|
||||||
for i in range(0, len(curr_map)):
|
for i in range(0, len(curr_map)):
|
||||||
dest_start = curr_map[i][0] + curr_map[i][1]
|
dest_start = curr_map[i][0] + curr_map[i][1]
|
||||||
dest_start_idx = find_largest_smaller_value(next_map, dest_start)[1]
|
dest_start_idx = find_largest_smaller_value(next_map, dest_start)[1]
|
||||||
dest_end = curr_map[i + 1][0] + curr_map[i][1] - 1 if i + 1 < len(curr_map) else None
|
dest_end = curr_map[i + 1][0] + curr_map[i][1] - 1 if i + 1 < len(curr_map) else None
|
||||||
dest_end_idx = find_largest_smaller_value(next_map, dest_end)[1] if dest_end is not None else len(next_map) - 1
|
dest_end_idx = find_largest_smaller_value(next_map, dest_end)[1] if dest_end is not None else len(next_map) - 1
|
||||||
for next_start, next_offset in next_map[dest_start_idx:dest_end_idx + 1]:
|
for next_start, next_offset in next_map[dest_start_idx:dest_end_idx + 1]:
|
||||||
next_mapping.append((max(curr_map[i][0], next_start - curr_map[i][1]), curr_map[i][1] + next_offset))
|
merged_map.append((max(curr_map[i][0], next_start - curr_map[i][1]), curr_map[i][1] + next_offset))
|
||||||
return next_mapping
|
return merged_map
|
||||||
|
|
||||||
# merge lists into a single one
|
|
||||||
curr_map = maps[map_names[0]]
|
for next_map in iter_maps(lines):
|
||||||
for name in map_names[1:]:
|
curr_map = next_map if curr_map is None else merge_maps(curr_map, next_map)
|
||||||
curr_map = merge_list(curr_map, maps[name])
|
|
||||||
|
|
||||||
|
|
||||||
result = float("inf")
|
result = float("inf")
|
||||||
|
|||||||
Reference in New Issue
Block a user