Form Formation
with Raku

by Arne Sommer

Form Formation with Raku

[368] Published 23. October 2025.

This is my response to The Weekly Challenge #344.

Challenge #344.1: Array Form Compute

You are given an array of integers, @ints and an integer, $x.

Write a script to add $x to the integer in the array-form.

The array form of an integer is a digit-by-digit representation stored as an array, where the most significant digit is at the 0th index.

Example 1:
Input: @ints = (1, 2, 3, 4), $x = 12
Output: (1, 2, 4, 6)
Example 2:
Input: @ints = (2, 7, 4), $x = 181
Output: (4, 5, 5)
Example 3:
Input: @ints = (9, 9, 9), $x = 1
Output: (1, 0, 0, 0)
Example 4:
Input: @ints = (1, 0, 0, 0, 0), $x = 9999
Output: (1, 9, 9, 9, 9)
Example 5:
Input: @ints = (0), $x = 1000
Output: (1, 0, 0, 0)
File: array-form-compute
#! /usr/bin/env raku

unit sub MAIN (Int :$x,                             # [1]
               *@ints where @ints.elems > 0         # [2]
                  && all(@ints) ~~ /^<[0..9]>$/);   # [2a]

say "({ (@ints.join + $x).comb.join(", ") })";      # [3]

[1] A named integer argument. It should probably be an unsigned int (UInt), though. Just as the array of integers really is an array of single digits. We do not want any negativity, no(w)?

[2] A slurpy array for the integers, with at least one element.

[3] Glue the integers together to a single value, add x, split the new value into single digits and print them as a comma separated list.

Running it:

$ ./array-form-compute -x=12 1 2 3 4
(1, 2, 4, 6)

$ ./array-form-compute -x=181 2 7 4
(4, 5, 5)

$ ./array-form-compute -x=1 9 9 9
(1, 0, 0, 0)

$ ./array-form-compute -x=9999 1 0 0 0 0
(1, 9, 9, 9, 9)

$ ./array-form-compute -x=1000 0
(1, 0, 0, 0)

Looking good.

No verbose mode for this one.

Challenge #344.2: Array Formation

You are given two lists: @source and @target.

Write a script to see if you can build the exact @target by putting these smaller lists from @source together in some order. You cannot break apart or change the order inside any of the smaller lists in @source.

Example 1:
Input: @source = ([2,3], [1], [4])
       @target = (1, 2, 3, 4)
Output: true

Use in the order: [1], [2,3], [4]
Example 2:
Input: @source = ([1,3], [2,4])
       @target = (1, 2, 3, 4)
Output: false
Example 3:
Input: @source = ([9,1], [5,8], [2])
       @target = (5, 8, 2, 9, 1)
Output: true

Use in the order: [5,8], [2], [9,1]
Example 4:
Input: @source = ([1], [3])
       @target = (1, 2, 3)
Output: false

Missing number: 2
Example 5:
Input: @source = ([7,4,6])
       @target = (7, 4, 6)
Output: true

Use in the order: [7, 4, 6]

We could have used recursive descent (depth first) here, but why bother with all that manual work when the built-in permutations can do it for us absolutely free of hard work (i.e. programming). The downside is that permutations gives us absolutely all permutations to try, even if the already selected values (to the left) do not fit.

File: array-formation
#! /usr/bin/env raku

unit sub MAIN (*@rows where @rows.elems > 0                      # [1]
                  && all(@rows) ~~ /^ <[0..9,]>+ $/,             # [1a]
                :t(:$target) where $target ~~ /^ <[0..9,]>+ $/,  # [2]
		:v(:$verbose));

my @source = @rows>>.split(',')>>.Int;                           # [3]
my @target = $target.split(',')>>.Int;                           # [4]

for @source.permutations -> @combo                               # [5]
{
  my @flat  = @combo[*;*];                                       # [6]
  my $equal = @flat eqv @target;                                 # [7]

  say ": ({ @combo.map({ "[{ $_.join(",")}]" }).join(", ") }) \
    eq ({ @target.join(",") }): { $equal }" if $verbose;

  if $equal                                                      # [8]
  {
    say 'true';                                                  # [8a]
    exit;                                                        # [8b]
  }
}

say 'false';                                                     # [9]

[1] A slurpy array of arrays, with at least one of them. Each element (array) consits of commas and digits only.

[2] The target as a named argument. This is also a comma separated list of integers.

[3] Split the source into a list of lists.

[4] Split the target into a (single) list.

[5] Iterate over the permutations of the source array.

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

[6] Flatten the subarrays in the array.

[7] Are the current permutation equal to the target? We use the equivalence operator eqv, that checks if the two arguments have the same types and values.

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

[8] Are they equal? If so, say so [8a] and finish [8b].

[9] We have failed to find equality in the loop if we reach this point. Say so.

Running it:

$ ./array-formation -t=1,2,3,4 2,3 1 4
true

$ ./array-formation -t=1,2,3,4 1,3 2,4
false

$ ./array-formation -t=5,8,2,9,1 9,1 5,8 2
true

$ ./array-formation -t=1,2,3 1 3
false

$ ./array-formation -t=7,4,6 7,4,6
true

Looking good.

With verbose mode:

$ ./array-formation -v -t=1,2,3,4 2,3 1 4
: ([2,3], [1], [4]) eq (1,2,3,4): False
: ([2,3], [4], [1]) eq (1,2,3,4): False
: ([1], [2,3], [4]) eq (1,2,3,4): True
true

$ ./array-formation -v -t=1,2,3,4 1,3 2,4
: ([1,3], [2,4]) eq (1,2,3,4): False
: ([2,4], [1,3]) eq (1,2,3,4): False
false

$ ./array-formation -v -t=5,8,2,9,1 9,1 5,8 2
: ([9,1], [5,8], [2]) eq (5,8,2,9,1): False
: ([9,1], [2], [5,8]) eq (5,8,2,9,1): False
: ([5,8], [9,1], [2]) eq (5,8,2,9,1): False
: ([5,8], [2], [9,1]) eq (5,8,2,9,1): True
true

$ ./array-formation -v -t=1,2,3 1 3
: ([1], [3]) eq (1,2,3): False
: ([3], [1]) eq (1,2,3): False
false

$ ./array-formation -v -t=7,4,6 7,4,6
: ([7,4,6]) eq (7,4,6): True
true

And that's it.