Przeglądaj źródła

Complete day 13

Frans Bergman 4 lat temu
rodzic
commit
3515a9c2ed
3 zmienionych plików z 74 dodań i 0 usunięć
  1. 2 0
      13.input
  2. 66 0
      13.py
  3. 6 0
      13.small.input

+ 2 - 0
13.input

@@ -0,0 +1,2 @@
+1000186
+17,x,x,x,x,x,x,x,x,x,x,37,x,x,x,x,x,907,x,x,x,x,x,x,x,x,x,x,x,19,x,x,x,x,x,x,x,x,x,x,23,x,x,x,x,x,29,x,653,x,x,x,x,x,x,x,x,x,41,x,x,13

+ 66 - 0
13.py

@@ -0,0 +1,66 @@
+lines = []
+
+with open("13.input") as f:
+    for line in f.readlines():
+        lines.append(line.strip())
+
+busses = [int(x) for x in lines[1].split(",") if x != "x"]
+
+my_time = int(lines[0])
+times = [x - my_time % x for x in busses]
+
+my_bus = busses[times.index(min(times))]
+
+print("Answer 1: {}".format(my_bus * min(times)))
+
+busses = [(- i % int(x), int(x)) for (i, x) in enumerate(lines[1].split(",")) if x != "x"]
+
+def print_table(start, busses):
+    end = start + busses[-1][0]
+    for i in range(start, end):
+        print("{}: ".format(i), end='')
+        for (offset, interval) in busses:
+            if i % interval == 0:
+                print('D', end='')
+            else:
+                print('.', end='')
+        print("")
+
+# Stolen from: https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Pseudocode
+def extended_gcd(a, b):
+    (old_r, r) = (a, b)
+    (old_s, s) = (1, 0)
+    (old_t, t) = (0, 1)
+
+    while r != 0:
+        quotient = int(old_r / r)
+        (old_r, r) = (r, old_r - quotient * r)
+        (old_s, s) = (s, old_s - quotient * s)
+        (old_t, t) = (t, old_t - quotient * t)
+
+    return (old_s, old_t)
+
+def combo(pair1, pair2):
+    off1, int1 = pair1
+    off2, int2 = pair2
+    # This is fine since all IDs are primes
+    new_int = int1 * int2
+    # Find the smallest solution to
+    # int1 * x + off1 = int2 * y + off2
+    # int1 * x - int2 * y = 1 * (off2 - off1)
+    x, y = extended_gcd(int1, -int2)
+    # Correct signs
+    if int1 * x - int2 * y != 1:
+        x = -x
+        y = -y
+    x *= (off2 - off1)
+    y *= (off2 - off1)
+    assert int1 * x + off1 == int2 * y + off2
+    return ((int1 * x + off1) % new_int, new_int)
+
+result_busses = list(busses)
+while len(result_busses) > 1:
+    result_busses = [combo(result_busses[0], result_busses[1])] + result_busses[2:]
+
+print("Answer 2: {}".format(result_busses[0][0]))
+

+ 6 - 0
13.small.input

@@ -0,0 +1,6 @@
+939
+1789,37,47,1889
+7,13,x,x,59,x,31,19
+67,7,59,61
+67,7,x,59,61
+67,x,7,59,61