|
@@ -0,0 +1,68 @@
|
|
|
+lines = [int(line) for line in open("20.input")]
|
|
|
+
|
|
|
+def show(nxt):
|
|
|
+ start = 0
|
|
|
+ current = start
|
|
|
+ while True:
|
|
|
+ print(lines[current], " ", end="")
|
|
|
+ current = nxt[current]
|
|
|
+ if current == start:
|
|
|
+ break
|
|
|
+
|
|
|
+ print("")
|
|
|
+
|
|
|
+full_circ = len(lines) - 1
|
|
|
+
|
|
|
+def mix(lines, repeat=1):
|
|
|
+ nxt = {i: i+1 for i in range(len(lines)-1)}
|
|
|
+ nxt[len(lines)-1] = 0
|
|
|
+
|
|
|
+ prev = {v: k for k, v in nxt.items()}
|
|
|
+
|
|
|
+ for i in range(repeat):
|
|
|
+ print("Iteration", i + 1)
|
|
|
+ for num, val in enumerate(lines):
|
|
|
+ if val > 0:
|
|
|
+ target = num
|
|
|
+ for i in range(val % full_circ):
|
|
|
+ target = nxt[target]
|
|
|
+ if target == num:
|
|
|
+ continue
|
|
|
+
|
|
|
+ nxt[prev[num]] = nxt[num]
|
|
|
+
|
|
|
+ tmp_nxt = nxt[target]
|
|
|
+ nxt[target] = num
|
|
|
+ nxt[num] = tmp_nxt
|
|
|
+
|
|
|
+ prev = {v: k for k, v in nxt.items()}
|
|
|
+
|
|
|
+ elif val < 0:
|
|
|
+ target = num
|
|
|
+ for i in range((-val) % full_circ):
|
|
|
+ target = prev[target]
|
|
|
+ if target == num:
|
|
|
+ continue
|
|
|
+
|
|
|
+ prev[nxt[num]] = prev[num]
|
|
|
+
|
|
|
+ tmp_prev = prev[target]
|
|
|
+ prev[target] = num
|
|
|
+ prev[num] = tmp_prev
|
|
|
+
|
|
|
+ nxt = {v: k for k, v in prev.items()}
|
|
|
+
|
|
|
+ #show(nxt)
|
|
|
+
|
|
|
+ total = 0
|
|
|
+
|
|
|
+ current = max(i for i, v in enumerate(lines) if v == 0)
|
|
|
+ for i in range(1, 3001):
|
|
|
+ current = nxt[current]
|
|
|
+ if i % 1000 == 0:
|
|
|
+ total += lines[current]
|
|
|
+
|
|
|
+ return total
|
|
|
+
|
|
|
+print("Part 1:", mix(lines, 1))
|
|
|
+print("Part 2:", mix([811589153 * x for x in lines], 10))
|