diff options
| author | Simon Green <mail@simon.green> | 2024-06-23 23:18:19 +1000 |
|---|---|---|
| committer | Simon Green <mail@simon.green> | 2024-06-23 23:18:19 +1000 |
| commit | 11d250df98a2ee69b3ca1f89019704433fba9579 (patch) | |
| tree | 1d9b82a94f37e5fdd97f41cfeb3b412c96c3586c /challenge-274/sgreen/python/ch-2.py | |
| parent | 41c7a18ce09761c310487d6af3e2f224cc43a161 (diff) | |
| download | perlweeklychallenge-club-11d250df98a2ee69b3ca1f89019704433fba9579.tar.gz perlweeklychallenge-club-11d250df98a2ee69b3ca1f89019704433fba9579.tar.bz2 perlweeklychallenge-club-11d250df98a2ee69b3ca1f89019704433fba9579.zip | |
sgreen solutions to challenge 274
Diffstat (limited to 'challenge-274/sgreen/python/ch-2.py')
| -rwxr-xr-x | challenge-274/sgreen/python/ch-2.py | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/challenge-274/sgreen/python/ch-2.py b/challenge-274/sgreen/python/ch-2.py new file mode 100755 index 0000000000..13f830318e --- /dev/null +++ b/challenge-274/sgreen/python/ch-2.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python3 + +from dataclasses import dataclass +import sys + + +@dataclass +class Route: + freq: int + offset: int + length: int + + +def calculate_departures(routes): + """ + Calculate the departures for each minute based on the given routes. + + Args: + routes (list): A list of Route objects representing bus routes. + + Returns: + dict: A dictionary where the keys are minutes and the values are the + length of the shortest route departing at that minute. + """ + departures = {} + for route in routes: + start_minute = route.offset % route.freq + while start_minute < 60: + if start_minute in departures and departures[start_minute] < route.length: + # This is a slower bus, so we can ignore it + continue + departures[start_minute] = route.length + start_minute += route.freq + + return departures + + +def next_bus(departures, minute): + """ + Find the next bus departure time after the given minute. + + Args: + departures (dict): A dictionary containing the departure times as keys and the duration of each departure as values. + minute (int): The minute after which to find the next bus departure time. + + Returns: + tuple: A tuple containing the start minute and the end minute of the next bus departure. + """ + start_minute = minute + while True: + if start_minute in departures: + return start_minute, start_minute + departures[start_minute] + + start_minute += 1 + if start_minute == 60: + start_minute = 0 + + +def bus_route(routes: list[Route]) -> list[int]: + # Get the start time of all bus routes + departures = calculate_departures(routes) + skip_bus = [] + + for minute in range(60): + start_minute, end_minute = next_bus(departures, minute) + + # Check if there are any faster buses + for second_bus_start in range(start_minute + 1, end_minute): + if second_bus_start % 60 not in departures: + # No bus departs at this minute + continue + if second_bus_start + departures[second_bus_start % 60] < end_minute: + # The second bus is faster + break + else: + # No second bus will get there sooner + continue + + skip_bus.append(minute) + + return skip_bus + + +def main(): + # Convert input into triplets of integers + routes = [] + for i in range(1, len(sys.argv), 3): + routes.append(Route(int(sys.argv[i]), int( + sys.argv[i+1]), int(sys.argv[i+2]))) + result = bus_route(routes) + print(result) + + +if __name__ == '__main__': + main() |
