aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteven <steven1170@zoho.eu>2024-06-19 18:46:53 +0100
committerSteven <steven1170@zoho.eu>2024-06-19 18:46:53 +0100
commit82945ea0cbc58d62f0292a0f3328111b892b01f1 (patch)
tree5a47e1d80f4adfc5fc8079c2dcc01ddfe692cc90
parentffc47a8850ee877978e371d11a01a028862a3f9d (diff)
downloadperlweeklychallenge-club-82945ea0cbc58d62f0292a0f3328111b892b01f1.tar.gz
perlweeklychallenge-club-82945ea0cbc58d62f0292a0f3328111b892b01f1.tar.bz2
perlweeklychallenge-club-82945ea0cbc58d62f0292a0f3328111b892b01f1.zip
add solutions week 274 in python
-rw-r--r--challenge-274/steven-wilson/python/ch-1.py50
-rw-r--r--challenge-274/steven-wilson/python/ch-2.py57
-rw-r--r--challenge-274/steven-wilson/python/test_route.py30
3 files changed, 137 insertions, 0 deletions
diff --git a/challenge-274/steven-wilson/python/ch-1.py b/challenge-274/steven-wilson/python/ch-1.py
new file mode 100644
index 0000000000..2918b1dadf
--- /dev/null
+++ b/challenge-274/steven-wilson/python/ch-1.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python3
+
+VOWELS = {'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'}
+
+
+def goat_latin(sentence):
+ ''' Given a sentence, convert the given sentence to Goat Latin, a made up
+ language similar to Pig Latin.
+
+ Rules for Goat Latin:
+
+ 1) If a word begins with a vowel ("a", "e", "i", "o", "u"), append
+ "ma" to the end of the word.
+ 2) If a word begins with consonant i.e. not a vowel, remove first
+ letter and append it to the end then add "ma".
+ 3) Add letter "a" to the end of first word in the sentence, "aa" to
+ the second word, etc etc.
+
+ >>> goat_latin("I love Perl")
+ 'Imaa ovelmaaa erlPmaaaa'
+ >>> goat_latin("Perl and Raku are friends")
+ 'erlPmaa andmaaa akuRmaaaa aremaaaaa riendsfmaaaaaa'
+ >>> goat_latin("The Weekly Challenge")
+ 'heTmaa eeklyWmaaa hallengeCmaaaa'
+ '''
+ words = []
+ for number, word in enumerate(sentence.split(" "), start=1):
+ words.append(convert_word(word, number))
+ return " ".join(words)
+
+
+
+def convert_word(word, number):
+ '''
+ >>> convert_word("I", 1)
+ 'Imaa'
+ >>> convert_word("Perl", 1)
+ 'erlPmaa'
+ >>> convert_word("are", 4)
+ 'aremaaaaa'
+ '''
+ if word[0] in VOWELS:
+ return word + 'ma' + number * 'a'
+ return word[1:] + word[0] + 'ma' + number * 'a'
+
+
+if __name__ == "__main__":
+ import doctest
+
+ doctest.testmod(verbose=True)
diff --git a/challenge-274/steven-wilson/python/ch-2.py b/challenge-274/steven-wilson/python/ch-2.py
new file mode 100644
index 0000000000..fea1afc1b2
--- /dev/null
+++ b/challenge-274/steven-wilson/python/ch-2.py
@@ -0,0 +1,57 @@
+#!/usr/bin/env python3
+
+
+def bus_routes(timetables):
+ ''' Several bus routes start from a bus stop near my home, and go to the
+ same stop in town. They each run to a set timetable, but they take
+ different times to get into town.
+
+ Find the times - if any - I should let one bus leave and catch a strictly
+ later one in order to get into town strictly sooner.
+
+ An input timetable consists of the service interval, the offset within the
+ hour, and the duration of the trip.
+ >>> bus_routes([ [12, 11, 41], [15, 5, 35] ])
+ [36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47]
+ >>> bus_routes([ [12, 3, 41], [15, 9, 35], [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]
+ '''
+ routes = [Route(i, o, d) for i, o ,d in timetables]
+ times = []
+ for current in range(0, 60):
+ next_bus = [(r.next_bus(current), r.end_trip(current)) for r in routes]
+ sorted_next_bus = sorted(next_bus)
+ # assuming if 2 buses arrive at the same time the first route
+ # will be the first bus
+ if any(sorted_next_bus[0][1] > end for end in list(zip(*sorted_next_bus[1:]))[1]):
+ times.append(current)
+ return times
+
+
+class Route:
+ def __init__(self, interval, offset, duration):
+ self.interval = interval
+ self.offset = offset
+ self.duration = duration
+
+ def __repr__(self):
+ class_name = type(self).__name__
+ return f"{class_name}: {self.interval} {self.offset} {self.duration}"
+
+ def next_bus(self, current):
+ time = self.offset
+ while current > time:
+ if time + self.interval > 59 and time + self.interval % 60 > self.offset:
+ time = 60 + self.offset
+ else:
+ time += self.interval
+ return time
+
+ def end_trip(self, current):
+ return self.next_bus(current) + self.duration
+
+
+if __name__ == "__main__":
+ import doctest
+
+ doctest.testmod(verbose=True)
diff --git a/challenge-274/steven-wilson/python/test_route.py b/challenge-274/steven-wilson/python/test_route.py
new file mode 100644
index 0000000000..928b4600db
--- /dev/null
+++ b/challenge-274/steven-wilson/python/test_route.py
@@ -0,0 +1,30 @@
+#!/usr/bin/env python3
+
+from unittest import TestCase, main
+from ch_2 import Route, bus_routes
+
+class test_route(TestCase):
+
+ def test_next_bus(self):
+ route = Route(12, 11, 41)
+ self.assertEqual(route.next_bus(10), 11)
+ self.assertEqual(route.next_bus(12), 23)
+ self.assertEqual(route.next_bus(23), 23)
+
+ def test_end_trip(self):
+ route = Route(12, 11, 41)
+ self.assertEqual(route.end_trip(10), 52)
+
+ route = Route(18, 0, 41)
+ self.assertEqual(route.end_trip(59), 101)
+
+class test_bus_routes(TestCase):
+
+ def test_routes(self):
+ self.assertEqual(bus_routes([ [12, 11, 41], [15, 5, 35] ]),
+ [36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47])
+ self.assertEqual(bus_routes([ [12, 3, 41], [15, 9, 35], [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__':
+ main()