Perl Weekly Challenge: You Have No Choice

Perl Weekly Challenge 362‘s tasks are Echo Chamber (which made me think maybe I should pick something by Echo and the Bunnymen) and Spellbound Sorting.

Spellbound? …yeah, I had to give you the song by Siouxsie and The Banshees. Especially because this was the task that took the most time…

Task 1: Echo Chamber

You are given a string containing lowercase letters.

Write a script to transform the string based on the index position of each character (starting from 0). For each character at position i, repeat it i + 1 times.

Example 1

Input: "abca"
Output: "abbcccaaaa"

Index 0: "a" -> repeated 1 time  -> "a"
Index 1: "b" -> repeated 2 times -> "bb"
Index 2: "c" -> repeated 3 times -> "ccc"
Index 3: "a" -> repeated 4 times -> "aaaa"

Example 2

Input: "xyz"
Output: "xyyzzz"

Index 0: "x" -> "x"
Index 1: "y" -> "yy"
Index 2: "z" -> "zzz"

Example 3

Input: "code"
Output: "coodddeeee"

Index 0: "c" -> "c"
Index 1: "o" -> "oo"
Index 2: "d" -> "ddd"
Index 3: "e" -> "eeee"

Example 4

Input: "hello"
Output: "heelllllllooooo"

Index 0: "h" -> "h"
Index 1: "e" -> "ee"
Index 2: "l" -> "lll"
Index 3: "l" -> "llll"
Index 4: "o" -> "ooooo"

Example 5

Input: "a"
Output: "a"

Index 0: "a" -> "a"

Approach

This one is fairly straightforward: split the string into an array of characters, maintain a counter starting at 1, shift a character off the front of the array, duplicate the character the number of times in the counter, then increment the counter and repeat until we run out of characters.

Raku

And, as usual, the moment I went to write my first solution after I wrote my approach, I realized my approach had steps I didn’t need. Yes, I need to split the string into characters, but I don’t need to store it in an array: I can just loop over the results with a for loop. As I’ve noted before, Raku has an infix string repetition operator, x.

sub echo($string) {
  my $i = 1;
  my $result;
  for $string.comb -> $c {
    $result ~= $c x $i++;
  }
  return $result;
}

View the entire Raku script for this task on GitHub.

$ raku/ch-1.raku
Example 1:
Input: "abca"
Output: "abbcccaaaa"

Example 2:
Input: "xyz"
Output: "xyyzzz"

Example 3:
Input: "code"
Output: "coodddeeee"

Example 4:
Input: "hello"
Output: "heelllllllooooo"

Example 5:
Input: "a"
Output: "a"

Perl

The Perl solution looks pretty much exactly like the Raku solution because, as I note a little later, I’ve been writing my Raku exactly like Perl.

sub echo($string) {
  my $i = 1;
  my $result;
  foreach my $c (split //, $string) {
    $result .= $c x $i++;
  }
  return $result;
}

View the entire Perl script for this task on GitHub.

Python

And I always write my Python exactly like Perl, so it looks the same. As I noted in PWC 360, Python’s string repetition operator is *.

def echo(string):
  i = 1
  result = ""
  for c in string:
    result += c * i
    i += 1
  return result

View the entire Python script for this task on GitHub.

Elixir

But because Elixir is a functional language, I decided to not mimic Perl and instead do the loop through a hand-rolled multi-dispatch function using String.duplicate/2 and String.graphemes/1:

def echo([], _), do: ""

def echo([c | rest], i) do
  String.duplicate(c, i) <> echo(rest, i+1)
end

def echo(string), do:
  echo(String.graphemes(string), 1)

View the entire Elixir script for this task on GitHub.

Raku, take 2

Part of the reason I wrote a function for my Elixir solution rather than doing something with Enum.reduce/3 and Kernel.elem/2 (which, by the way, would have been this…)

