Perl Weekly Challenge 282: Good Integer
These are some answers to the Week 281, Task 1, of the Perl Weekly Challenge organized by Mohammad S. Anwar.
Spoiler Alert: This weekly challenge deadline is due in a few days from now (on August 18, 2024, at 23:59). This blog post provides some solutions to this challenge. Please don’t read on if you intend to complete the challenge on your own.
Task 1: Good Integer
You are given a positive integer, $int
, having 3 or more digits.
Write a script to return the Good Integer in the given integer or -1 if none found.
A good integer is exactly three consecutive matching digits.
Example 1
Input: $int = 12344456
Output: "444"
Example 2
Input: $int = 1233334
Output: -1
Example 3
Input: $int = 10020003
Output: "000"
Good Integer in Raku
I first tried with a single regex using lookaround assertions such as <!before $0>
and <!after $O>
to prevent matches when there is a sequence of more than 3 identical digits, but it appears that it is not possible to combine lookaround assertions with a previous captured match special variable ($0
or $/[0]
), or, at least, that I did not find the proper syntax (but it seems to me that there are some good reasons for this not to be possible).
So I decided to simply use two successive regexes, one to exclude the cases with 4 (or more) identical digits, and the second one to match three identical digits.
sub good-integer ($in) {
return -1 if $in ~~ / (\d) $0 ** 3 /; # 4 digits
return ~$/ if $in ~~ / (\d) $0 ** 2 /; # 3 digits
return -1;
}
my @tests = 12344456, 123444456, 1233334, 10020003;
for @tests -> $test {
printf "%-10s => ", $test;
say good-integer $test;
}
This program displays the following output:
$ raku ./good-integer.raku
12344456 => 444
123444456 => -1
1233334 => -1
10020003 => 000
Good Integer in Perl
I suspect that Perl's look-ahead and look-behind assertions will have the same behavior as Raku's lookaround assertions. So, I used the same strategy as in Raku, and this is actually a port to Perl of the previous Raku program.
use strict;
use warnings;
use feature 'say';
sub good_integer {
my $in = shift;
return -1 if $in =~ /(\d)\1{3}/;
return $1 x 3 if $in =~ /(\d)\1{2}/;
return -1;
}
my @tests = (12344456, 123444456, 1233334, 10020003);
for my $test (@tests) {
printf "%-10s => ", $test;
say good_integer $test;
}
This program displays the following output:
$ perl ./good-integer.pl
12344456 => 444
123444456 => -1
1233334 => -1
10020003 => 000
Wrapping up
The next week Perl Weekly Challenge will start soon. If you want to participate in this challenge, please check https://perlweeklychallenge.org/ and make sure you answer the challenge before 23:59 BST (British summer time) on August 25, 2024. And, please, also spread the word about the Perl Weekly Challenge if you can.
Leave a comment