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 | |
| 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')
| -rwxr-xr-x | challenge-274/sgreen/python/ch-1.py | 26 | ||||
| -rwxr-xr-x | challenge-274/sgreen/python/ch-2.py | 95 | ||||
| -rwxr-xr-x | challenge-274/sgreen/python/test.py | 37 |
3 files changed, 158 insertions, 0 deletions
diff --git a/challenge-274/sgreen/python/ch-1.py b/challenge-274/sgreen/python/ch-1.py new file mode 100755 index 0000000000..394023196a --- /dev/null +++ b/challenge-274/sgreen/python/ch-1.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 + +import sys + + +def goat_latin(sentence: str) -> str: + # Split on each word + words = sentence.split(' ') + for i, word in enumerate(words): + # If the first letter is not a vowel, move it to the end + if word[0].lower() not in ['a', 'e', 'i', 'o', 'u']: + word = word[1:] + word[0] + + # Add the appropriate suffix + words[i] = word + 'maa' + 'a' * i + + return ' '.join(words) + + +def main(): + result = goat_latin(sys.argv[1]) + print(result) + + +if __name__ == '__main__': + main() 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() diff --git a/challenge-274/sgreen/python/test.py b/challenge-274/sgreen/python/test.py new file mode 100755 index 0000000000..16ef8c1661 --- /dev/null +++ b/challenge-274/sgreen/python/test.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 + +import unittest +ch_1 = __import__('ch-1') +ch_2 = __import__('ch-2') + + +class TestClass(unittest.TestCase): + def test_ch_1(self): + self.assertEqual( + ch_1.goat_latin('I love Perl'), + 'Imaa ovelmaaa erlPmaaaa' + ) + self.assertEqual( + ch_1.goat_latin('Perl and Raku are friends'), + 'erlPmaa andmaaa akuRmaaaa aremaaaaa riendsfmaaaaaa' + ) + self.assertEqual( + ch_1.goat_latin('The Weekly Challenge'), + 'heTmaa eeklyWmaaa hallengeCmaaaa' + ) + + def test_ch_2(self): + self.assertEqual( + ch_2.bus_route([ch_2.Route(12, 11, 41), ch_2.Route(15, 5, 35)]), + [36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47] + ) + self.assertEqual( + ch_2.bus_route([ch_2.Route(12, 3, 41), ch_2.Route( + 15, 9, 35), ch_2.Route(30, 5, 25)]), + [0, 1, 2, 3, 25, 26, 27, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 55, 56, 57, 58, 59] + ) + + +if __name__ == '__main__': + unittest.main() |
