-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday_05.py
102 lines (73 loc) · 2.52 KB
/
day_05.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
from colorist import *
import aoc_helper
from aoc_helper import (
extract_ints,
list,
range,
)
import sys
EXAMPLE = "EXAMPLE" in sys.argv
TWO = "2" in sys.argv
DAY = 5
YEAR = 2023
if EXAMPLE:
if TWO:
raw, answer = aoc_helper.get_sample_input(day=DAY, year=YEAR, part=2)
else:
raw, answer = aoc_helper.get_sample_input(day=DAY, year=YEAR, part=1)
else:
raw = aoc_helper.fetch(DAY, YEAR)
s = raw.split("\n\n")
seeds = extract_ints(s[0])
def x_to_y_map_1(description:str, inputs: list[int]):
ranges = [tuple(extract_ints(i)) for i in description.splitlines()[1:]]
ans = []
for i in inputs:
for dest, sour, ln in ranges:
if 0 <= (i - sour) < ln:
ans.append(dest + i - sour)
break
else:
ans.append(i)
return ans
# part 1
ok = seeds[::]
for hmm in s[1:]: ok = x_to_y_map_1(hmm, ok)
print(f"Part 1: {BrightColor.CYAN}{min(ok)}{BrightColor.OFF}")
# part 2
seed_ranges = list((seeds[i], seeds[i+1]) for i in range(0, len(seeds), 2))
def strt_ln_to_strt_end(start, len): return (start, start + len - 1)
def strt_end_to_strt_ln(start, end): return (start, end - start + 1)
def intersect_ranges(range1, range2):
"""
returns common, part_of_seed_not_intersecting
range1 is the seed
range2 is the source_map
"""
strt1, end1 = strt_ln_to_strt_end(*range1)
strt2, end2 = strt_ln_to_strt_end(*range2)
strt, end = max(strt1, strt2), min(end1, end2)
if end < strt: return [], [range1]
diff =[]
if strt1 < strt: diff.append(strt_end_to_strt_ln(strt1, strt-1))
if end < end1: diff.append(strt_end_to_strt_ln(end+1, end1))
return [ strt_end_to_strt_ln(strt, end) ], diff
def x_to_y_map_2(description:str, inputs: list[tuple[int,int]]):
ranges = [tuple(extract_ints(i)) for i in description.splitlines()[1:]]
ans = []
not_handled = inputs[::]
new_not_handled = []
for dest, sour, ln in ranges:
for seedrng in not_handled:
comm, diff = intersect_ranges(seedrng, (sour, ln))
if comm:
ans.append((comm[0][0]+dest-sour, comm[0][1]))
if diff:
new_not_handled.extend(diff)
not_handled = new_not_handled.copy()
new_not_handled = []
ans.extend(not_handled)
return ans
ok = seed_ranges[::]
for hmm in s[1:]: ok = x_to_y_map_2(hmm, ok)
print(f"Part 2: {BrightColor.CYAN}{min(ok)[0]}{BrightColor.OFF}")