def echo(string) do
  string
  |> String.graphemes
  |> Enum.reduce({"", 1}, fn c, {result, i} ->
    { result <> String.duplicate(c, i), i+1 }
  end)
  |> elem(0)
end

is that while I was looking for the link to the documentation for the Raku for loop, I ran across Classic loops and why we do not like them:

Classic for loops, with a loop variable being incremented, can be done in Raku through the loop keyword. Other repeat and while loops are also possible.

However, in general, they are discouraged. Raku is a functional and concurrent language; when coding in Raku, you should look at loops in a functional way: processing, one by one, the items produced by an iterator, that is, feeding an item to a block without any kind of secondary effects. This functional view allows also easy parallelization of the operation via the hyper or race auto-threading methods.

And I realized that I’ve been writing Raku like it’s just a newer version of Perl, not a functional language like Elixir. So I decided to rewrite my Raku solution functionally:

multi echo($i, @chars) {
  return "" unless @chars;
  @chars[0] x $i ~ echo($i+1, @chars[1 .. *-1]);
}

multi echo($string) { echo(1, $string.comb); }

This is using the same approach as the Elixir code: the single-argument version of echo splits the string into characters and then calls the multiple-argument version of echo with the character list and the repetition counter. The multiple-argument version then takes the first character off the list, repeats it the number of times indicated by the counter, an recursively calls itself with the remaining characters and an incremented counter. Rather than defining a multi echo($i, @chars where @chars == 0) { "" } to cover the stopping condition for the recursion, I decided to just return from the multiple-argument version early if there’s no characters. It may not be strictly functional, but it feels right to me.


Task 2: Spellbound Sorting

You are given an array of integers.

Write a script to return them in alphabetical order, in any language of your choosing. Default language is English.

Example 1

Input: (6, 7, 8, 9 ,10)
Output: (8, 9, 7, 6, 10)

eight, nine, seven, six, ten

Example 2

Input: (-3, 0, 1000, 99)
Output: (-3, 99, 1000, 0)

minus three, ninety-nine, one thousand, zero

Example 3

Input: (1, 2, 3, 4, 5)

Output: (5, 2, 4, 3, 1) for French language
cinq, deux, quatre, trois, un

Output: (5, 4, 1, 3, 2) for English language
five, four, one, three, two

Example 4

Input: (0, -1, -2, -3, -4)
Output: (-4, -1, -3, -2, 0)

minus four, minus one, minus three, minus two, zero


Example 5
Input: (100, 101, 102)
Output: (100, 101, 102)

one hundred, one hundred and one, one hundred and two

Approach

Now, the moment I saw this, I knew that the way to do this was a CPAN module in the Lingua:: namespace. And I found it: Lingua::EN::Numbers with its function num2en. But if I wanted to do the French sorting in Example 3, then I’d need Lingua::FR::Numbersnumber_to_fr function. Or if I wanted German, I’d need Lingua::DE::Num2Word and num2de_cardinal. For each language, I would need to load a different module and use a different function.

Then I noticed Lingua::Any::Numbers.

The most popular Lingua modules are seem to be the ones that convert numbers into words. These kind of modules exist for a lot of languages. However, there is no standard interface defined for them. Most of the modules’ interfaces are completely different and some do not implement the ordinal conversion at all. Lingua::Any::Numbers tries to create a common interface to call these different modules. And if a module has a known interface, but does not implement the required function/method then the number itself is returned instead of dying.

That’s just what I needed! So after a quick cpanm Task::Lingua::Any::Numbers I found myself with the ability to inflect numbers in 18 different languages.

Perl

So I went a little overboard. I’m allowing you to specify the language to use on the command line, and the script is issuing an error if the language isn’t known.

The basic approach, however, is to create a hash of all the numbers in the array with the word representation of each number as the hash key and the number as the value (line 31). Then we sort the keys alphabetically (line 32), and use that to generate a new array from the values corresponding to the sorted words (line 35).

