This is my response to The Weekly Challenge #378.
Input: $str = "aaaaa77777"
Output: -1
The only digit in the given string is 7 and there is no second digit.
Example 2:
Input: $str = "abcde"
Output: -1
No numerical digits in the given string.
Example 3:
Input: $str = "9zero8eight7seven9"
Output: 8
Example 4:
Input: $str = "xyz9876543210"
Output: 8
Example 5:
Input: $str = "4abc4def2ghi8jkl2"
Output: 4
#! /usr/bin/env raku
subset ALPHANUM where /^ <[a..z A..Z 0..9]>+ $ /;
unit sub MAIN (ALPHANUM $str, :v(:$verbose));
my @distinct = $str.comb.grep( * ~~ /\d/ ).sort(-*).unique;
say ": Distinct digits: { @distinct.elems ?? @distinct.join(",") !! "none" }" if $verbose;
say @distinct.elems > 1
?? @distinct[1]
!! '-1';
[3] A custom type, set up with subset, to enforce alphanumeric
characters only on the input in [5].
See docs.raku.org/language/typesystem#subset for more information about subset.
[5] Apply the custom type on the input.
[7] Split the string into individual characters (with comb), and only keep the
ones that are digits (with grep). Then we sort the resulting list of (zero or
more) digits in reverse order (the (-*) argument), and throw away duplicates,
if any, with unique.
[11] If we have more than 1 element, print the second one (with index 1). Otherwise print «-1» to indicate failure.
Running it:
$ ./second-largest-digit aaaaa77777
-1
$ ./second-largest-digit abcde
-1
$ ./second-largest-digit 9zero8eight7seven9
8
$ ./second-largest-digit xyz9876543210
8
$ ./second-largest-digit 4abc4def2ghi8jkl2
4
Looking good.
With verbose mode:
$ ./second-largest-digit -v aaaaa77777
: Distinct digits: 7
-1
$ ./second-largest-digit -v abcde
: Distinct digits: none
-1
$ ./second-largest-digit -v 9zero8eight7seven9
: Distinct digits: 9,8,7
8
$ ./second-largest-digit -v xyz9876543210
: Distinct digits: 9,8,7,6,5,4,3,2,1,0
8
$ ./second-largest-digit -v 4abc4def2ghi8jkl2
: Distinct digits: 8,4,2
4
Input: $str1 = "acb", $str2 = "cba", $str3 = "cdb"
Output: true
$str1 = "acb" = 021
$str2 = "cba" = 210
$str3 = "cdb" = 231
$str1 + $str2 = $str3
Example 2:
Input: $str1 = "aab", $str2 = "aac", $str3 = "ad"
Output: true
$str1 = "aab" = 001
$str2 = "aac" = 002
$str3 = "ad" = 03
Example 3:
Input: $str1 = "bc", $str2 = "je", $str3 = "jg"
Output: false
$str1 = "bc" = 12
$str2 = "je" = 94
$str3 = "jg" = 96
Example 4:
Input: $str1 = "a", $str2 = "aaaa", $str3 = "aa"
Output: true
$str1 = "a" = 0
$str2 = "aaaa" = 0000
$str3 = "aa" = 00
Example 5:
Input: $str1 = "c", $str2 = "d", $str3 = "h"
Output: false
$str1 = "c" = 2
$str2 = "d" = 3
$str3 = "h" = 7
Example 6:
Input: $str1 = "gfi", $str2 = "hbf", $str3 = "bdhd"
Output: true
$str1 = "gfi" = 658
$str2 = "hbf" = 715
$str3 = "bdhd" = 1373
#! /usr/bin/env raku
subset AJ where /^ <[a..j]>+ $ /;
unit sub MAIN (AJ $str1, AJ $str2, AJ $str3,
:v(:$verbose));
sub digitise (AJ $string)
{
return $string.comb.map( *.ord - 'a'.ord ).join;
}
my $num1 = digitise($str1);
my $num2 = digitise($str2);
my $num3 = digitise($str3);
if $verbose
{
say ": \$str1 = '$str1' = $num1";
say ": \$str2 = '$str2' = $num2";
say ": \$str3 = '$str3' = $num3";
}
say $num1 + $num2 == $num3;
[3] Another subset. It is customary (I think) to use uppercase letters on subset names, but it does look odd as the letters themselves are lowercase in this case (pun intended).
[5] Apply the subset on the three strings.
[8] Procedure to turn a string into the prescribed number.
[10] We take each letter and map each one into a digit (a=0, b=1, ..
j=9), before joining them together to form a multi-digit integer.
[13,14,15] Digitise the three strings.
[24] Is the sum of the first two numbers equal to the third?
Running it:
$ ./sum-of-words -v acb cba cdb
True
$ ./sum-of-words -v aab aac ad
True
$ ./sum-of-words -v bc je jg
False
$ ./sum-of-words -v a aaaa aa
True
$ ./sum-of-words -v c d h
False
$ ./sum-of-words -v gfi hbf bdhd
True
Looking good.
With verbose mode:
$ ./sum-of-words -v acb cba cdb
: $str1 = 'acb' = 021
: $str2 = 'cba' = 210
: $str3 = 'cdb' = 231
True
$ ./sum-of-words -v aab aac ad
: $str1 = 'aab' = 001
: $str2 = 'aac' = 002
: $str3 = 'ad' = 03
True
$ ./sum-of-words -v bc je jg
: $str1 = 'bc' = 12
: $str2 = 'je' = 94
: $str3 = 'jg' = 96
False
$ ./sum-of-words -v a aaaa aa
: $str1 = 'a' = 0
: $str2 = 'aaaa' = 0000
: $str3 = 'aa' = 00
True
$ ./sum-of-words -v c d h
: $str1 = 'c' = 2
: $str2 = 'd' = 3
: $str3 = 'h' = 7
False
$ ./sum-of-words -v gfi hbf bdhd
: $str1 = 'gfi' = 658
: $str2 = 'hbf' = 715
: $str3 = 'bdhd' = 1373
True
And that's it.