<jupyter_start><jupyter_text>part 1<jupyter_code>test_start = (4, 8)
puzzle_start = (5, 9)
board_size = 10
def new_deterministic_die(num_sides):
    return itertools.cycle(range(1, num_sides+1))
def take(n, iterable):
    "Return first n items of the iterable as a list"
    return list(itertools.islice(iterable, n))
def move_player(loc, score, die):
    s = sum(take(3, die))
    loc = (loc + s) % board_size # positions labeled 0, 1, .., 9
    score += loc + 1 # add 1 because true board values are 1, 2, ..., 10
    return loc, score, die
def rolls(loc1, loc2, score1, score2, numrolls, die):
    s1 = sum(take(3, die))
    s2 = sum(take(3, die))
    print(s1, s2)
    loc1 = (loc1 + s1) % board_size # positions labeled 0, 1, ..., 9
    loc2 = (loc2 + s2) % board_size
    score1 += loc1 + 1 # add 1 because true board values are 1, 2, ..., 10
    score2 += loc2 + 1
    numrolls += 3 + 3
    return loc1, loc2, score1, score2, numrolls, die
def solve(starting_pos):
    loc1 = starting_pos[0] - 1 # board positions labeled 0, 1, ..., 9
    loc2 = starting_pos[1] - 1
    die = new_deterministic_die(100)
    score1, score2 = 0, 0
    numrolls = 0
    while True:
        loc1, score1, die = move_player(loc1, score1, die)
        numrolls += 3
        if score1 >= 1000:
            break
        loc2, score2, die = move_player(loc2, score2, die)
        numrolls += 3
        if score2 >= 1000:
            break
    return min(score1, score2)*numrolls

solve(test_start)
solve(puzzle_start)<jupyter_output><empty_output><jupyter_text>part 2 Each "universe" has a state (l1, s1, l2, s2), where l and s correspond to the location and the scoreof players 1 and 2. A move is 3 dice rolls, and each die roll splits a state into 3 new states, wereone of them has a die role of +1, one w/ +2, and onw w/ +3. After 3 rolls, there will be 27 new states:    +3, +4, +5        +4, +5, +6            +5, +6, +7        +4, +5, +6            +5, +6, +7                +6, +7, +8            +5, +6, +7                +6, +7, +8                    +7, +8, +9                So +3 (1x), +4 (3x), +5 (6x), +6 (7x), +7 (6x), +8 (3x), +9 (1x).<jupyter_code>newcases = {+3: 1, +4: 3, +5: 6, +6: 7, +7: 6, +8: 3, +9: 1}
newcases
def solve2(starting_pos):
    l1, l2 = starting_pos
    states = {(l1-1, 0, l2-1, 0): 1}
    wins1, wins2 = 0, 0
    while True:
        if len(states) == 0:
            break
        newstates = collections.defaultdict(int)
        # player 1 rolls
        for (l1, s1, l2, s2), replicas in states.items():
            for offset, cnt in newcases.items():
                newl1 = (l1 + offset) % board_size
                news1 = s1 + (newl1 + 1)
                if news1 >= 21:
                    wins1 += replicas*cnt
                else:
                    newstates[(newl1, news1, l2, s2)] += replicas*cnt
        states = newstates
        if len(states) == 0:
            break
        newstates = collections.defaultdict(int)
        # player 2 rolls
        for (l1, s1, l2, s2), replicas in states.items():
            for offset, cnt in newcases.items():
                newl2 = (l2 + offset) % board_size
                news2 = s2 + (newl2 + 1)
                if news2 >= 21:
                    wins2 += replicas*cnt
                else:
                    newstates[(l1, s1, newl2, news2)] += replicas*cnt
        states = newstates
    return max(wins1, wins2)
solve2(test_start)
solve2(puzzle_start)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1302969155376189, 'fraction_numerical': 0.06399538771980398, 'mean_word_length': 2.0332167832167833, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '297581', 'license': 'BSD-2-Clause', 'n_tokens_mistral': 1350, 'n_tokens_neox': 1243, 'n_words': 402, 'path': 'day21.ipynb', 'repo_name': 'g2boojum/AdventOfCode2021', 'size': '3469'}