use Getopt::Long;
use Lingua::Any::Numbers qw( :standard );
use List::AllUtils qw( none );
use Locale::Codes::Language;

binmode STDOUT, ":utf8";

my $help = 0;
my $lang = 'EN';
GetOptions
  'language=s' => \$lang,
  'help|?'     => \$help
;
my $bad_language = none { $lang eq $_ } available;
if ($help || $bad_language ) {
  my $language = code2language($lang) // ''; # translate language code
  $language = " ($language)" if $language; # wrap in parens if defined
  say "unknown language: $lang$language" if $bad_language;
  say "usage: $0 [--language=XX] [--help | -?]\n";
  say "Avalable languages:";
  foreach my $code (available) {
    say " * $code - ".code2language($code);
  }
  exit;
}

sub spellbound($lang, @nums) {
  my %words_to_num = map { to_string($_, $lang) => $_} @nums;
  my @wordlist = sort { fc($a) cmp fc($b) } keys %words_to_num;
  return (
    join(', ', @wordlist),
    map { $words_to_num{$_} } @wordlist
  );
}

View the entire Perl script for this task on GitHub.

$ perl/ch-2.pl
Example 1:
Input: (6, 7, 8, 9, 10)
Output: (8, 9, 7, 6, 10)

English: eight, nine, seven, six, ten

Example 2:
Input: (-3, 0, 1000, 99)
Output: (-3, 99, 1000, 0)

English: negative three, ninety-nine, one thousand, zero

Example 3:
Input: (1, 2, 3, 4, 5)
Output: (5, 4, 1, 3, 2)

English: five, four, one, three, two

Example 4:
Input: (0, -1, -2, -3, -4)
Output: (-4, -1, -3, -2, 0)

English: negative four, negative one, negative three, negative two, zero

Example 5:
Input: (100, 101, 102)
Output: (100, 101, 102)

English: one hundred, one hundred and one, one hundred and two

$ perl/ch-2.pl --lang FR
Example 1:
Input: (6, 7, 8, 9, 10)
Output: (10, 8, 9, 7, 6)

French: dix, huit, neuf, sept, six

Example 2:
Input: (-3, 0, 1000, 99)
Output: (1000, -3, 99, 0)

French: mille, moins trois, quatre-vingt-dix-neuf, zéro

Example 3:
Input: (1, 2, 3, 4, 5)
Output: (5, 2, 4, 3, 1)

French: cinq, deux, quatre, trois, un

Example 4:
Input: (0, -1, -2, -3, -4)
Output: (-2, -4, -3, -1, 0)

French: moins deux, moins quatre, moins trois, moins un, zéro

Example 5:
Input: (100, 101, 102)
Output: (100, 102, 101)

French: cent, cent deux, cent un

$ perl/ch-2.pl --lang JA
Example 1:
Input: (6, 7, 8, 9, 10)
Output: (7, 9, 8, 6, 10)

Japanese: 七, 九, 八, 六, 十

Example 2:
Input: (-3, 0, 1000, 99)
Output: (-3, 99, 1000, 0)

Japanese: −三, 九十九, 千, 零

Example 3:
Input: (1, 2, 3, 4, 5)
Output: (1, 3, 2, 5, 4)

Japanese: 一, 三, 二, 五, 四

Example 4:
Input: (0, -1, -2, -3, -4)
Output: (-1, -3, -2, -4, 0)

Japanese: −一, −三, −二, −四, 零

Example 5:
Input: (100, 101, 102)
Output: (100, 101, 102)

Japanese: 百, 百一, 百二

$ perl/ch-2.pl --lang HE
unknown language: HE (Hebrew)
usage: perl/ch-2.pl [--language=XX] [--help | -?]

