Common Beauty
with Raku

by Arne Sommer

Common Beauty with Raku

[399] Published 26. May 2026.

This is my response to The Weekly Challenge #375.

#375.1 Single Common Word You are given two array of strings.

Write a script to return the number of strings that appear exactly once in each of the two given arrays. String comparison is case sensitive.

Example 1:
Input: @array1 = ("apple", "banana", "cherry")
       @array2 = ("banana", "cherry", "date")
Output: 2
Example 2:
Input: @array1 = ("a", "ab", "abc")
       @array2 = ("a", "a", "ab", "abc")
Output: 2

"a" appears once in @array1 but appears twice in @array2, therefore, not counted.
Example 3:
Input: @array1 = ("orange", "lemon")
       @array2 = ("grape", "melon")
Output: 0
Example 4:
Input: @array1 = ("test", "test", "demo")
       @array2 = ("test", "demo", "demo")
Output: 0
Example 5:
Input: @array1 = ("Hello", "world")
       @array2 = ("hello", "world")
Output: 1

String comparison is case sensitive.
File: single-common-word
#! /usr/bin/env raku

unit sub MAIN ($array1, $array2, :v(:$verbose));

my @array1  = $array1.words;
my @array2  = $array2.words;

my @unique1 = @array1.Bag.grep( *.value == 1 )>>.key;
my @unique2 = @array2.Bag.grep( *.value == 1 )>>.key;

my @common  = @unique1 (&) @unique2;

if $verbose
{
  say ": Array1: @array1[]";
  say ": Array2: @array2[]";
  say ": Unique1: @unique1[]";
  say ": Unique2: @unique2[]";
  say ": Common: { @common>>.key }";
}

say @common.elems;

[3] The two arrays, each one as a space separated string.

[5+6] Extract the words with words, thus giving us the two arrays in this roundabout way.

See docs.raku.org/routine/words for more information about words.

[8+9] Get the values that appear exactly once from the array. We do this with Bag, a hash like structure keeping track of the occurences. Then we grep out (i.e. keep) only those that occure once. The result of this is a list of pair objects, so we pick the key (i.e. the word) from each pair with >>.key.

See docs.raku.org/routine/Bag for more information about Bag.

[13] Get the intersection of the two lists, (i.e. elements occuring in both) using the intersection operator (&).

See docs.raku.org/routine/(&),%20infix%20%E2%88%A9 for more information about the intersection operator (&).

[22] Print the number of common elements.

Running it:

$ ./single-common-word "apple banana cherry" "banana cherry date"
2

$ ./single-common-word "a ab abc" "a a ab abc"
2

$ ./single-common-word "orange lemon" "grape melon"
0

$ ./single-common-word "test test demo" "test demo demo"
0

$ ./single-common-word "Hello world" "hello world"
1

Looking good.

With verbose mode:

$ ./single-common-word -v "apple banana cherry" "banana cherry date"
: Array1: apple banana cherry
: Array2: banana cherry date
: Unique1: banana apple cherry
: Unique2: date cherry banana
: Common: banana cherry
2

$ ./single-common-word -v "a ab abc" "a a ab abc"
: Array1: a ab abc
: Array2: a a ab abc
: Unique1: abc ab a
: Unique2: abc ab
: Common: abc ab
2

$ ./single-common-word -v "orange lemon" "grape melon"
: Array1: orange lemon
: Array2: grape melon
: Unique1: orange lemon
: Unique2: melon grape
: Common: 
0

$ ./single-common-word -v "test test demo" "test demo demo"
: Array1: test test demo
: Array2: test demo demo
: Unique1: demo
: Unique2: test
: Common: 
0

$ ./single-common-word -v "Hello world" "hello world"
: Array1: Hello world
: Array2: hello world
: Unique1: world Hello
: Unique2: world hello
: Common: world
1

#375.2 Find K-Beauty You are given a number and a digit (k).

Write a script to find the K-Beauty of the given number. The K-Beauty of an integer number is defined as the number of substrings of given number when it is read as a string has length of ‘k’ and is a divisor of given number.

Example 1:
Input: $num = 240, $k = 2
Output: 2

Substring with length 2:
24: 240 is divisible by 24
40: 240 is divisible by 40
Example 2:
Input: $num = 1020, $k = 2
Output: 3

Substring with length 2:
10: 240 is divisible by 10
02: 240 is divisible by 2
20: 240 is divisible by 20
Example 3:
Input: $num = 444, $k = 2
Output: 0

Substring with length 2:
First "44": 444 is not divisible by 44
Second "44": 444 is not divisible by 44
Example 4:
Input: $num = 17, $k = 2
Output: 1

Substring with length 2:
17: 17 is divisible by 17
Example 5:
Input: $num = 123, $k = 1
Output: 2

Substring with length 1:
1: 123 is divisible by 1
2: 123 is not divisible by 2
3: 123 is divisible by 3
File: find-k-beauty
#! /usr/bin/env raku

unit sub MAIN (UInt $num,
               UInt $k where $k > 0 && $k <= min($num.chars, 9),
	       :v(:$verbose));

my $matches = 0;

for 0 .. $num.chars - $k -> $start
{
  my $candidate = $num.substr($start, $k);
  my $match     = $num %% $candidate;

  $matches++ if $match;

  say ": candidate $candidate [start:$start stop:{ \
    $start + $k -1 }] { $match ?? "- $num is divisible \
    by { $candidate.Int }" !! ""}" if $verbose;

}
say $matches;

[3] An unsigned integer (i.e. zero is allowed).

[4] Another unsigned integer, but this one must have a value between 1 and "the length of the first one or 9", whichever is smallest.

[7] The number of matches, initially zero.

[9] Iterate over all the possible start positions, allowing for the substring (with length $k) to fit inside the rest of $num.

[11] Use substr to extract the substring.

See docs.raku.org/routine/substr for more information about substr.

[12] Do we have a match?

[14] If so, count it.

[21] Print the result (number of matches).

Running it:

$ ./find-k-beauty 240 2
2

$ ./find-k-beauty 1020 2
3

$ ./find-k-beauty 444 2
0

$ ./find-k-beauty 17 2
1

$ ./find-k-beauty 123 1
2

Looking good.

With verbose mode:

$ ./find-k-beauty -v 240 2
: candidate 24 [start:0 stop:1] - 240 is divisible by 24
: candidate 40 [start:1 stop:2] - 240 is divisible by 40
2

$ ./find-k-beauty -v 1020 2
: candidate 10 [start:0 stop:1] - 1020 is divisible by 10
: candidate 02 [start:1 stop:2] - 1020 is divisible by 2
: candidate 20 [start:2 stop:3] - 1020 is divisible by 20
3

$ ./find-k-beauty -v 444 2
: candidate 44 [start:0 stop:1] 
: candidate 44 [start:1 stop:2] 
0

$ ./find-k-beauty -v 17 2
: candidate 17 [start:0 stop:1] - 17 is divisible by 17
1

$ ./find-k-beauty -v 123 1
: candidate 1 [start:0 stop:0] - 123 is divisible by 1
: candidate 2 [start:1 stop:1] 
: candidate 3 [start:2 stop:2] - 123 is divisible by 3
2

And that's it.