| 21 November 2025 | Challenge 348 |
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:
- Create
DateTimeobjects from the source and target strings. - Get the difference between target and source in minutes modulo 1 day.
- Convert the difference into the
mixed radix positional system
with weights
(1, 5, 15, 60, 1440)by repeated Euclidian division. The divisors are the quotients between successive weights, i.e.(5, 3, 4, 24). - Take the
sumover the “digits”.
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.