DEV Community

Simon Green
Simon Green

Posted on

Happy 7th birthday TWC!

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.

Challenge, My solutions

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)
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)")
Enter fullscreen mode Exit fullscreen mode

The next task is calculating the number of valid hours.

  1. If the hours is ??, then there are 24 valid hours.
  2. 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).
  3. If the second character is a question mark, there are 4 valid hours if the first digit is 2, or 10 valid hours otherwise.
  4. 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
Enter fullscreen mode Exit fullscreen mode

Thankfully calculating the number of valid minutes is a little easier.

  1. If the minutes is ??, then there are sixty valid minutes.
  2. If the first character is a question mark, then there are six valid minutes (e.g. 06 16 26 36 46 56).
  3. If the second characters is a question mark, there are ten valid minutes (e.g. 50 51 ... 58 59).
  4. 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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Top comments (0)