Weekly Challenge 366
It was seven years ago that Mohammad sent out the first challenge to Team PWC (as it was then known). Thank you very much for all your work over the seven years.
Each week Mohammad S. Anwar sends out The Weekly Challenge, a chance for all of us to come up with solutions to two weekly tasks. My solutions are written in Python first, and then converted to Perl. Unless otherwise stated, Copilot (and other AI tools) have NOT been used to generate the solution. It's a great way for us all to practice some coding.
Task 1: Count Prefixes
Task
You are given an array of words and a string (contains only lowercase English letters).
Write a script to return the number of words in the given array that are a prefix of the given string.
My solution
This is a one-liner in Python. It should be pretty self-explanatory. Given a list called array and a string called prefix, it counts the number of items in the list where the first letters of the prefix match the word.
def count_prefixes(array: list, prefix: str) -> int:
return sum(1 for word in array if prefix[:len(word)] == word)
The Perl solution uses the grep function to perform the counting. In a scalar context, grep returns the number of matching items.
sub main (@array) {
my $prefix = pop(@array);
my $count = grep { substr( $prefix, 0, length($_) ) eq $_ } @array;
say $count;
}
Examples
$ ./ch-1.py a ap app apple banana apple
4
$ ./ch-1.py cat dog fish bird
0
$ ./ch-1.py hello he hello heaven he hello
4
$ ./ch-1.py "" code coding cod coding
3
$ ./ch-1.py p pr pro prog progr progra program program
7
Task 2: Valid Times
Task
You are given a time in the form HH:MM. The earliest possible time is 00:00 and the latest possible time is 23:59. In the string time, the digits represented by the ? symbol are unknown, and must be replaced with a digit from 0 to 9.
Write a script to return the count different ways we can make it a valid time.
My solution
This is an interesting challenge as the solution is not straight forward. There are a few approaches that can be taken. One option is to calculate all 1440 minutes in a day and see if it matched the expected pattern.
The approach I took was to calculate the possible hours and possible minutes, and multiplying both figures to return a result.
I start by using a regular expression to check if the time is valid. As the question mark ? is within square brackets [ ] this is taken as a literal character.
def valid_times(input_string: str) -> int:
if not re.search(r'^([0-1?][0-9?]|2[0-3?]):[0-5?][0-9?]$', input_string):
raise ValueError("Input is not in the expected format (HH:MM)")
The next task is calculating the number of valid hours.
- If the hours is
??, then there are 24 valid hours. - If the first character is a question there are 3 valid hours if the second digit is less than four (e.g. 02 12 22), or 2 if it is 4 or greater (e.g. 04 14).
- If the second character is a question mark, there are 4 valid hours if the first digit is 2, or 10 valid hours otherwise.
- If hours have no questions marks, there is only one valid hour.
# Compute the hours
if input_string[:2] == "??":
hours = 24
elif input_string[:1] == "?":
hours = 3 if int(input_string[1:2]) < 4 else 2
elif input_string[1:2] == "?":
hours = 4 if input_string[:1] == "2" else 10
else:
hours = 1
Thankfully calculating the number of valid minutes is a little easier.
- If the minutes is
??, then there are sixty valid minutes. - If the first character is a question mark, then there are six valid minutes (e.g. 06 16 26 36 46 56).
- If the second characters is a question mark, there are ten valid minutes (e.g. 50 51 ... 58 59).
- If the minutes have no question marks, there is only one valid minute.
if input_string[3:] == "??":
minutes = 60
elif input_string[3:4] == "?":
minutes = 6
elif input_string[4:] == "?":
minutes = 10
else:
minutes = 1
return hours * minutes
The Perl solution follows the same logic as the Python solution.
Examples
$ ./ch-2.py ?2:34
3
$ ./ch-2.py ?4:?0
12
$ ./ch-2.py ??:??
1440
$ ./ch-2.py ?3:45
3
$ ./ch-2.py 2?:15
4
Top comments (0)