|
1 | 1 | #!/bin/python |
2 | 2 | """Advent of Code, Day 22.""" |
3 | | -# https://www.reddit.com/r/adventofcode/comments/ee0rqi/comment/fbwp0r0/ |
4 | | - |
5 | 3 | import collections |
6 | 4 | PARSER = str.splitlines |
7 | 5 |
|
8 | 6 |
|
9 | 7 | def solve(data: list[str], part: int, testing: bool) -> int: |
10 | 8 | """Return a card after shuffling.""" |
11 | | - want_card = 0 if testing else 2019 if part == 1 else 2020 |
12 | | - deck_size = 10 if testing else 10007 if part == 1 else 119315717514047 |
| 9 | + return (part1 if part == 1 else part2)(data, testing) |
| 10 | + |
| 11 | + |
| 12 | +def part1(data: list[str], testing: bool) -> int: |
| 13 | + """Track the position of a card through some shuffles.""" |
| 14 | + want_card = 0 if testing else 2019 |
| 15 | + deck_size = 10 if testing else 10007 |
13 | 16 | # cards = collections.deque(range(deck_size)) |
14 | 17 | # position = list(cards).index(want_card) |
15 | 18 | position = want_card |
16 | | - for _ in range(1 if part == 1 else 101741582076661): |
17 | | - for cmd in data: |
18 | | - if cmd == "deal into new stack": |
19 | | - # cards.reverse() |
20 | | - position = deck_size - 1 - position |
21 | | - elif cmd.startswith("cut"): |
22 | | - n = int(cmd.split()[-1]) |
23 | | - # cards.rotate(-n) |
24 | | - position = (position - n) % deck_size |
25 | | - elif cmd.startswith("deal with increment"): |
26 | | - n = int(cmd.split()[-1]) |
27 | | - # new_cards = [0] * deck_size |
28 | | - # for i, card in enumerate(cards): |
29 | | - # new_cards[(i * n) % deck_size] = card |
30 | | - # cards = collections.deque(new_cards) |
31 | | - position = (position * n) % deck_size |
| 19 | + for cmd in data: |
| 20 | + if cmd == "deal into new stack": |
| 21 | + # cards.reverse() |
| 22 | + position = deck_size - 1 - position |
| 23 | + elif cmd.startswith("cut"): |
| 24 | + n = int(cmd.split()[-1]) |
| 25 | + # cards.rotate(-n) |
| 26 | + position = (position - n) % deck_size |
| 27 | + elif cmd.startswith("deal with increment"): |
| 28 | + n = int(cmd.split()[-1]) |
| 29 | + # new_cards = [0] * deck_size |
| 30 | + # for i, card in enumerate(cards): |
| 31 | + # new_cards[(i * n) % deck_size] = card |
| 32 | + # cards = collections.deque(new_cards) |
| 33 | + position = (position * n) % deck_size |
32 | 34 |
|
33 | 35 | return position |
34 | 36 |
|
35 | 37 |
|
| 38 | +def part2(data: list[str], testing: bool) -> int: |
| 39 | + """Perform many shuffles. |
| 40 | +
|
| 41 | + Code taken from https://github.com/Dementophobia/advent-of-code-2019/blob/master/2019_22_p2.py |
| 42 | +
|
| 43 | + See also, |
| 44 | + https://www.reddit.com/r/adventofcode/comments/ee0rqi/comment/fbwp0r0/ |
| 45 | + https://www.reddit.com/r/adventofcode/comments/ee0rqi/comment/fbnkaju/ |
| 46 | + https://www.reddit.com/r/adventofcode/comments/ee0rqi/comment/fbnifwk/ |
| 47 | + """ |
| 48 | + del testing |
| 49 | + position = 2020 |
| 50 | + size = 119315717514047 |
| 51 | + iterations = 101741582076661 |
| 52 | + |
| 53 | + addi, multi = 0, 1 |
| 54 | + for operation in data: |
| 55 | + if operation == "deal into new stack": |
| 56 | + multi *= -1 |
| 57 | + addi += multi |
| 58 | + elif operation.startswith("cut"): |
| 59 | + n = int(operation.split()[-1]) |
| 60 | + addi += n * multi |
| 61 | + elif operation.startswith("deal with increment"): |
| 62 | + n = int(operation.split()[-1]) |
| 63 | + multi *= pow(n, -1, size) |
| 64 | + |
| 65 | + all_multi = pow(multi, iterations, size) |
| 66 | + all_addi = addi * (1 - pow(multi, iterations, size)) * pow(1 - multi, -1, size) |
| 67 | + |
| 68 | + return (position * all_multi + all_addi) % size |
| 69 | + |
| 70 | + |
36 | 71 | SAMPLE = [ |
37 | 72 | """\ |
38 | 73 | deal with increment 7 |
@@ -60,7 +95,7 @@ def solve(data: list[str], part: int, testing: bool) -> int: |
60 | 95 | ] |
61 | 96 | TESTS = [ |
62 | 97 | (1, SAMPLE[0], 0), |
63 | | - (1, SAMPLE[1], 3), |
64 | | - (1, SAMPLE[2], 6), |
65 | | - (1, SAMPLE[3], 9), |
| 98 | + (1, SAMPLE[1], 1), |
| 99 | + (1, SAMPLE[2], 2), |
| 100 | + (1, SAMPLE[3], 7), |
66 | 101 | ] |
0 commit comments