Skip to content

Commit fefa4d6

Browse files
committed
Added solution for day 25
1 parent 0a02cc1 commit fefa4d6

File tree

3 files changed

+105
-1
lines changed

3 files changed

+105
-1
lines changed

advent2020/day25.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# MIT License
2+
#
3+
# Copyright (c) 2021 Andrew Krepps
4+
#
5+
# Permission is hereby granted, free of charge, to any person obtaining a copy
6+
# of this software and associated documentation files (the "Software"), to deal
7+
# in the Software without restriction, including without limitation the rights
8+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
# copies of the Software, and to permit persons to whom the Software is
10+
# furnished to do so, subject to the following conditions:
11+
#
12+
# The above copyright notice and this permission notice shall be included in all
13+
# copies or substantial portions of the Software.
14+
#
15+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
# SOFTWARE.
22+
23+
24+
import math
25+
26+
from . import util
27+
28+
29+
def parse_input(lines):
30+
assert len(lines) == 2
31+
return int(lines[0]), int(lines[1])
32+
33+
34+
def find_loop_size(subject, modulus, output):
35+
# uses baby-step giant-step algorithm
36+
m = math.ceil(math.sqrt(modulus))
37+
subject_to_j_table = {pow(subject, j, modulus): j for j in range(m)}
38+
gamma = output
39+
subject_to_neg_m = pow(subject, -m, modulus) # requires python 3.8+
40+
for i in range(m):
41+
if gamma in subject_to_j_table.keys():
42+
return i * m + subject_to_j_table[gamma]
43+
gamma = (gamma * subject_to_neg_m) % modulus
44+
return None
45+
46+
47+
def get_part1_answer(lines):
48+
subject = 7
49+
modulus = 20201227
50+
card_public_key, door_public_key = parse_input(lines)
51+
card_loop_size = find_loop_size(subject, modulus, card_public_key)
52+
if card_loop_size is not None:
53+
return pow(door_public_key, card_loop_size, modulus)
54+
door_loop_size = find_loop_size(subject, modulus, door_public_key)
55+
if door_loop_size is not None:
56+
return pow(card_public_key, door_loop_size, modulus)
57+
return None
58+
59+
60+
def run():
61+
lines = util.get_input_file_lines("day25.txt")
62+
print(f"The answer to part 1 is {get_part1_answer(lines)}")
63+
print(f"There is no part 2. Go back to enjoying the holidays!")

main.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
from advent2020 import day22
4848
from advent2020 import day23
4949
from advent2020 import day24
50+
from advent2020 import day25
5051

5152

5253
day_runners = [
@@ -73,7 +74,8 @@
7374
lambda: day21.run(),
7475
lambda: day22.run(),
7576
lambda: day23.run(),
76-
lambda: day24.run()
77+
lambda: day24.run(),
78+
lambda: day25.run()
7779
]
7880

7981

test/test_day25.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# MIT License
2+
#
3+
# Copyright (c) 2021 Andrew Krepps
4+
#
5+
# Permission is hereby granted, free of charge, to any person obtaining a copy
6+
# of this software and associated documentation files (the "Software"), to deal
7+
# in the Software without restriction, including without limitation the rights
8+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
# copies of the Software, and to permit persons to whom the Software is
10+
# furnished to do so, subject to the following conditions:
11+
#
12+
# The above copyright notice and this permission notice shall be included in all
13+
# copies or substantial portions of the Software.
14+
#
15+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
# SOFTWARE.
22+
23+
24+
import unittest
25+
26+
from advent2020.day25 import get_part1_answer
27+
from advent2020.util import get_input_data_lines
28+
29+
30+
data = """
31+
5764801
32+
17807724
33+
"""
34+
35+
36+
class Day25Test(unittest.TestCase):
37+
def test_day25(self):
38+
lines = get_input_data_lines(data)
39+
self.assertEqual(get_part1_answer(lines), 14897079)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy