Skip to content

Commit f81f8ee

Browse files
committed
Added solutions for day 13
1 parent b8e30a1 commit f81f8ee

File tree

3 files changed

+141
-1
lines changed

3 files changed

+141
-1
lines changed

advent2020/day13.py

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# MIT License
2+
#
3+
# Copyright (c) 2020 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 functools
25+
import operator
26+
27+
from . import util
28+
29+
30+
def parse_bus_schedule(lines):
31+
return int(lines[0]), [int(token) if token != 'x' else -1 for token in lines[1].split(',')]
32+
33+
34+
def find_earliest_bus(arrival_time, buses):
35+
t = arrival_time
36+
while True:
37+
for bus in buses:
38+
if bus > 0 and t % bus == 0:
39+
return t, bus
40+
t += 1
41+
42+
43+
def find_time_with_cosmic_bus_alignment(buses):
44+
max_bus = max(buses)
45+
max_idx = buses.index(max_bus)
46+
t = max_bus
47+
searching = True
48+
while searching:
49+
searching = False
50+
for idx, bus in enumerate(buses):
51+
if bus > 0 and (t + (idx - max_idx)) % bus != 0:
52+
searching = True
53+
break
54+
if searching:
55+
t += max_bus
56+
return t - max_idx
57+
58+
59+
def find_time_with_cosmic_bus_alignment_except_faster_since_apparently_the_buses_are_pairwise_coprime(buses):
60+
limit = functools.reduce(operator.mul, filter(lambda x: x > 0, buses), 1)
61+
answer = 0
62+
skip = 1
63+
for idx, bus in enumerate(buses):
64+
if bus > 0:
65+
current = answer
66+
while current < limit and current % bus != (bus - idx) % bus:
67+
current += skip
68+
if current >= limit:
69+
return None
70+
answer = current
71+
skip *= bus
72+
return answer
73+
74+
75+
def get_part1_answer(arrival_time, buses):
76+
departure_time, bus = find_earliest_bus(arrival_time, buses)
77+
return (departure_time - arrival_time)*bus
78+
79+
80+
def get_part2_answer(buses):
81+
return find_time_with_cosmic_bus_alignment_except_faster_since_apparently_the_buses_are_pairwise_coprime(buses)
82+
83+
84+
def run():
85+
arrival_time, buses = parse_bus_schedule(util.get_input_file_lines("day13.txt"))
86+
print(f"The answer to part 1 is {get_part1_answer(arrival_time, buses)}")
87+
print(f"The answer to part 2 is {get_part2_answer(buses)}")

main.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
from advent2020 import day10
3636
from advent2020 import day11
3737
from advent2020 import day12
38+
from advent2020 import day13
3839

3940

4041
day_runners = [
@@ -49,7 +50,8 @@
4950
lambda: day9.run(),
5051
lambda: day10.run(),
5152
lambda: day11.run(),
52-
lambda: day12.run()
53+
lambda: day12.run(),
54+
lambda: day13.run()
5355
]
5456

5557

test/test_day13.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# MIT License
2+
#
3+
# Copyright (c) 2020 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.day13 import get_part1_answer
27+
from advent2020.day13 import get_part2_answer
28+
from advent2020.day13 import parse_bus_schedule
29+
from advent2020.util import get_input_data_lines
30+
31+
32+
bus_data1 = """
33+
939
34+
7,13,x,x,59,x,31,19
35+
"""
36+
37+
38+
class Day13Test(unittest.TestCase):
39+
def test_day13(self):
40+
arrival_time, buses = parse_bus_schedule(get_input_data_lines(bus_data1))
41+
self.assertEqual(get_part1_answer(arrival_time, buses), 295)
42+
self.run_part2_test("7,13,x,x,59,x,31,19", 1068781)
43+
self.run_part2_test("17,x,13,19", 3417)
44+
self.run_part2_test("67,7,59,61", 754018)
45+
self.run_part2_test("67,x,7,59,61", 779210)
46+
self.run_part2_test("67,7,x,59,61", 1261476)
47+
self.run_part2_test("1789,37,47,1889", 1202161486)
48+
49+
def run_part2_test(self, bus_line, expected_result):
50+
_, buses = parse_bus_schedule(["-1", bus_line])
51+
self.assertEqual(get_part2_answer(buses), expected_result)

0 commit comments

Comments
 (0)