Bläddra i källkod

Description of solution

master
Noëlle Anthony 11 månader sedan
förälder
incheckning
f3bc4eaa39
1 ändrade filer med 62 tillägg och 3 borttagningar
  1. 62
    3
      day05-2.py

+ 62
- 3
day05-2.py Visa fil

@@ -4,6 +4,14 @@ helper = Helper(debug=True)
load_input = helper.load_input
debug = helper.debug

# FUTURE ME: HERE'S THE KEY
# You don't have to check every seed.
# Instead, create ranges, and use the later steps to cut those ranges
# into chunks. The smallest value in the smallest chunk after the last
# step is the solution. The brute-force solution takes an enormous amount
# of time; the chunk solution is still polynomial time, I think, but
# the n is much smaller (dozens rather than hundreds of millions).

def within(target, start, end):
if start == end:
return target == start
@@ -11,6 +19,40 @@ def within(target, start, end):
start, end = end, start
return target >= start and end >= target

def chunk_it(old_range, new_range):
o_start, o_end = old_range
n_start, n_end = new_range
debug(o_start, o_end, n_start, n_end)

# The new range is entirely outside the current range
if n_end < o_start or n_start > o_end:
debug("Entirely outside!")
return sorted([old_range, new_range], key=lambda n:n[0])
# The new range is entirely within the current range
if n_start >= o_start and n_end <= o_end:
# We've already accounted for this range
debug("Already got it")
return [old_range]

# The new range starts lower and ends higher
if n_start <= o_start and n_end >= o_end:
# We can replace the old range with the new one
debug("Replacement!")
return [new_range]

# The new range starts lower but ends within
if n_start <= o_start and n_end >= o_start and n_end <= o_end:
debug("Starts before")
return [[n_start, o_end]]

# The new range starts within but ends higher
if n_end >= o_end and n_start >= o_start and n_start <= o_end:
debug("Ends after")
return [[o_start, n_end]]
raise Exception(f"What? What? Nothing matched: {old_range}, {new_range}")

def main():
lines = load_input(5)

@@ -26,10 +68,29 @@ def main():
}
maps_keys = list(maps_dict.keys())
maps_dict["seeds"] = [int(n) for n in lines[0].split()[1:]]
debug(f"Starting with {len(maps_dict['seeds'])//2} ranges")
real_seeds = []
i, j = 0, 1
while j < len(maps_dict["seeds"]):
real_seeds.append((maps_dict["seeds"][i], maps_dict["seeds"][i] + maps_dict["seeds"][j]))
new_range = [maps_dict["seeds"][i], maps_dict["seeds"][i] + maps_dict["seeds"][j]]
if len(real_seeds) == 0:
real_seeds.append(new_range)
else:
new_real_seeds = []
for range in real_seeds:
add_ranges = chunk_it(range, new_range)
debug(add_ranges)
for r in add_ranges:
if r not in new_real_seeds:
new_real_seeds.append(r)
real_seeds = list(new_real_seeds)
i += 2
j += 2
debug(real_seeds, i, j)
debug(f"Found {len(real_seeds)} actual ranges")
real_seeds.sort(key=lambda n: n[0])
# debug(real_seeds)
return
# new_start = maps_dict["seeds"][i]
# new_end = new_start + maps_dict["seeds"][j]
# debug(f"Adding seeds in range {new_start}-{new_end}")
@@ -37,8 +98,6 @@ def main():
# debug(new_seeds)
# real_seeds.append(new_seeds)
# debug(real_seeds)
i += 2
j += 2
seeds_list = [{"seed": seed[1]} for seed in real_seeds]
current_key = ""

Laddar…
Avbryt
Spara