The Bear's Den

Enter at your own risk

The Times They Are a-Like

Task 1: String Alike

Submitted by: Mohammad Sajid Anwar


You are given a string of even length.

Write a script to find out whether the given string can be split into two halves of equal lengths, each with the same non-zero number of vowels.

Example 1

Input: $str = "textbook"
Output: false

1st half: "text" (1 vowel)
2nd half: "book" (2 vowels)

Example 2

Input: $str = "book"
Output: true

1st half: "bo" (1 vowel)
2nd half: "ok" (1 vowel)

Example 3

Input: $str = "AbCdEfGh"
Output: true

1st half: "AbCd" (1 vowel)
2nd half: "EfGh" (1 vowel)

Example 4

Input: $str = "rhythmmyth"
Output: false

1st half: "rhyth" (0 vowel)
2nd half: "mmyth" (0 vowel)

Example 5

Input: $str = "UmpireeAudio"
Output: false

1st half: "Umpire" (3 vowels)
2nd half: "eAudio" (5 vowels)

Solution

Try to split the string into halves, count the vowels therein and check if these numbers are nonzero and equal.

use strict;
use warnings;

sub string_alike ($str) {
    my $l = () = $str =~ /../g;
    my ($h, $t) = map tr/aeiouAEIOU//, $str =~ /^(.{$l})((?1))$/;

    $h && $h == $t;
}

See the full solution to task 1.

Task 2: Convert Time

Submitted by: Mohammad Sajid Anwar


You are given two strings, $source and $target, containing time in 24-hour time form.

Write a script to convert the source into target by performing one of the following operations:

1. Add  1 minute
2. Add  5 minutes
3. Add 15 minutes
4. Add 60 minutes

Find the total operations needed to get to the target.

Example 1

Input: $source = "02:30"
       $target = "02:45"
Output: 1

Just one operation i.e. "Add 15 minutes".

Example 2

Input: $source = "11:55"
       $target = "12:15"
Output: 2

Two operations i.e. "Add 15 minutes" followed by "Add 5 minutes".

Example 3

Input: $source = "09:00"
       $target = "13:00"
Output: 4

Four operations of "Add 60 minutes".

Example 4

Input: $source = "23:45"
       $target = "00:30"
Output: 3

Three operations of "Add 15 minutes".

Example 5

Input: $source = "14:20"
       $target = "15:25"
Output: 2

Two operations, one "Add 60 minutes" and one "Add 5 minutes"

Solution

Perl

Four steps to solve this task:

use strict;
use warnings;
use DateTime::Format::Strptime;
use List::Util 'sum';

sub convert_time {
    state $div = [5, 3, 4, 24];
    state $parser = DateTime::Format::Strptime->new(pattern => "%R",
        strict => 1, on_error => 'croak');

    my ($s, $t) = map $parser->parse_datetime($_), @_;
    my $diff = ($t - $s)->in_units('minutes') % (24 * 60);

    use integer;
    sum map +($diff % $_, $diff /= $_)[0], @$div;
}

See the full solution to task 2.

J

As J has builtin support for mixed radix numbers, the solution is even simpler with it. Given a (possibly boxed) 2x2-matrix H1 M1; H2 M2, the hours and minutes are interpreted as numbers with radices 24, 60. Then the difference modulo 1 day is converted into the 24, 4, 3, 5-radix system and the sum over the “digits” is calculated.

ConvertTime =. {{+/ 24 4 3 5 #: (24 * 60) | -~/ 24 60 #. > y}}

echo ConvertTime 2 30; 2 45
echo ConvertTime 11 55; 12 15
echo ConvertTime 9 0; 13 0
echo ConvertTime 23 45; 0 30
echo ConvertTime 14 20; 15 25

exit ''

I don’t know if this follows the “spirit” of J as it is my first program in this language.

See the full solution.