Add 2023 solutions
This commit is contained in:
163
2023/d5.py
Normal file
163
2023/d5.py
Normal file
@@ -0,0 +1,163 @@
|
||||
EXAMPLE = """
|
||||
seeds: 79 14 55 13
|
||||
|
||||
seed-to-soil map:
|
||||
50 98 2
|
||||
52 50 48
|
||||
|
||||
soil-to-fertilizer map:
|
||||
0 15 37
|
||||
37 52 2
|
||||
39 0 15
|
||||
|
||||
fertilizer-to-water map:
|
||||
49 53 8
|
||||
0 11 42
|
||||
42 0 7
|
||||
57 7 4
|
||||
|
||||
water-to-light map:
|
||||
88 18 7
|
||||
18 25 70
|
||||
|
||||
light-to-temperature map:
|
||||
45 77 23
|
||||
81 45 19
|
||||
68 64 13
|
||||
|
||||
temperature-to-humidity map:
|
||||
0 69 1
|
||||
1 0 69
|
||||
|
||||
humidity-to-location map:
|
||||
60 56 37
|
||||
56 93 4
|
||||
"""
|
||||
|
||||
def clean(text: str) -> list[str]:
|
||||
return list(text.splitlines())
|
||||
|
||||
def solve(lines: list[str]):
|
||||
seeds = []
|
||||
idx = -1
|
||||
maps = []
|
||||
|
||||
for (_, line) in enumerate(lines):
|
||||
if line.startswith("seeds:"):
|
||||
seeds = map(int, line.replace("seeds:", "").strip().split(" "))
|
||||
continue
|
||||
if line.strip() == "":
|
||||
continue
|
||||
if "map" in line:
|
||||
maps.append([])
|
||||
idx += 1
|
||||
continue
|
||||
else:
|
||||
maps[idx].append(list(map(int, line.split(" "))))
|
||||
|
||||
locs = []
|
||||
for current in seeds:
|
||||
for m in maps:
|
||||
for mapping in m:
|
||||
dest_range_start, source_range_start, range_len = mapping
|
||||
if current >= source_range_start and current < source_range_start + range_len:
|
||||
current = dest_range_start + (current - source_range_start)
|
||||
break
|
||||
else:
|
||||
current = current
|
||||
locs.append(current)
|
||||
return min(locs)
|
||||
|
||||
def solve2(lines: list[str]):
|
||||
seeds = []
|
||||
idx = -1
|
||||
maps = []
|
||||
|
||||
for (_, line) in enumerate(lines):
|
||||
if line.startswith("seeds:"):
|
||||
all_seeds = []
|
||||
seeds = list(map(int, line.replace("seeds:", "").strip().split(" ")))
|
||||
for i in range(0, len(seeds), 2):
|
||||
all_seeds.append(seeds[i:i+2])
|
||||
seeds = all_seeds
|
||||
continue
|
||||
if line.strip() == "":
|
||||
continue
|
||||
if "map" in line:
|
||||
maps.append([])
|
||||
idx += 1
|
||||
continue
|
||||
else:
|
||||
maps[idx].append(list(map(int, line.split(" "))))
|
||||
|
||||
# source: |---------------------|
|
||||
# seeds:
|
||||
# |---|
|
||||
# aaaaaabbbb
|
||||
# aaaaaabbbbbbbbbbbbbbbbbbbbbbcccc
|
||||
# aaaaaaaaaaaaaaaa
|
||||
# aaaaaaaaaaaaaaaaaaaccccc
|
||||
# |-------|
|
||||
|
||||
for m in maps:
|
||||
next_seeds = []
|
||||
while seeds:
|
||||
seed_start, seed_range = seeds.pop()
|
||||
seed_end = seed_start + seed_range
|
||||
for mapping in m:
|
||||
dest_start, source_start, m_range = mapping
|
||||
source_end = source_start + m_range
|
||||
|
||||
if seed_end <= source_start:
|
||||
continue
|
||||
elif seed_start < source_start and seed_end <= source_end:
|
||||
a_range = source_start - seed_start
|
||||
seeds.append([seed_start, a_range])
|
||||
b_range = seed_end - source_start
|
||||
next_seeds.append([dest_start, b_range])
|
||||
break
|
||||
elif seed_start < source_start and seed_end > source_end:
|
||||
a_range = source_start - seed_start
|
||||
seeds.append([seed_start, a_range])
|
||||
next_seeds.append([dest_start, m_range]) # b range
|
||||
c_range = seed_end - source_end
|
||||
next_seeds.append([source_end, c_range])
|
||||
break
|
||||
elif seed_start >= source_start and seed_end <= source_end:
|
||||
new_seed_start = dest_start + (seed_start - source_start)
|
||||
next_seeds.append([new_seed_start, seed_range])
|
||||
break
|
||||
elif seed_start >= source_start and seed_start < source_end:
|
||||
new_seed_start = dest_start + (seed_start - source_start)
|
||||
a_range = source_end - seed_start
|
||||
next_seeds.append([new_seed_start, a_range])
|
||||
c_range = seed_end - source_end
|
||||
seeds.append([source_end, c_range])
|
||||
break
|
||||
elif seed_start >= source_end:
|
||||
continue
|
||||
else:
|
||||
print(f"{seed_start=} {seed_range=} {seed_end=}")
|
||||
print(f"{source_start=} {source_end=}")
|
||||
raise Exception("Unexpected case")
|
||||
else:
|
||||
next_seeds.append([seed_start, seed_range])
|
||||
seeds = next_seeds
|
||||
return min(seeds)[0]
|
||||
|
||||
def main():
|
||||
example = clean(EXAMPLE)
|
||||
print("Example 1:", solve(example))
|
||||
|
||||
data = clean(open("d5.txt").read())
|
||||
print("Solution 1:", solve(data))
|
||||
|
||||
example = clean(EXAMPLE)
|
||||
print("Example 2:", solve2(example))
|
||||
|
||||
data = clean(open("d5.txt").read())
|
||||
print("Solution 2:", solve2(data))
|
||||
assert(solve2(data) == 63179500)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user