Armstring or Strong
with Raku

by Arne Sommer

Armstring or Strong with Raku

[404] Published 28. June 2026.

This is my response to The Weekly Challenge #379.

#379.1 Reverse String You are given a string.

Write a script to reverse the given string without using standard reverse function.

Example 1:
Input: $str = ""
Output: ""
Example 2:
Input: $str = "reverse the given string"
Output: "gnirts nevig eht esrever"
Example 3:
Input: $str = "Perl is Awesome"
Output: "emosewA si lreP"
Example 4:
Input: $str = "v1.0.0-Beta!"
Output: "!ateB-0.0.1v"
Example 5:
Input: $str = "racecar"
Output: "racecar"
File: reverse-string-substr
#! /usr/bin/env raku

multi sub MAIN ($str where $str.chars > 0)
{
  say ($str.chars -1 ... 0).map({ $str.substr($_,1) }).join;
}

multi sub MAIN ($str where $str.chars == 0)
{
  say "";
}

[3] This code block does not work if we give it an empty string, so we wrap it in a multi sub MAIN that is only used if we get a non-empty string.

See docs.raku.org/syntax/multi for more information about multi.

[5] Take all the indices in the string, from the end towards 0, apply map on each index to get the (single) character at that index. Then we join the characters and print the result.

[8] This version handles empty strings;

[10] in which case we print an empty string.

A more elegant solution, perhaps:

File: reverse-string-pop
#! /usr/bin/env raku

unit sub MAIN ($str);

my @input = $str.comb;

print @input.pop while @input;

say "";

[3] No empty/not empty restrictions on the string this time around.

[5] Split the string into a list of individual characters (with comb).

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

[7] As long as the list is non-empty (the while), get the last character (with pop) and print it.

[9] Add a final newline.

Running it:

$ ./reverse-string-substr ""


$ ./reverse-string-pop ""


$ ./reverse-string-substr "reverse the given string"
gnirts nevig eht esrever

$ ./reverse-string-pop "reverse the given string"
gnirts nevig eht esrever

$ ./reverse-string-substr "Perl is Awesome"
emosewA si lreP

$ ./reverse-string-pop "Perl is Awesome"
emosewA si lreP

$ ./reverse-string-substr 'v1.0.0-Beta!'
!ateB-0.0.1v

$ ./reverse-string-pop 'v1.0.0-Beta!'
!ateB-0.0.1v

$ ./reverse-string-substr "racecar"
racecar

$ ./reverse-string-pop "racecar"
racecar

Looking good.

Verbose mode did not make much sense.

#379.2 Armstrong Number You are given two integers, $base and $limit.

Write a script to find all Armstrong numbers in base $base that are less than $limit.

If raising each of the digits of a nonnegative integer to the power of the total number of digits, then taking the sum, equals the original number, it is an Armstrong number.

Example 1:
Input: $base = 10, $limit = 1000
Output: (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 153, 370, 371, 407)
Example 2:
Input: $base = 7, $limit = 1000
Output: (0, 1, 2, 3, 4, 5, 6, 10, 25, 32, 45, 133, 134, 152, 250)
Example 3:
Input: $base = 16, $limit = 1000
Output: (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 342, \
  371, 520, 584, 645)
File: armstrong-number
#! /usr/bin/env raku

unit sub MAIN (UInt :$base where 36 >= $base >= 2,
               UInt :$limit where $limit > 0 = 1000,
               :l(:$loquacious),
               :v(:$verbose) = $loquacious);

my @result;

for 1 .. $limit -1 -> $i
{
  my $in-base      = $i.base($base);
  my $sum          =
     $in-base.comb.map({ $_ ** $in-base.chars }).sum;

  my $is-armstrong = $i eq $sum;

  say ": $i (base $base) -> $in-base -> $sum \
    { $is-armstrong ?? "yes" !! "no" }"
      if $loquacious || ($verbose && $is-armstrong); 

  @result.push: $i if $is-armstrong;
}

say "(" ~ @result.join(", ") ~ ")";