Avalable languages:
 * AF - Afrikaans
 * BG - Bulgarian
 * CS - Czech
 * DE - German
 * EN - English
 * ES - Spanish
 * EU - Basque
 * FR - French
 * ID - Indonesian
 * IT - Italian
 * JA - Japanese
 * NL - Dutch
 * NO - Norwegian
 * PL - Polish
 * PT - Portuguese
 * SV - Swedish
 * TR - Turkish
 * ZH - Chinese

Raku

Raku proved to be a little tricky. The Lingua::Number module appears to be broken

$ zef install Lingua::Number
===> Searching for: Lingua::Number
===> Staging Lingua::Number
===> Staging [OK] for Lingua::Number
===> Testing: Lingua::Number
[Lingua::Number] # Failed test 'basically works in english'
[Lingua::Number] # at t/00-basic.t line 7
[Lingua::Number] # expected: 'three million one hundred twenty-three thousand four hundred fifty-six'
[Lingua::Number] #      got: '  million'
[Lingua::Number] # Failed test 'español también'
[Lingua::Number] # at t/00-basic.t line 8
[Lingua::Number] # expected: 'tres millones ciento veintitrés mil cuatrocientos cincuenta y seis'
[Lingua::Number] #      got: '  millones'
[Lingua::Number] # Failed test 'also nihongo'
[Lingua::Number] # at t/00-basic.t line 9
[Lingua::Number] # expected: '三百十二万三千四百五十六'
[Lingua::Number] #      got: ' 万'
[Lingua::Number] # Failed test 'zero is okay'
[Lingua::Number] # at t/00-basic.t line 10
[Lingua::Number] # expected: 'zero'
[Lingua::Number] #      got: ''
[Lingua::Number] # Failed test 'english first'
[Lingua::Number] # at t/00-basic.t line 13
[Lingua::Number] # expected: 'five hundred sixty-seven point eight nine'
[Lingua::Number] #      got: '  hundred point  '
[Lingua::Number] Too few positionals passed; expected 2 arguments but got 1
[Lingua::Number]   in sub rule2text at /usr/local/Cellar/rakudo-star/2025.11/share/pe
[Lingua::Number] rl6/site/sources/9263FC8D469831E03B6D475206FAFA790C37E2E7 (Lingua::Number) line 124
[Lingua::Number]   in block  at /usr/local/Cellar/rakudo-star/2025.11/share/perl6/site/sources/9263FC8D469831E03B6D475206FAFA790C37E2E7 (Lingua::Number) line 103
[Lingua::Number]   in sub rule2text at /usr/
[Lingua::Number] local/Cellar/rakudo-star/2025.11/share/perl6/site/sources/9263FC8D469831E03B6D475206FAFA790C37E2E7 (Lingua::Number) line 100
[Lingua::Number]   in sub cardinal at /usr/local/Cellar/rakudo-star/2025.11/share/perl6/site/sources/9263FC8D469831E03B6D475206FAFA790C37E2E7 (Lingua::Number) line 226
[Lingua::Number]   in block <unit> at t/00-basic.t line 14
[Lingua::Number]
===> Testing [FAIL]: Lingua::Number
Aborting due to test failure: Lingua::Number (use --force-test to override)
master|≫9∆6

