Frans Bergman 3 years ago
parent
commit
e4457f9b3c
1 changed files with 72 additions and 0 deletions
  1. 72 0
      21.py

+ 72 - 0
21.py

@@ -0,0 +1,72 @@
+from itertools import product
+
+#input = [4, 8]
+input = [1, 5]
+
+pos = [input[0] - 1, input[1] - 1]
+score = [0, 0]
+turn = 0
+
+dice = 1
+rolls = 0
+
+def roll():
+    global dice
+    global rolls
+    res = dice
+    dice += 1
+    rolls += 1
+    if dice == 101:
+        dice = 1
+    return res
+
+def roll3():
+    global dice
+    global rolls
+    if dice < 98:
+        res = dice * 3 + 3
+        dice += 3
+        rolls += 3
+        return res
+    else:
+        return roll() + roll() + roll()
+
+while score[0] < 1000 and score[1] < 1000:
+    for i in range(2):
+        pos[i] += roll3()
+        pos[i] = pos[i] % 10
+        score[i] += pos[i] + 1
+        if score[i] >= 1000:
+            print("Part 1:", score[(i + 1) % 2] * rolls)
+
+wincount = {}
+
+def calc_wincount(state):
+    (pos, score, turn) = state
+    wc = [0, 0]
+    if score[0] >= 21:
+        return [1, 0]
+    elif score[1] >= 21:
+        return [0, 1]
+    for [a, b, c] in product(list(range(1, 4)), repeat=3):
+        steps = a + b + c
+        if turn == 0:
+            newpos = ((pos[0] + steps) % 10, pos[1])
+            newscore = (score[0] + newpos[0] + 1, score[1])
+        else:
+            newpos = (pos[0], (pos[1] + steps) % 10)
+            newscore = (score[0], score[1] + newpos[1] + 1)
+        [c1, c2] = wincount[(newpos, newscore, (turn + 1) % 2)]
+        wc[0] += c1
+        wc[1] += c2
+    return wc
+
+for ascore in reversed(range(0, 31)):
+    for bscore in reversed(range(0, 31)):
+        for turn in range(2):
+            for apos in range(0, 10):
+                for bpos in range(0, 10):
+                    state = ((apos, bpos), (ascore, bscore), turn)
+                    wincount[state] = calc_wincount(state)
+
+print("Part 2:", max(wincount[((input[0] - 1, input[1] - 1), (0, 0), 0)]))