[3] The base as an (unsigned) integer between 2 and 36, both included, as that is the range of what base (in [12]) can handle.

[4] The limit, with a default value of 1000 - as used in the examples.

[5] Loquacious is an excessively verbose mode, and it enables the normal verbose mode as well (in [9]).

[8] The result will end up here.

[10] Iterate over the numbers from 0 to the (decimal) limit.

[12] Use base to convert the decimal number into the given base.

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

[13,14] Raise each digit to the power of the number of digits in the original number, and add them up.

[16] Do we have an Armstrong number?

[22] If so, add it to the result.

[25] Pretty print the result.

Running it:

$ ./armstrong-number -base=10
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 153, 370, 371, 407)

$ ./armstrong-number -base=7
(0, 1, 2, 3, 4, 5, 6, 10, 25, 32, 45, 133, 134, 152, 250)

$ ./armstrong-number -base=16
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 342, 371, 520, 584, 645)

Looking good.

With verbose mode:

$ ./armstrong-number -base=10 -v
: 0 (base 10) -> 0 -> 0 yes
: 1 (base 10) -> 1 -> 1 yes
: 2 (base 10) -> 2 -> 2 yes
: 3 (base 10) -> 3 -> 3 yes
: 4 (base 10) -> 4 -> 4 yes
: 5 (base 10) -> 5 -> 5 yes
: 6 (base 10) -> 6 -> 6 yes
: 7 (base 10) -> 7 -> 7 yes
: 8 (base 10) -> 8 -> 8 yes
: 9 (base 10) -> 9 -> 9 yes
: 153 (base 10) -> 153 -> 153 yes
: 370 (base 10) -> 370 -> 370 yes
: 371 (base 10) -> 371 -> 371 yes
: 407 (base 10) -> 407 -> 407 yes
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 153, 370, 371, 407)

$ ./armstrong-number -base=7 -v
: 0 (base 7) -> 0 -> 0 yes
: 1 (base 7) -> 1 -> 1 yes
: 2 (base 7) -> 2 -> 2 yes
: 3 (base 7) -> 3 -> 3 yes
: 4 (base 7) -> 4 -> 4 yes
: 5 (base 7) -> 5 -> 5 yes
: 6 (base 7) -> 6 -> 6 yes
: 10 (base 7) -> 13 -> 10 yes
: 25 (base 7) -> 34 -> 25 yes
: 32 (base 7) -> 44 -> 32 yes
: 45 (base 7) -> 63 -> 45 yes
: 133 (base 7) -> 250 -> 133 yes
: 134 (base 7) -> 251 -> 134 yes
: 152 (base 7) -> 305 -> 152 yes
: 250 (base 7) -> 505 -> 250 yes
(0, 1, 2, 3, 4, 5, 6, 10, 25, 32, 45, 133, 134, 152, 250)

$ ./armstrong-number -base=16 -v
: 0 (base 16) -> 0 -> 0 yes
: 1 (base 16) -> 1 -> 1 yes
: 2 (base 16) -> 2 -> 2 yes
: 3 (base 16) -> 3 -> 3 yes
: 4 (base 16) -> 4 -> 4 yes
: 5 (base 16) -> 5 -> 5 yes
: 6 (base 16) -> 6 -> 6 yes
: 7 (base 16) -> 7 -> 7 yes
: 8 (base 16) -> 8 -> 8 yes
: 9 (base 16) -> 9 -> 9 yes
: 10 (base 16) -> A -> 10 yes
: 11 (base 16) -> B -> 11 yes
: 12 (base 16) -> C -> 12 yes
: 13 (base 16) -> D -> 13 yes
: 14 (base 16) -> E -> 14 yes
: 15 (base 16) -> F -> 15 yes
: 342 (base 16) -> 156 -> 342 yes
: 371 (base 16) -> 173 -> 371 yes
: 520 (base 16) -> 208 -> 520 yes
: 584 (base 16) -> 248 -> 584 yes
: 645 (base 16) -> 285 -> 645 yes
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 342, 371, 520, 584, 645)

Feel free to have a go at loquacious mode...

And that's it.