$ zef install Lingua::Number --force-test
===> Searching for: Lingua::Number
===> Staging Lingua::Number
===> Staging [OK] for Lingua::Number
===> Testing: Lingua::Number
[Lingua::Number] # Failed test 'basically works in english'
[Lingua::Number] # at t/00-basic.t line 7
[Lingua::Number] # expected: 'three million one hundred twenty-three thousand four hundred fifty-six'
[Lingua::Number] #      got: '  million'
[Lingua::Number] # Failed test 'español también'
[Lingua::Number] # at t/00-basic.t line 8
[Lingua::Number] # expected: 'tres millones ciento veintitrés mil cuatrocientos cincuenta y seis'
[Lingua::Number] #      got: '  millones'
[Lingua::Number] # Failed test 'also nihongo'
[Lingua::Number] # at t/00-basic.t line 9
[Lingua::Number] # expected: '三百十二万三千四百五十六'
[Lingua::Number] #      got: ' 万'
[Lingua::Number] # Failed test 'zero is okay'
[Lingua::Number] # at t/00-basic.t line 10
[Lingua::Number] # expected: 'zero'
[Lingua::Number] #      got: ''
[Lingua::Number] # Failed test 'english first'
[Lingua::Number] # at t/00-basic.t line 13
[Lingua::Number] # expected: 'five hundred sixty-seven point eight nine'
[Lingua::Number] #      got: '  hundred point  '
[Lingua::Number] Too few positionals passed; expected 2 arguments but got 1
[Lingua::Number]   in sub rule2text at /usr/local/Cellar/rakudo-star/2025.11/share/pe
[Lingua::Number] rl6/site/sources/9263FC8D469831E03B6D475206FAFA790C37E2E7 (Lingua::Number) line 124
[Lingua::Number]   in block  at /usr/local/Cellar/rakudo-star/2025.11/share/perl6/site/sources/9263FC8D469831E03B6D475206FAFA790C37E2E7 (Lingua::Number) line 103
[Lingua::Number]   in sub rule2text at /usr/
[Lingua::Number] local/Cellar/rakudo-star/2025.11/share/perl6/site/sources/9263FC8D469831E03B6D475206FAFA790C37E2E7 (Lingua::Number) line 100
[Lingua::Number]   in sub cardinal at /usr/local/Cellar/rakudo-star/2025.11/share/perl6/site/sources/9263FC8D469831E03B6D475206FAFA790C37E2E7 (Lingua::Number) line 226
[Lingua::Number]   in block <unit> at t/00-basic.t line 14
[Lingua::Number]
===> Testing [FAIL]: Lingua::Number
[Lingua::Number] Failed to get passing tests, but continuing with --force-test
===> Installing: Lingua::Number

$ raku
Welcome to Rakudo™ Star v2025.11.
Implementing the Raku® Programming Language v6.d.
Built on MoarVM version 2025.11.

To exit type 'exit' or '^D'
[0] > use Lingua::Number;
Nil
[1] > cardinal(-3);
minus
[2] > cardinal(3);

[3] > cardinal(451);
  hundred

So I decided to use a fork of that package, Lingua::NumericWordForms. But… that package only supports forming words from numeric values in Armenian, Bulgarian, English, Japanese, Koremutake, or Russian.

Fine. I’ll do all the sorting in one of those languages. Oh, but then I discovered that it also didn’t handle negative numbers. At least that was something I could easily fix myself by wrapping the function provided by the module. Besides, it gave me a chance to play wth given/when. I added all the languages, even though only six of them are supported. Sue me.

use Getopt::Long;
use Lingua::NumericWordForms;

get-options(
  'language=s' => my $lang,
  'help|?'     => my $help,
  auto-abbreviate => True,
);
$lang //= 'english'; # default language
my @available = from-numeric-word-form('languages').sort;
my $bad_language = $lang.lc eq @available.none;
if ($help || $bad_language ) {
  say "unknown language: $lang" if $bad_language;
  say "usage: $*PROGRAM [--language=XX] [--help | -?]\n";
  say "Avalable languages:";
  for @available -> $code {
    say " * " ~ $code.tc;
  }
  exit;
}

