-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathday05.py
87 lines (77 loc) · 2.21 KB
/
day05.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
from benchy import minibench
lines = open("day05.txt").read().split("\n")
lines.append(":")
numbers = []
ranges = []
steps = []
def parse():
s = lines[0].split()
numbers.clear()
ranges.clear()
steps.clear()
numbers.extend(map(int, s[1:]))
for i in range(len(numbers) // 2):
ranges.append((numbers[2 * i], numbers[2 * i] + numbers[2 * i + 1] - 1))
cur = []
for line in lines[3:]:
if not line:
continue
if line[-1] == ":":
cur.sort()
steps.append(cur)
cur = []
continue
(dst, src, l) = map(int, line.split())
cur.append((src, dst, l))
return 0
def part1():
work = numbers.copy()
for step in steps:
next = []
for n in work:
for src, dst, l in step:
if n >= src + l:
continue
if n < src:
next.append(n)
else:
next.append(n + dst - src)
n = -1
break
if n >= 0:
next.append(n)
work = next
return min(work)
def part2():
work = ranges.copy()
for step in steps:
next = []
for a, b in work:
for src, dst, l in step:
ofs = dst - src
if a >= src + l:
continue
if a < src: # some is untranslated
next.append((a, src - 1))
a = src
# a >= src.
if b >= src + l: # some range remains
next.append((a + ofs, (src + l - 1) + ofs))
a = src + l
else: # everything fits
next.append((a + ofs, b + ofs))
a = b + 1
break
if a <= b: # some was left untranslated
next.append((a, b))
work = []
for a, b in sorted(next):
if work and (a == work[-1][1] + 1):
work[-1] = (work[-1][0], b)
else:
work.append((a, b))
return work[0][0]
parse()
print(part1())
print(part2())
minibench({"parse": parse, "part1": part1, "part2": part2})