Browse Source

Much faster solution to day 23

Frans Bergman 4 years ago
parent
commit
12f83baa4b
1 changed files with 34 additions and 32 deletions
  1. 34 32
      23.py

+ 34 - 32
23.py

@@ -1,30 +1,36 @@
-from collections import deque
-from time import time
-
 input = "137826495"
 input = "137826495"
 #input = "389125467"
 #input = "389125467"
 cups = [int(i) for i in list(input)]
 cups = [int(i) for i in list(input)]
 max_cup = max(cups)
 max_cup = max(cups)
 
 
-def my_popleft(cups, following):
+def ring_str(after):
-    current = cups.popleft()
+    result = ""
-    if current in following:
+    current = 1
-        cups.extendleft(following[current])
+    printed = []
-        del following[current]
+    while current not in printed:
-    return current
+        result += str(current)
+        printed.append(current)
+        current = after[current]
+    return result
+
 
 
 def run_on_cups(cups, iterations):
 def run_on_cups(cups, iterations):
     cup_count = len(cups)
     cup_count = len(cups)
     max_cup = max(cups)
     max_cup = max(cups)
-    following = {}
+    after = {}
-    start = time()
+    for i in range(0, cup_count - 1):
-    print("Start")
+        after[cups[i]] = cups[i + 1]
+    after[cups[-1]] = cups[0]
+
+    current_cup = cups[0]
     for i in range(0, iterations):
     for i in range(0, iterations):
-        current_cup = my_popleft(cups, following)
+        #print("Current:", current_cup)
-        one = my_popleft(cups, following)
+        #print_ring(after)
-        two = my_popleft(cups, following)
+        one = after[current_cup]
-        three = my_popleft(cups, following)
+        two = after[one]
-        three_cups = [three, two, one]
+        three = after[two]
+        three_cups = [one, two, three]
+        #print("Selecting:", three_cups)
         dest = current_cup
         dest = current_cup
         while True:
         while True:
             dest -= 1
             dest -= 1
@@ -32,20 +38,16 @@ def run_on_cups(cups, iterations):
                 dest = max_cup
                 dest = max_cup
             if dest not in three_cups:
             if dest not in three_cups:
                 break
                 break
-        following[dest] = three_cups
+        #print("Destination:", dest)
-        cups.append(current_cup)
+        after[current_cup] = after[three]
-    print("Time:", time() - start)
+        after[three] = after[dest]
-
+        after[dest] = one
-    while len(following) > 0:
+        current_cup = after[current_cup]
-        current = my_popleft(cups, following)
+    return after
-        cups.append(current)
-    return cups
 
 
-res1 = run_on_cups(deque(cups), 100)
+after = run_on_cups(cups, 100)
-print("Answer 1:", ''.join([str(i) for i in res1]))
+print("Answer 1:", ring_str(after)[1:])
-res2 = run_on_cups(deque(cups + list(range(10, 1000001))), 10000000)
+after = run_on_cups(cups + list(range(10, 1000001)), 10000000)
-res2.rotate(- res2.index(1))
+a = after[1]
-assert res2.popleft() == 1
+b = after[a]
-a = res2.popleft()
-b = res2.popleft()
 print("Answer 2:", a * b)
 print("Answer 2:", a * b)