# Lingua::NumericWordForms does not handle negative numbers!
# so we have to wrap the to-numeric-word-form and massage the
# output so it has the appropriate prefix
&to-numeric-word-form.wrap(
  sub ($num, $lang) {
    nextsame if $num >= 0;
    my $minus = do given $lang.lc {
      when 'armenian'    { 'բացասական ' }
      when 'azerbaijani' { 'mənfi ' }
      when 'azərbaycan'  { 'mənfi ' }
      when 'bulgarian'   { 'минус ' }
      when 'český'       { 'mínus ' }
      when 'czech'       { 'mínus ' }
      when 'deutsch'     { 'minus ' }
      when 'français'    { 'moins ' }
      when 'french'      { 'moins ' }
      when 'german'      { 'minus ' }
      when 'greek'       { 'μείον ' }
      when 'japanese'    { 'マイナス' }
      when 'kazakh'      { 'минус ' }
      when 'korean'      { '마이너스 ' }
      when 'koremutake'  { 'minus ' }
      when 'qazaq'       { 'минус ' }
      when 'казак'       { 'минус ' }
      when 'қазақ'       { 'минус ' }
      when 'ελληνικά'    { 'μείον ' }
      when 'български'   { 'минус ' }
      when 'Հայերեն'      { 'բացասական ' }
      when '한국어'        { '마이너스 ' }
      when '日本語'       { 'マイナス' }
      when 'persian'     { 'منها ' }
      when 'polish'      { 'minus ' }
      when 'polski'      { 'minus ' }
      when 'portuguese'  { 'menos ' }
      when 'português'   { 'menos ' }
      when 'romanian'    { 'minus ' }
      when 'română'      { 'minus ' }
      when 'russian'     { 'минус ' }
      when 'руский'      { 'минус ' }
      when 'spanish'     { 'menos ' }
      when 'español'     { 'menos ' }
      when 'ukrainian'   { 'мінус ' }
      when 'український' { 'мінус ' }
      default            { 'negative ' }
    };
    $minus ~ callwith(abs($num), $lang);
  }
);

sub spellbound($lang, @nums) {
  my %words_to_num = @nums.map({
    to-numeric-word-form($_, $lang) => $_
  });
  my @wordlist = %words_to_num.keys.sort: *.fc;
  return (
    @wordlist.join(", "),
    @wordlist.map( { %words_to_num{$_} } )
  );
}

View the entire Raku script for this task on GitHub.

Python

In Python, the module to use appears to be num2words. I had to teach myself how to use argparse, Python’s parser for command-line options and arguments, but fortunately there’s a good tutorial on it.

import argparse
import sys
from num2words import num2words, CONVERTER_CLASSES

# parse the command line to grab the language
available = sorted(CONVERTER_CLASSES.keys())

epilog = "Available languages:"
for lang in available:
  epilog += f"\n * {lang}"

parser = argparse.ArgumentParser(
  add_help=False, # allow me to add -? to help
  epilog=epilog,
  # this formatter doesn't try to reformat the epilog
  formatter_class=argparse.RawDescriptionHelpFormatter
)
parser.add_argument(
  '-?', '-h', '--help', action='help', 
  help='show this help message and exit'
)
parser.add_argument(
  '-l', '--lang', '--language', action='store'
)
args = parser.parse_args()

if args.lang:
  lang = args.lang
else:
  lang = 'en'

if lang not in available:
  print(f'unknown language: {lang}')
  parser.print_help()
  sys.exit()

# here's the actual code

def spellbound(lang, nums):
  words_to_num = {
    num2words(num, lang=lang): num for num in nums
  }
  wordlist = sorted(words_to_num.keys())
  return (
    ", ".join(wordlist),
    [ words_to_num[word] for word in wordlist ]
  )

View the entire Python script for this task on GitHub.

Elixir

In Elixir, the module to load for generating words from numbers is Cldr. As with Python, I needed to teach myself how to use OptionParser for parsing the command line. I didn’t provide a listing of available languages in the help text, mostly because there are so many. I decided to just list the locales I wanted at the top of the script. Also, by this point I was getting a little tired, and I just wanted to finish this task, which has become much larger than I’d anticipated.

But you can still see the meat of my algorithm, there on lines 17-31: making a map of word representations to numbers, creating a list of those word representations sorted alphabetically, and then returning a list of the numbers corresponding to those word representations.

locales = ["fr", "en", "de", "ja"]

