-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay6_Challenge1.py
103 lines (80 loc) · 3.32 KB
/
Day6_Challenge1.py
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import re
import unittest
def get_distances(race_time: int | str) -> list[int]:
"""For a given time, find the possible distances that can be
covered if for each second the acceleration key is held the
boat does not move but gains 1m/sec in speed for the time it
does spend moving. Ex: If there are 10 seconds, a boat may
spend 1 second holding the key and 9 moving for a distance of
9m.
Args:
race_time (int | str ): the time the race takes
Returns:
list[int]: a list of the possible distances covered excluding 0s
"""
distances: list[int] = []
race_time = int(race_time)
for second in range(1, race_time):
distances.append((race_time - second) * second)
return distances
def find_wins(possible_distances: list[int], record_distance: int) -> int:
"""For a given list of possible distances and the record distance, find
the number of possible distances which break the record.
Args:
possible_distances (list[int]): distances a boat can go in the given race
record_distance (int): the current record distance to beat
Returns:
int: the number of possible distances which break the record
"""
total_broken_records: int = 0
for distance in possible_distances:
if distance > record_distance:
total_broken_records += 1
return total_broken_records
def total_ways_to_win(possible_wins: list[int]) -> int:
"""For a list of possible ways to break the recod in a number of races,
calculate the total number of ways to break all the records.
Args:
possible_wins (list[int]): a list of the number of ways to break each record
Returns:
int: the total number of combinations
"""
total: int = 1
for wins in possible_wins:
total = wins * total
return total
with open("Data/D6_data.txt", "r") as f:
# get the string of race times
times = f.readline()
# get the string of distance records
distances = f.readline()
# convert the strings into lists of just the numbers
times = re.findall("[0-9]+", times)
distances = re.findall("[0-9]+", distances)
# a list to store the number of ways to win for each race
possible_wins = []
for i in range(0, len(times)):
# for each race, get the number of distances possible
possible_distances = get_distances(times[i])
# get the record distance for the race
record_distance = int(distances[i])
# find the number of wins and append it to the list of possibilities
possible_wins.append(find_wins(possible_distances, record_distance))
# show how many combinations of ways to break the record exist
print(total_ways_to_win(possible_wins))
### TESTS FOR THE FUNCTIONS BASED ON AoC EXAMPLE DATA
class TestString(unittest.TestCase):
def test_get_distances(self):
time = 7
expected_distances = [6, 10, 12, 12, 10, 6]
self.assertEqual(get_distances(7), expected_distances)
def test_find_wins(self):
record_distance = 9
possible_distances = [6, 10, 12, 12, 10, 6]
self.assertEqual(find_wins(possible_distances, record_distance), 4)
def test_total_ways_to_win(self):
possible_wins = [4, 8, 9]
expected_total = 288
self.assertEqual(total_ways_to_win(possible_wins), expected_total)
if __name__ == "__main__":
unittest.main()