aboutsummaryrefslogtreecommitdiff
path: root/2021/day21/21b.py
blob: 3404c222ad755d9ce664fea9b0a7ecfc8ed12948 (plain)
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
from collections import defaultdict

POSSIBLE_ROLLS = [a + b + c for a in range(1, 4) for b in range(1, 4) for c in range(1, 4)]

def move(p, roll):
    pos, score = p
    pos += roll
    while pos > 10:
        pos -= 10

    return (pos, score + pos)

def won(p):
    return p[1] >= 21

P1_WON_KEY = (-1, -1, True)
P2_WON_KEY = (-1, -1, False)

def step_universes(d):
    nxt = defaultdict(lambda: 0)
    nxt[P1_WON_KEY] = d[P1_WON_KEY]
    nxt[P2_WON_KEY] = d[P2_WON_KEY]
    for ((p1, p2, p1_turn), count) in d.items():
        if p1 == -1:
            continue
        elif won(p1):
            nxt[P1_WON_KEY] += count
            continue
        elif won(p2):
            nxt[P2_WON_KEY] += count
            continue

        for roll in POSSIBLE_ROLLS:
            if p1_turn:
                nxt[(move(p1, roll), p2, False)] += count
            else:
                nxt[(p1, move(p2, roll), True)] += count

    return nxt

inp = open("./input").read().split("\n")
p1_start = int(inp[0].split(": ")[1])
p2_start = int(inp[1].split(": ")[1])

d = defaultdict(lambda: 0)
d[((p1_start, 0), (p2_start, 0), True)] = 1
d = step_universes(d)

while len(d) > 2:
    d = step_universes(d)

w1 = d[P1_WON_KEY]
w2 = d[P2_WON_KEY]
print("Part 2: %d" % max([w1, w2]))