Mix.install([ {:ex_cldr_numbers, "~> 2.33"} ])

# the Cldr documentation calls this a "Backend Module"
defmodule PWC.Cldr do
  use Cldr,
    default_locale: "en",
    locales: locales,
    add_fallback_locales: false,
    providers: [Cldr.Number],
    data_dir: "./priv/cldr"
end

defmodule PWC do
  def spellbound(nums) do
    words_to_num = Enum.reduce(nums, %{}, fn num, words_to_num ->
      {_, words} = PWC.Cldr.Number.to_string(
        num, format: :spellout
      )
      Map.put(words_to_num, words, num)
    end)
    wordlist = words_to_num |> Map.keys |> Enum.sort
    {
      Enum.join(wordlist, ", "),
      Enum.reduce(wordlist, [], fn word, result ->
        result ++ [ Map.get(words_to_num, word) ]
      end)
    }
  end

  def solution(nums) do
    IO.puts("Input: (" <> Enum.join(nums, ", ") <> ")")
    {words, sorted} = spellbound(nums)
    IO.puts("Output: (" <> Enum.join(sorted, ", ") <> ")")
    IO.puts("\n#{PWC.Cldr.get_locale()}: " <> words)
  end
end

# process the command line for the language
options = [ language: :string, help: :boolean ]
case OptionParser.parse(System.argv(), strict: options) do
  {parsed, _args, []} ->
    cond do
      parsed[:help] ->
        IO.puts("usage: ch-2.exs --language <language>")
      parsed[:language] ->
        ok = locales |> Enum.find_value(
          fn l -> if l == parsed[:language], do: true, else: false
        end)
        if ok do
          PWC.Cldr.put_locale(parsed[:language])
        else
          IO.puts("Unknown locale: #{parsed[:language]}")
          IO.puts("Locales: #{inspect(locales)}")
          System.halt(1)
        end
      true -> :noop
    end
  {_parsed, _args, invalid} ->
    IO.puts("Invalid arguments: #{inspect(invalid)}")
    System.halt(1)
end

View the entire Elixir script for this task on GitHub.

Note: when I did try to list the available locales, the list was just too big…

Locales: [:aa, :"aa-DJ", :"aa-ER", :ab, :af, :"af-NA", :agq, :ak, :am, :an, :ann, :apc, :ar, :"ar-AE", :"ar-BH", :"ar-DJ", :"ar-DZ", :"ar-EG", :"ar-EH", :"ar-ER", :"ar-IL", :"ar-IQ", :"ar-JO", :"ar-KM", :"ar-KW", :"ar-LB", :"ar-LY", :"ar-MA", :"ar-MR", :"ar-OM", :"ar-PS", :"ar-QA", :"ar-SA", :"ar-SD", :"ar-SO", :"ar-SS", :"ar-SY", :"ar-TD", :"ar-TN", :"ar-YE", :arn, :as, :asa, :ast, :az, :"az-Arab", :"az-Arab-IQ", :"az-Arab-TR", :"az-Cyrl", :"az-Latn", :ba, :bal, :"bal-Arab", :"bal-Latn", :bas, :be, :"be-tarask", :bem, :bew, :bez, :bg, :bgc, :bgn, :"bgn-AE", :"bgn-AF", :"bgn-IR", :"bgn-OM", :bho, :blo, :blt, :bm, :"bm-Nkoo", :bn, :"bn-IN", :bo, :"bo-IN", :bqi, :br, :brx, :bs, :"bs-Cyrl", :"bs-Latn", :bss, :bua, :byn, :ca, :"ca-AD", :"ca-ES-valencia", :"ca-FR", :"ca-IT", :cad, :cch, :ccp, :"ccp-IN", :ce, :ceb, :cgg, :cho, :chr, :cic, ...]

Here’s all my solutions in GItHub: https://github.com/packy/perlweeklychallenge-club/tree/master/challenge-362/packy-anderson

Leave a Reply