[User]
Task

Write a subroutine, function, whatever it may be called in your language, that takes an integer number and returns an English text sequence starting with the English cardinal representation of that integer, the word 'is' and then the English cardinal representation of the count of characters that made up the first word, followed by a comma.

Continue the sequence by using the previous count word as the first word of the next phrase, append 'is' and the cardinal count of the letters in *that* word.

Continue until you reach four. Since four has four characters, finish by adding the words 'four is magic' and a period. All integers will eventually wind up at four.

For instance, suppose your are given the integer **3**. Convert **3** to **Three**, add  **is** , then the cardinal character count of three, or **five**, with a comma to separate if from the next phrase. Continue the sequence **five is four,** (five has four letters), and finally, **four is magic.**

```
     Three is five, five is four, four is magic.

```

For reference, here are outputs for 0 through 9.

```
     Zero is four, four is magic.
     One is three, three is five, five is four, four is magic.
     Two is three, three is five, five is four, four is magic.
     Three is five, five is four, four is magic.
     Four is magic.
     Five is four, four is magic.
     Six is three, three is five, five is four, four is magic.
     Seven is five, five is four, four is magic.
     Eight is five, five is four, four is magic.
     Nine is four, four is magic.

```

Some task guidelines
:   * You may assume the input will only contain integer numbers.
    * Cardinal numbers between 20 and 100 may use either hyphens or spaces as word separators but they must use a word separator. (**23** is **twenty three** or **twenty-three** not **twentythree**.)
    * Cardinal number conversions should follow the English short scale. (billion is 1e9, trillion is 1e12, etc.)
    * Cardinal numbers should not include commas. (**20140** is **twenty thousand one hundred forty** not **twenty thousand, one hundred forty**.)
    * When converted to a string, **100** should be **one hundred**, not **a hundred** or **hundred**, **1000** should be **one thousand**, not **a thousand** or **thousand**.
    * When converted to a string, there should be no **and** in the cardinal string. **130** should be **one hundred thirty** not **one hundred and thirty**.
    * When counting characters, count *all* of the characters in the cardinal number including spaces and hyphens. **One hundred fifty-one** should be **21** not **18**.
    * The output should follow the format "N is K, K is M, M is ... four is magic." (unless the input is 4, in which case the output should simply be "four is magic.")
    * The output can either be the return value from the function, or be displayed from within the function.
    * You are encouraged, though not mandated to use proper sentence capitalization.
    * You may optionally support negative numbers. **-7** is **negative seven**.
    * Show the output here for a small representative sample of values, at least 5 but no more than 25. You are free to choose which which numbers to use for output demonstration.

You can choose to use a library, (module, external routine, whatever) to do the cardinal conversions as long as the code is easily and freely available to the public.

If you roll your own, make the routine accept at minimum any integer from 0 up to 999999. If you use a pre-made library, support at least up to unsigned 64 bit integers. (or the largest integer supported in your language if it is less.)

Four is magic is a popular code-golf task. **This is not code golf.** Write legible, idiomatic and well formatted code.

Related tasks
:   * Four is the number of\_letters in the ...
    * Look-and-say sequence
    * Number names
    * Self-describing numbers
    * Summarize and say sequence
    * Spelling of ordinal numbers
    * De Bruijn sequences

[Assistant]
(formerly Perl 6)

**Works with**: Rakudo version 2017.09

Lingua::EN::Numbers module available from the Raku ecosystem.

```
use Lingua::EN::Numbers; # Version 2.4.0 or higher

sub card ($n) { cardinal($n).subst(/','/, '', :g) }

sub magic (Int $int is copy) {
    my $string;
    loop {
       $string ~= "{ card($int) } is ";
       if $int = ($int == 4) ?? 0 !! card($int).chars {
           $string ~= "{ card($int) }, "
       } else {
           $string ~= "magic.\n";
           last
       }
   }
   $string.tc
}

.&magic.say for 0, 4, 6, 11, 13, 75, 337, -164, 9876543209, 2**256;

```

Output:

```
Zero is four, four is magic.

Four is magic.

Six is three, three is five, five is four, four is magic.

Eleven is six, six is three, three is five, five is four, four is magic.

Thirteen is eight, eight is five, five is four, four is magic.

Seventy-five is twelve, twelve is six, six is three, three is five, five is four, four is magic.

Three hundred thirty-seven is twenty-six, twenty-six is ten, ten is three, three is five, five is four, four is magic.

Negative one hundred sixty-four is thirty-one, thirty-one is ten, ten is three, three is five, five is four, four is magic.

Nine billion eight hundred seventy-six million five hundred forty-three thousand two hundred nine is ninety-seven, ninety-seven is twelve, twelve is six, six is three, three is five, five is four, four is magic.

One hundred fifteen quattuorvigintillion seven hundred ninety-two trevigintillion eighty-nine duovigintillion two hundred thirty-seven unvigintillion three hundred sixteen vigintillion one hundred ninety-five novemdecillion four hundred twenty-three octodecillion five hundred seventy septendecillion nine hundred eighty-five sexdecillion eight quindecillion six hundred eighty-seven quattuordecillion nine hundred seven tredecillion eight hundred fifty-three duodecillion two hundred sixty-nine undecillion nine hundred eighty-four decillion six hundred sixty-five nonillion six hundred forty octillion five hundred sixty-four septillion thirty-nine sextillion four hundred fifty-seven quintillion five hundred eighty-four quadrillion seven trillion nine hundred thirteen billion one hundred twenty-nine million six hundred thirty-nine thousand nine hundred thirty-six is eight hundred sixty-nine, eight hundred sixty-nine is twenty-four, twenty-four is eleven, eleven is six, six is three, three is five, five is four, four is magic.
```


[User]
The      **Four is ...**      sequence is based on the counting of the number of
letters in the words of the (never─ending) sentence:

```
  Four is the number of letters in the first word of this sentence, two in the second,
  three in the third, six in the fourth, two in the fifth, seven in the sixth, ···

```

Definitions and directives
:   * English is to be used in spelling numbers.
    * **Letters**   are defined as the upper─ and lowercase letters in the Latin alphabet   (**A──►Z**   and   **a──►z**).
    * Commas are not counted,   nor are hyphens (dashes or minus signs).
    * **twenty─three**   has eleven letters.
    * **twenty─three**   is considered one word   (which is hyphenated).
    * no    ***and***    words are to be used when spelling a (English) word for a number.
    * The short scale numbering system (i.e. 2,000,000,000 is two billion) will be used here. wp:Long and short scales

```
         2,000,000,000   is two billion,   not   two milliard.

```

Task
:   * Write a driver (invoking routine) and a function (subroutine/routine···) that returns the sequence (for any positive integer) of the number of letters in the first   **N**   words in the never─ending sentence.   For instance, the portion of the never─ending sentence shown above (2nd sentence of this task's preamble),   the sequence would be:

```
         4  2  3  6  2  7

```

:   * Only construct as much as is needed for the never─ending sentence.
    * Write a driver (invoking routine) to show the number of letters in the   Nth   word,   *as well as*   showing the   Nth   word itself.
    * After each test case, show the total number of characters   (including blanks, commas, and punctuation)   of the sentence that was constructed.
    * Show all output here.

Test cases

```
 Display the first  201  numbers in the sequence   (and the total number of characters in the sentence).
 Display the number of letters  (and the word itself)  of the       1,000th  word.
 Display the number of letters  (and the word itself)  of the      10,000th  word.
 Display the number of letters  (and the word itself)  of the     100,000th  word.
 Display the number of letters  (and the word itself)  of the   1,000,000th  word.
 Display the number of letters  (and the word itself)  of the  10,000,000th  word  (optional).

```

Related tasks
:   * Four is magic
    * Look-and-say sequence
    * Number names
    * Self-describing numbers
    * Self-referential sequence
    * Spelling of ordinal numbers

Also see
:   * See the OEIS sequence A72425 "Four is the number of letters...".
    * See the OEIS sequence A72424 "Five's the number of letters..."

[Assistant]
(formerly Perl 6)

**Works with**: Rakudo version 2017.09

Uses the Lingua::EN::Numbers module to generate both cardinal and ordinal numbers. This module places commas in number words between 3-orders-of-magnitude clusters. E.G. `12345678.&ordinal` becomes: twelve million, three hundred forty-five thousand, six hundred seventy-eighth. Uses a custom 'no-commas' routine to filter them out for accurate character counts. Generates the 'sentence' lazily so only the words needed are ever calculated and reified.

```
use Lingua::EN::Numbers;
no-commas(True);

my $index = 1;
my @sentence = flat 'Four is the number of letters in the first word of this sentence, '.words,
  { @sentence[$index++].&alpha.&cardinal, 'in', 'the', |($index.&ordinal ~ ',').words } ... * ;

sub alpha ( $str ) { $str.subst(/\W/, '', :g).chars }
sub count ( $index ) { @sentence[^$index].join(' ').chars ~ " characters in the sentence, up to and including this word.\n" }

say 'First 201 word lengths in the sequence:';
put ' ', map { @sentence[$_].&alpha.fmt("%2d") ~ (((1+$_) %% 25) ?? "\n" !! '') }, ^201;
say 201.&count;

for 1e3, 1e4, 1e5, 1e6, 1e7 {
    say "{.&ordinal.tc} word, '{@sentence[$_ - 1]}', has {@sentence[$_ - 1].&alpha} characters. ", .&count
}

```

Output:

```
First 201 word lengths in the sequence:
  4  2  3  6  2  7  2  3  5  4  2  4  8  3  2  3  6  5  2  3  5  3  2  3  6
  3  2  3  5  5  2  3  5  3  2  3  7  5  2  3  6  4  2  3  5  4  2  3  5  3
  2  3  8  4  2  3  7  5  2  3 10  5  2  3 10  3  2  3  9  5  2  3  9  3  2
  3 11  4  2  3 10  3  2  3 10  5  2  3  9  4  2  3 11  5  2  3 12  3  2  3
 11  5  2  3 12  3  2  3 11  5  2  3 11  3  2  3 13  5  2  3 12  4  2  3 11
  4  2  3  9  3  2  3 11  5  2  3 12  4  2  3 11  5  2  3 12  3  2  3 11  5
  2  3 11  5  2  3 13  4  2  3 12  3  2  3 11  5  2  3  8  3  2  3 10  4  2
  3 11  3  2  3 10  5  2  3 11  4  2  3 10  4  2  3 10  3  2  3 12  5  2  3
 11
1203 characters in the sentence, up to and including this word.

One thousandth word, 'in', has 2 characters. 6249 characters in the sentence, up to and including this word.

Ten thousandth word, 'in', has 2 characters. 64097 characters in the sentence, up to and including this word.

One hundred thousandth word, 'one', has 3 characters. 659455 characters in the sentence, up to and including this word.

One millionth word, 'the', has 3 characters. 7113560 characters in the sentence, up to and including this word.

Ten millionth word, 'thousand', has 8 characters. 70995729 characters in the sentence, up to and including this word.
```


[User]
Task

Fill with 1's the four sides of square. The rest of the square should be filled with 0's.

If you can please use GUI

Four sides of square - image

### See also

* Matrix with two diagonals
* Mosaic matrix

[Assistant]
This isn't a matrix, especially if it is supposed to be graphical; it's a very small (or extremely low resolution) bitmap.

```
sub hollow ($n) { [1 xx $n], |(0 ^..^ $n).map( { [flat 1, 0 xx $n - 2, 1] } ), [1 xx $n] }

.put for hollow 7;
put '';
.put for hollow 10;

```

Output:

```
1 1 1 1 1 1 1
1 0 0 0 0 0 1
1 0 0 0 0 0 1
1 0 0 0 0 0 1
1 0 0 0 0 0 1
1 0 0 0 0 0 1
1 0 0 0 0 0 1
1 1 1 1 1 1 1

1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 1
1 1 1 1 1 1 1 1 1 1
```


[User]
Generate and draw a fractal tree.

1. Draw the trunk
2. At the end of the trunk, split by some angle and draw two branches
3. Repeat at the end of each branch until a sufficient level of branching is reached

Related tasks

* Pythagoras Tree

[Assistant]
(formerly Perl 6)
Image is created in SVG format.

```
my ($width, $height) = (1000,1000); # image dimension
my $scale = 6/10; # branch scale relative to trunk
my $length = 400; # trunk size

say "<?xml version='1.0' encoding='utf-8' standalone='no'?>
<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN'
'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
<svg width='100%' height='100%' version='1.1'
xmlns='http://www.w3.org/2000/svg'>";

tree($width/2, $height, $length, 3*pi/2);

say "</svg>";

multi tree($, $, $length where { $length < 1}, $) {}
multi tree($x, $y, $length, $angle)
{
	my ($x2, $y2) = ( $x + $length * $angle.cos, $y + $length * $angle.sin);
	say "<line x1='$x' y1='$y' x2='$x2' y2='$y2' style='stroke:rgb(0,0,0);stroke-width:1'/>";
	tree($x2, $y2, $length*$scale, $angle + pi/5);
	tree($x2, $y2, $length*$scale, $angle - pi/5);
}

```


[User]
```
              There is a fine line between numerator and denominator.       ─── anonymous

```

A method to   "reduce"   some reducible fractions is to   *cross out*   a digit from the
numerator and the denominator.   An example is:

```
       16                                                  16
      ────     and then (simply) cross─out the sixes:      ────
       64                                                  64

```

resulting in:

```
        1
       ───
        4

```

Naturally,   this "method" of reduction must reduce to the proper value   (shown as a fraction).

This "method" is also known as   *anomalous cancellation*   and also   *accidental cancellation*.

(Of course,   this "method" shouldn't be taught to impressionable or gullible minds.)        😇

Task

Find and show some fractions that can be reduced by the above "method".

:   * show 2-digit fractions found   (like the example shown above)
    * show 3-digit fractions
    * show 4-digit fractions
    * show 5-digit fractions   (and higher)       *(optional)*
    * show each (above) n-digit fractions separately from other different n-sized fractions, don't mix different "sizes" together
    * for each "size" fraction,   only show a dozen examples   (the 1st twelve found)
    * (it's recognized that not every programming solution will have the same generation algorithm)
    * for each "size" fraction:

    :   :   * show a count of how many reducible fractions were found.   The example (above) is size **2**
            * show a count of which digits were crossed out   (one line for each different digit)

    * for each "size" fraction,   show a count of how many were found.   The example (above) is size **2**
    * show each n-digit example   (to be shown on one line):

    :   :   * show each n-digit fraction
            * show each reduced n-digit fraction
            * show what digit was crossed out for the numerator and the denominator

Task requirements/restrictions
:   * only proper fractions and their reductions   (the result)   are to be used   (no vulgar fractions)
    * only positive fractions are to be used   (no negative signs anywhere)
    * only base ten integers are to be used for the numerator and denominator
    * no zeros   (decimal digit)   can be used within the numerator or the denominator
    * the numerator and denominator should be composed of the same number of digits
    * no digit can be repeated in the numerator
    * no digit can be repeated in the denominator
    * (naturally)   there should be a shared decimal digit in the numerator   *and*   the denominator
    * fractions can be shown as   16/64   (for example)

Show all output here, on this page.

Somewhat related task
:   * Farey sequence       (It concerns fractions.)

References
:   * Wikipedia entry:   proper and improper fractions.
    * Wikipedia entry:   anomalous cancellation and/or accidental cancellation.

[Assistant]
(formerly Perl 6)

**Works with**: Rakudo version 2019.07.1

Anomalous Cancellation

```
my %reduced;
my $digits = 2..4;

for $digits.map: * - 1 -> $exp {
    my $start = sum (0..$exp).map( { 10 ** $_ * ($exp - $_ + 1) });
    my $end   = 10**($exp+1) - sum (^$exp).map( { 10 ** $_ * ($exp - $_) } ) - 1;

    ($start ..^ $end).race(:8degree, :3batch).map: -> $den {
        next if $den.contains: '0';
        next if $den.comb.unique <= $exp;

        for $start ..^ $den -> $num {
            next if $num.contains: '0';
            next if $num.comb.unique <= $exp;

            my $set = ($den.comb.head(* - 1).Set ∩ $num.comb.skip(1).Set);
            next if $set.elems < 1;

            for $set.keys {
                my $ne = $num.trans: $_ => '', :delete;
                my $de = $den.trans: $_ => '', :delete;
                if $ne / $de == $num / $den {
                    print "\b" x 40, "$num/$den:$_ => $ne/$de";
                    %reduced{"$num/$den:$_"} = "$ne/$de";
                }
            }
        }
    }

    print "\b" x 40, ' ' x 40, "\b" x 40;

    my $digit = $exp +1;
    my %d = %reduced.pairs.grep: { .key.chars == ($digit * 2 + 3) };
    say "\n({+%d}) $digit digit reduceable fractions:";
    for 1..9 {
        my $cnt = +%d.pairs.grep( *.key.contains: ":$_" );
        next unless $cnt;
        say "  $cnt with removed $_";
    }
    say "\n  12 Random (or all, if less) $digit digit reduceable fractions:";
    say "    {.key.substr(0, $digit * 2 + 1)} => {.value} removed {.key.substr(* - 1)}"
      for %d.pairs.pick(12).sort;
}

```

Sample output:

```
(4) 2 digit reduceable fractions:
  2 with removed 6
  2 with removed 9

  12 Random (or all, if less) 2 digit reduceable fractions:
    16/64 => 1/4 removed 6
    19/95 => 1/5 removed 9
    26/65 => 2/5 removed 6
    49/98 => 4/8 removed 9

(122) 3 digit reduceable fractions:
  9 with removed 3
  1 with removed 4
  6 with removed 5
  15 with removed 6
  16 with removed 7
  15 with removed 8
  60 with removed 9

  12 Random (or all, if less) 3 digit reduceable fractions:
    149/298 => 14/28 removed 9
    154/352 => 14/32 removed 5
    165/264 => 15/24 removed 6
    176/275 => 16/25 removed 7
    187/286 => 17/26 removed 8
    194/291 => 14/21 removed 9
    286/385 => 26/35 removed 8
    286/682 => 26/62 removed 8
    374/572 => 34/52 removed 7
    473/572 => 43/52 removed 7
    492/984 => 42/84 removed 9
    594/693 => 54/63 removed 9

(660) 4 digit reduceable fractions:
  14 with removed 1
  25 with removed 2
  92 with removed 3
  14 with removed 4
  29 with removed 5
  63 with removed 6
  16 with removed 7
  17 with removed 8
  390 with removed 9

  12 Random (or all, if less) 4 digit reduceable fractions:
    1348/4381 => 148/481 removed 3
    1598/3196 => 158/316 removed 9
    1783/7132 => 178/712 removed 3
    1978/5934 => 178/534 removed 9
    2971/5942 => 271/542 removed 9
    2974/5948 => 274/548 removed 9
    3584/4592 => 384/492 removed 5
    3791/5798 => 391/598 removed 7
    3968/7936 => 368/736 removed 9
    4329/9324 => 429/924 removed 3
    4936/9872 => 436/872 removed 9
    6327/8325 => 627/825 removed 3
```


[User]
**FRACTRAN** is a Turing-complete esoteric programming language invented by the mathematician John Horton Conway.

A FRACTRAN program is an ordered list of positive fractions

P
=
(

f

1
,

f

2
,
…
,

f

m
)
{\displaystyle {\displaystyle P=(f\_{1},f\_{2},\ldots ,f\_{m})}}
, together with an initial positive integer input

n
{\displaystyle {\displaystyle n}}
.

The program is run by updating the integer

n
{\displaystyle {\displaystyle n}}
 as follows:

* for the first fraction,

  f

  i
  {\displaystyle {\displaystyle f\_{i}}}
  , in the list for which

  n

  f

  i
  {\displaystyle {\displaystyle nf\_{i}}}
   is an integer, replace

  n
  {\displaystyle {\displaystyle n}}
   with

  n

  f

  i
  {\displaystyle {\displaystyle nf\_{i}}}
   ;
* repeat this rule until no fraction in the list produces an integer when multiplied by

  n
  {\displaystyle {\displaystyle n}}
  , then halt.

Conway gave a program for primes in FRACTRAN:

:   17

    /
    91
    {\displaystyle {\displaystyle 17/91}}
    ,

    78

    /
    85
    {\displaystyle {\displaystyle 78/85}}
    ,

    19

    /
    51
    {\displaystyle {\displaystyle 19/51}}
    ,

    23

    /
    38
    {\displaystyle {\displaystyle 23/38}}
    ,

    29

    /
    33
    {\displaystyle {\displaystyle 29/33}}
    ,

    77

    /
    29
    {\displaystyle {\displaystyle 77/29}}
    ,

    95

    /
    23
    {\displaystyle {\displaystyle 95/23}}
    ,

    77

    /
    19
    {\displaystyle {\displaystyle 77/19}}
    ,

    1

    /
    17
    {\displaystyle {\displaystyle 1/17}}
    ,

    11

    /
    13
    {\displaystyle {\displaystyle 11/13}}
    ,

    13

    /
    11
    {\displaystyle {\displaystyle 13/11}}
    ,

    15

    /
    14
    {\displaystyle {\displaystyle 15/14}}
    ,

    15

    /
    2
    {\displaystyle {\displaystyle 15/2}}
    ,

    55

    /
    1
    {\displaystyle {\displaystyle 55/1}}

Starting with

n
=
2
{\displaystyle {\displaystyle n=2}}
, this FRACTRAN program will change

n
{\displaystyle {\displaystyle n}}
 to

15
=
2
×
(
15

/
2
)
{\displaystyle {\displaystyle 15=2\times (15/2)}}
, then

825
=
15
×
(
55

/
1
)
{\displaystyle {\displaystyle 825=15\times (55/1)}}
, generating the following sequence of integers:

:   2
    {\displaystyle {\displaystyle 2}}
    ,

    15
    {\displaystyle {\displaystyle 15}}
    ,

    825
    {\displaystyle {\displaystyle 825}}
    ,

    725
    {\displaystyle {\displaystyle 725}}
    ,

    1925
    {\displaystyle {\displaystyle 1925}}
    ,

    2275
    {\displaystyle {\displaystyle 2275}}
    ,

    425
    {\displaystyle {\displaystyle 425}}
    ,

    390
    {\displaystyle {\displaystyle 390}}
    ,

    330
    {\displaystyle {\displaystyle 330}}
    ,

    290
    {\displaystyle {\displaystyle 290}}
    ,

    770
    {\displaystyle {\displaystyle 770}}
    ,

    …
    {\displaystyle {\displaystyle \ldots }}

After 2, this sequence contains the following powers of 2:

:   2

    2
    =
    4
    {\displaystyle {\displaystyle 2^{2}=4}}
    ,

    2

    3
    =
    8
    {\displaystyle {\displaystyle 2^{3}=8}}
    ,

    2

    5
    =
    32
    {\displaystyle {\displaystyle 2^{5}=32}}
    ,

    2

    7
    =
    128
    {\displaystyle {\displaystyle 2^{7}=128}}
    ,

    2

    11
    =
    2048
    {\displaystyle {\displaystyle 2^{11}=2048}}
    ,

    2

    13
    =
    8192
    {\displaystyle {\displaystyle 2^{13}=8192}}
    ,

    2

    17
    =
    131072
    {\displaystyle {\displaystyle 2^{17}=131072}}
    ,

    2

    19
    =
    524288
    {\displaystyle {\displaystyle 2^{19}=524288}}
    ,

    …
    {\displaystyle {\displaystyle \ldots }}

which are the prime powers of 2.

Task

Write a program that reads a list of fractions in a *natural* format from the keyboard or from a string,
to parse it into a sequence of fractions (*i.e.* two integers),
and runs the FRACTRAN starting from a provided integer, writing the result at each step.
It is also required that the number of steps is limited (by a parameter easy to find).

Extra credit

Use this program to derive the first **20** or so prime numbers.

See also

For more on how to program FRACTRAN as a universal programming language, see:

* J. H. Conway (1987). Fractran: A Simple Universal Programming Language for Arithmetic. In: Open Problems in Communication and Computation, pages 4–26. Springer.

* J. H. Conway (2010). "FRACTRAN: A simple universal programming language for arithmetic". In Jeffrey C. Lagarias. The Ultimate Challenge: the 3x+1 problem. American Mathematical Society. pp. 249–264. ISBN 978-0-8218-4940-8. Zbl 1216.68068.

* Number Pathology: Fractran by Mark C. Chu-Carroll; October 27, 2006.

[Assistant]
(formerly Perl 6)

**Works with**: rakudo version 2015-11-03

A Fractran program potentially returns an infinite list, and infinite lists are a common data structure in Raku. The limit is therefore enforced only by slicing the infinite list.

```
sub fractran(@program) {
    2, { first Int, map (* * $_).narrow, @program } ... 0
}
say fractran(<17/91 78/85 19/51 23/38 29/33 77/29 95/23 77/19 1/17 11/13 13/11
        15/14 15/2 55/1>)[^100];

```

Output:

```
(2 15 825 725 1925 2275 425 390 330 290 770 910 170 156 132 116 308 364 68 4 30 225 12375 10875 28875 25375 67375 79625 14875 13650 2550 2340 1980 1740 4620 4060 10780 12740 2380 2184 408 152 92 380 230 950 575 2375 9625 11375 2125 1950 1650 1450 3850 4550 850 780 660 580 1540 1820 340 312 264 232 616 728 136 8 60 450 3375 185625 163125 433125 380625 1010625 888125 2358125 2786875 520625 477750 89250 81900 15300 14040 11880 10440 27720 24360 64680 56840 150920 178360 33320 30576 5712 2128 1288)
```

**Extra credit:**
We can weed out all the powers of two into another infinite constant list based on the first list. In this case the sequence is limited only by our patience, and a ^C from the terminal. The .msb method finds the most significant bit of an integer, which conveniently is the base-2 log of the power-of-two in question.

```
sub fractran(@program) {
    2, { first Int, map (* * $_).narrow, @program } ... 0
}
for fractran <17/91 78/85 19/51 23/38 29/33 77/29 95/23 77/19 1/17 11/13 13/11
        15/14 15/2 55/1> {
        say $++, "\t", .msb, "\t", $_ if 1 +< .msb == $_;
}

```

Output:

```
0       1       2
1	2	4
2	3	8
3	5	32
4	7	128
5	11	2048
6	13	8192
7	17	131072
8	19	524288
9	23	8388608
^C
```


[User]
Write a program to convert dates between the Gregorian calendar and the French Republican calendar.

The year 1 of the Republican calendar began on 22 September 1792. There were twelve months (Vendémiaire, Brumaire, Frimaire, Nivôse, Pluviôse, Ventôse, Germinal, Floréal, Prairial, Messidor, Thermidor, and Fructidor) of 30 days each, followed by five intercalary days or *Sansculottides* (*Fête de la vertu* / Virtue Day, *Fête du génie* / Talent Day, *Fête du travail* / Labour Day, *Fête de l'opinion* / Opinion Day, and *Fête des récompenses* / Honours Day). In leap years (the years 3, 7, and 11) a sixth *Sansculottide* was added: *Fête de la Révolution* / Revolution Day.

As a minimum, your program should give correct results for dates in the range from 1 Vendémiaire 1 = 22 September 1792 to 10 Nivôse 14 = 31 December 1805 (the last day when the Republican calendar was officially in use). If you choose to accept later dates, be aware that there are several different methods (described on the Wikipedia page) about how to determine leap years after the year 14. You should indicate which method you are using. (Because of these different methods, correct programs may sometimes give different results for dates after 1805.)

Test your program by converting the following dates both from Gregorian to Republican and from Republican to Gregorian:

• 1 Vendémiaire 1 = 22 September 1792

• 1 Prairial 3 = 20 May 1795

• 27 Messidor 7 = 15 July 1799 *(Rosetta Stone discovered)*

• Fête de la Révolution 11 = 23 September 1803

• 10 Nivôse 14 = 31 December 1805

[Assistant]
(formerly Perl 6)

```
use v6;
constant @month_names = <
    Vendémiaire Brumaire Frimaire  Nivôse   Pluviôse  Ventôse
    Germinal    Floréal  Prairial  Messidor Thermidor Fructidor
>;
constant @intercalary =
    'Fête de la vertu',  'Fête du génie',        'Fête du travail',
    "Fête de l'opinion", 'Fête des récompenses', 'Fête de la Révolution',
;
constant %month_nums  = %( @month_names Z=> 1..12 );
constant %i_cal_nums  = %( @intercalary Z=> 1.. 6 );
constant $i_cal_month = 13;
constant $epoch       = Date.new: '1792-09-22';

sub is_republican_leap_year ( Int:D $year --> Bool ) {
    my $y := $year + 1;
    return ?( $y %% 4 and ($y !%% 100 or $y %% 400) );
}

sub Republican_to_Gregorian ( Str:D $rep_date --> Date ) {
    grammar Republican_date_text {
        token day   { \d+ }
        token year  { \d+ }
        token ic    { @intercalary }
        token month { @month_names }
        rule TOP    { ^ [ <ic> | <day> <month> ] <year> $ }
    }

    Republican_date_text.parse($rep_date)
        orelse die "Republican date not recognized: '$rep_date'";

    my $day1   := $/<ic>    ?? %i_cal_nums{~$/<ic>}    !! +$/<day>;
    my $month1 := $/<month> ?? %month_nums{~$/<month>} !! $i_cal_month;

    my @ymd0 := ($/<year>, $month1, $day1) »-» 1;
    my $days_since_epoch := [+] @ymd0 Z* (365, 30, 1);

    my $leap_days := +grep &is_republican_leap_year, 1 ..^ $/<year>;
    return $epoch + $days_since_epoch + $leap_days;
}

sub Gregorian_to_Republican ( Date:D $greg_date --> Str ) {
    my $days_since_epoch := $greg_date - $epoch;
    die if $days_since_epoch < 0;

    my ( $year, $days ) = 1, $days_since_epoch;
    loop {
        my $year_length = 365 + (1 if $year.&is_republican_leap_year);
        last if $days < $year_length;
        $days -= $year_length;
        $year += 1;
    }

    my ( $day0, $month0 ) = $days.polymod( 30 );
    my ( $day1, $month1 ) = ($day0, $month0) X+ 1;

    return $month1 == $i_cal_month
        ??       "@intercalary[$day0  ] $year"
        !! "$day1 @month_names[$month0] $year";
}

my @test_data =
    ( '1792-09-22', '1 Vendémiaire 1' ),
    ( '1795-05-20', '1 Prairial 3' ),
    ( '1799-07-15', '27 Messidor 7' ),
    ( '1803-09-23', 'Fête de la Révolution 11' ),
    ( '1805-12-31', '10 Nivôse 14' ),

    ( '1871-03-18', '27 Ventôse 79' ),
    ( '1944-08-25', '7 Fructidor 152' ),
    ( '2016-09-19', 'Fête du travail 224' ),

    ( '1871-05-06', '16 Floréal 79'  ), # Paris Commune begins
    ( '1871-05-23', '3 Prairial 79'  ), # Paris Commune ends
    ( '1799-11-09', '18 Brumaire 8'  ), # Revolution ends by Napoléon coup
    ( '1804-12-02', '11 Frimaire 13' ), # Republic   ends by Napoléon coronation
    ( '1794-10-30', '9 Brumaire 3'   ), # École Normale Supérieure established
    ( '1794-07-27', '9 Thermidor 2'  ), # Robespierre falls
    ( '1799-05-27', '8 Prairial 7'   ), # Fromental Halévy born

    ( '1792-09-22', '1 Vendémiaire 1'   ),
    ( '1793-09-22', '1 Vendémiaire 2'   ),
    ( '1794-09-22', '1 Vendémiaire 3'   ),
    ( '1795-09-23', '1 Vendémiaire 4'   ),
    ( '1796-09-22', '1 Vendémiaire 5'   ),
    ( '1797-09-22', '1 Vendémiaire 6'   ),
    ( '1798-09-22', '1 Vendémiaire 7'   ),
    ( '1799-09-23', '1 Vendémiaire 8'   ),
    ( '1800-09-23', '1 Vendémiaire 9'   ),
    ( '1801-09-23', '1 Vendémiaire 10'  ),
    ( '1802-09-23', '1 Vendémiaire 11'  ),
    ( '1803-09-24', '1 Vendémiaire 12'  ),
    ( '1804-09-23', '1 Vendémiaire 13'  ),
    ( '1805-09-23', '1 Vendémiaire 14'  ),
    ( '1806-09-23', '1 Vendémiaire 15'  ),
    ( '1807-09-24', '1 Vendémiaire 16'  ),
    ( '1808-09-23', '1 Vendémiaire 17'  ),
    ( '1809-09-23', '1 Vendémiaire 18'  ),
    ( '1810-09-23', '1 Vendémiaire 19'  ),
    ( '1811-09-24', '1 Vendémiaire 20'  ),
    ( '2015-09-23', '1 Vendémiaire 224' ),
    ( '2016-09-22', '1 Vendémiaire 225' ),
    ( '2017-09-22', '1 Vendémiaire 226' ),
;

for @test_data -> ( $g_text, $r ) {
    my $g = Date.new: $g_text;

    die if Republican_to_Gregorian($r) != $g
        or Gregorian_to_Republican($g) ne $r;

    die if Gregorian_to_Republican(Republican_to_Gregorian($r)) ne $r
        or Republican_to_Gregorian(Gregorian_to_Republican($g)) != $g;
}
say 'All tests successful.';

```

Output:

```
All tests successful.
```


[User]
Task

Find and display here on this page the Frobenius numbers that are    <    10,000.

The series is defined by:

```
     FrobeniusNumber(n)  =  prime(n) * prime(n+1)   -   prime(n)   -   prime(n+1)

```

where:

:   :   :   :   prime(1)   =   2
            :   prime(2)   =   3
            :   prime(3)   =   5
            :   prime(4)   =   7

                :   •
                :   •
                :   •

[Assistant]
```
say "{+$_} matching numbers\n{.batch(10)».fmt('%4d').join: "\n"}\n"
    given (^1000).grep( *.is-prime ).rotor(2 => -1)
    .map( { (.[0] * .[1] - .[0] - .[1]) } ).grep(* < 10000);

```

Output:

```
25 matching numbers
   1    7   23   59  119  191  287  395  615  839
1079 1439 1679 1931 2391 3015 3479 3959 4619 5039
5615 6395 7215 8447 9599
```


[User]
Task

Connect to a server, change directory, list its contents and download a file as binary using the FTP protocol. Use passive mode if available.

[Assistant]
(formerly Perl 6)

**Works with**: rakudo version 2018.04

```
use Net::FTP;

my $host = 'speedtest.tele2.net';
my $user = 'anonymous';
my $password = '';

my $ftp = Net::FTP.new( host => $host, :passive );

$ftp.login( user => $user, pass => $password );

$ftp.cwd( 'upload' );

$ftp.cwd( '/' );

say $_<name> for $ftp.ls;

$ftp.get( '1KB.zip', :binary );

```

Output:

```
1000GB.zip
100GB.zip
100KB.zip
100MB.zip
10GB.zip
10MB.zip
1GB.zip
1KB.zip
1MB.zip
200MB.zip
20MB.zip
2MB.zip
3MB.zip
500MB.zip
50MB.zip
512KB.zip
5MB.zip
upload
```


[User]
Task

Create a function, compose,   whose two arguments   *f*   and   *g*,   are both functions with one argument.

The result of compose is to be a function of one argument, (lets call the argument   *x*),   which works like applying function    *f*    to the result of applying function    *g*    to    *x*.

Example

```
 compose(f, g) (x) = f(g(x))

```

Reference: Function composition

Hint: In some languages, implementing compose correctly requires creating a closure.

[Assistant]
(formerly Perl 6)

**Works with**: rakudo version 2018.03

The function composition operator is ∘, U+2218 RING OPERATOR (with a "Texas" version o for the Unicode challenged). Here we compose a routine, an operator, and a lambda:

```
sub triple($n) { 3 * $n }
my &f = &triple ∘ &prefix:<-> ∘ { $^n + 2 };
say &f(5); # prints "-21".
```


[User]
A function is a body of code that returns a value.

The value returned may depend on arguments provided to the function.

Task

Write a definition of a function called "multiply" that takes two arguments and returns their product.

(Argument types should be chosen so as not to distract from showing how functions are created and values returned).

Related task

* Function prototype

[Assistant]
(formerly Perl 6)
Without a signature:

```
sub multiply { return @_[0] * @_[1]; }
```

The return is optional on the final statement, since the last expression would return its value anyway. The final semicolon in a block is also optional.
(Beware that a subroutine without an explicit signature, like this one, magically becomes variadic (rather than nullary) only if `@_` or `%_` appear in the body.) In fact, we can define the variadic version explicitly, which still works for two arguments:

```
sub multiply { [*] @_ }
```

With formal parameters and a return type:

```
sub multiply (Rat $a, Rat $b --> Rat) { $a * $b }
```

Same thing:

```
my Rat sub multiply (Rat $a, Rat $b) { $a * $b }
```

It is possible to define a function in "lambda" notation and then bind that into a scope, in which case it works like any function:

```
my &multiply := -> $a, $b { $a * $b };
```

Another way to write a lambda is with internal placeholder parameters:

```
my &multiply := { $^a * $^b };
```

(And, in fact, our original @\_ above is just a variadic self-declaring placeholder argument. And the famous Perl "topic", $\_, is just a self-declared parameter to a unary block.)

You may also curry both built-in and user-defined operators by supplying a \* (known as "whatever") in place of the argument that is *not* to be curried:

```
my &multiply := * * *;
```

This is not terribly readable in this case due to the visual confusion between the whatever star and the multiplication operator, but Perl knows when it's expecting terms instead of infixes, so only the middle star is multiplication.
It tends to work out much better with other operators. In particular, you may
curry a cascade of methods with only the original invocant missing:

```
@list.grep( *.substr(0,1).lc.match(/<[0..9 a..f]>/) )
```

This is equivalent to:

```
@list.grep( -> $obj { $obj.substr(0,1).lc.match(/<[0..9 a..f]>/) } )
```


[User]
Display - for a program or runtime environment (whatever suits the style of your language) - the top ten most frequently occurring functions (or also identifiers or tokens, if preferred).

This is a static analysis: The question is not how often each function is
actually executed at runtime, but how often it is used by the programmer.

Besides its practical usefulness, the intent of this task is to show how to do self-inspection within the language.

[Assistant]
(formerly Perl 6)
Here we just examine the ast of the Raku compiler (which is written in Raku) to look for function calls.

```
my $text = qqx[raku --target=ast @*ARGS[]];
my %fun;
for $text.lines {
    %fun{$0}++ if / '(call &' (.*?) ')' /
}

for %fun.invert.sort.reverse[^10] { .value.say }

```

Output:

Here we run it on the strand sort RC entry. Note how Raku considers various operators to really be function calls underneath.

```
$ ./morefun strand
pop
postcircumfix:<[ ]>
unshift
succeed
splice
prefix:<->
push
infix:<,>
infix:<..>
infix:<->
```


[User]
Some languages provide the facility to declare functions and subroutines through the use of function prototyping.

Task

Demonstrate the methods available for declaring prototypes within the language. The provided solutions should include:

* An explanation of any placement restrictions for prototype declarations
* A prototype declaration for a function that does not require arguments
* A prototype declaration for a function that requires two arguments
* A prototype declaration for a function that utilizes varargs
* A prototype declaration for a function that utilizes optional arguments
* A prototype declaration for a function that utilizes named parameters
* Example of prototype declarations for subroutines or procedures (if these differ from functions)
* An explanation and example of any special forms of prototyping not covered by the above

Languages that do not provide function prototyping facilities should be omitted from this task.

[Assistant]
(formerly Perl 6)
There is no restriction on placement of prototype declarations. (Actually, we call them "stub declarations".) In fact, stub declarations are rarely needed in Raku because post-declaration of functions is allowed, and normal function declarations do not bend the syntax the way they sometimes do in Perl 5.

Note that the ... in all of these stub bodies is literally part of the declaration syntax.

A prototype declaration for a function that does not require arguments (and returns an Int):

```
sub foo ( --> Int) {...}

```

A prototype declaration for a function that requires two arguments.
Note that we can omit the variable name and just use the sigil in the stub, since we don't need to reference the argument until the actual definition of the routine. Also, unlike in Perl 5, a sigil like @ defaults to binding a single positional argument.

```
sub foo (@, $ --> Int) {...}

```

A prototype declaration for a function that utilizes varargs after one required argument.
Note the "slurpy" star turns the @ sigil into a parameter that accepts all the rest of the positional arguments.

```
sub foo ($, *@ --> Int) {...}

```

A prototype declaration for a function that utilizes optional arguments after one required argument. Optionality is conferred by either a question mark or a default:

```
sub foo ($, $?, $ = 42 --> Int) {...}

```

A prototype declaration for a function that utilizes named parameters:

```
sub foo ($, :$faster, :$cheaper --> Int) {...}

```

Example of prototype declarations for subroutines or procedures, which in Raku is done simply by noting that nothing is returned:

```
sub foo ($, $ --> Nil) {...}

```

A routine may also slurp up all the named arguments that were not bound earlier in the signature:

```
sub foo ($, :$option, *% --> Int) {...}

```

A routine may make a named parameter mandatory using exclamation mark. (This is more useful in multi subs than in stubs though.)

```
sub foo ($, :$option! --> Int) {...}

```

A routine may unpack an Array automaticly. Here the first element is stored in a scalar and the rest in an Array. Other buildin types can be unpacked as well.

```
sub foo ([$, @]) {...}

```

A routine may ask for a closure parameter to implement higher order functions. Typed or untyped signatures can be supplied.

```
sub foo (@, &:(Str --> Int)) {...}

```


[User]
Functional coverage is a measure of how much a particular function of a system
has been verified as correct. It is used heavily in tracking the completeness
of the verification of complex System on Chip (SoC) integrated circuits, where
it can also be used to track how well the functional *requirements* of the
system have been verified.

This task uses a sub-set of the calculations sometimes used in tracking
functional coverage but uses a more familiar(?) scenario.

Task Description

The head of the clean-up crews for "The Men in a very dark shade of grey when
viewed at night" has been tasked with managing the cleansing of two properties
after an incident involving aliens.

She arranges the task hierarchically with a manager for the crews working on
each house who return with a breakdown of how they will report on progress in
each house.

The overall hierarchy of (sub)tasks is as follows,

```
cleaning
    house1
        bedrooms
        bathrooms
            bathroom1
            bathroom2
            outside lavatory
        attic
        kitchen
        living rooms
            lounge
            dining room
            conservatory
            playroom
        basement
        garage
        garden
    house2
        upstairs
            bedrooms
                suite 1
                suite 2
                bedroom 3
                bedroom 4
            bathroom
            toilet
            attics
        groundfloor
            kitchen
            living rooms
                lounge
                dining room
                conservatory
                playroom
            wet room & toilet
            garage
            garden
            hot tub suite
        basement
            cellars
            wine cellar
            cinema
```

The head of cleanup knows that her managers will report fractional completion of leaf tasks (tasks with no child tasks of their own), and she knows that she will want to modify the weight of values of completion as she sees fit.

Some time into the cleaning, and some coverage reports have come in and she thinks see needs to weight the big house2 60-40 with respect to coverage from house1 She prefers a tabular view of her data where missing weights are assumed to be 1.0 and missing coverage 0.0.

```
NAME_HIERARCHY                  |WEIGHT  |COVERAGE  |
cleaning                        |        |          |
    house1                      |40      |          |
        bedrooms                |        |0.25      |
        bathrooms               |        |          |
            bathroom1           |        |0.5       |
            bathroom2           |        |          |
            outside_lavatory    |        |1         |
        attic                   |        |0.75      |
        kitchen                 |        |0.1       |
        living_rooms            |        |          |
            lounge              |        |          |
            dining_room         |        |          |
            conservatory        |        |          |
            playroom            |        |1         |
        basement                |        |          |
        garage                  |        |          |
        garden                  |        |0.8       |
    house2                      |60      |          |
        upstairs                |        |          |
            bedrooms            |        |          |
                suite_1         |        |          |
                suite_2         |        |          |
                bedroom_3       |        |          |
                bedroom_4       |        |          |
            bathroom            |        |          |
            toilet              |        |          |
            attics              |        |0.6       |
        groundfloor             |        |          |
            kitchen             |        |          |
            living_rooms        |        |          |
                lounge          |        |          |
                dining_room     |        |          |
                conservatory    |        |          |
                playroom        |        |          |
            wet_room_&_toilet   |        |          |
            garage              |        |          |
            garden              |        |0.9       |
            hot_tub_suite       |        |1         |
        basement                |        |          |
            cellars             |        |1         |
            wine_cellar         |        |1         |
            cinema              |        |0.75      |
```

Calculation

The coverage of a node in the tree is calculated as the weighted average of the coverage of its children evaluated bottom-upwards in the tree.

**The task is to** calculate the overall coverage of the cleaning task and display the coverage at all levels of the hierarchy on this page, in a manner that visually shows the hierarchy, weights and coverage of all nodes.

Extra Credit

After calculating the coverage for all nodes, one can also calculate the additional/delta top level coverage that would occur if any (sub)task were to be fully covered from its current fractional coverage. This is done by multiplying the extra coverage that could be gained

1
−
c
o
v
e
r
a
g
e
{\displaystyle {\displaystyle 1-coverage}}
 for any node, by the product of the `powers` of its parent nodes from the top down to the node.
The power of a direct child of any parent is given by the power of the parent multiplied by the weight of the child divided by the sum of the weights of all the direct children.

The pseudo code would be:

```
   method delta_calculation(this, power):
       sum_of_weights = sum(node.weight for node in children)
       this.delta  = (1 - this.coverage) * power
       for node in self.children:
           node.delta_calculation(power * node.weight / sum_of_weights)
       return this.delta

```

Followed by a call to:

```
   top.delta_calculation(power=1)

```

**Note:** to aid in getting the data into your program you might want to use an alternative, more functional description of the starting data given on the discussion page.

[Assistant]
(formerly Perl 6)

**Translation of**: Perl

```
sub walktree ($data) {
    my (@parts, $cnt);

    while ($data ~~ m:nth(++$cnt)/$<head>=[(\s*)    \N+\n  ]      # split off one level as 'head' (or terminal 'leaf')
                                  $<body>=[[$0  \s+ \N+\n]*]/ ) { # next sub-level is 'body' (defined by extra depth of indentation)

        my ($head, $body) = ($<head>, $<body>);
        $head ~~ /'|' $<weight>=[\S*] \s* '|' $<coverage>=[\S*]/; # save values of weight and coverage (if any) for later

        my ($w, $wsum) = (0, 0);
        $head ~= .[0],
        $w    += .[1],
        $wsum += .[1] * .[2]
            for walktree $body;

        my $weight   = (~$<weight>   or 1).fmt('%-8s');
        my $coverage = $w == 0
                    ?? (~$<coverage> or 0).fmt('%-10s')
                    !! ($wsum/$w)         .fmt('%-10.2g');
        @parts.push: [$head.subst(/'|' \N+/, "|$weight|$coverage|"), $weight, $coverage ];
    }
    return @parts;
}

(say .[0] for walktree $_) given

    q:to/END/
    NAME_HIERARCHY                  |WEIGHT  |COVERAGE  |
    cleaning                        |        |          |
        house1                      |40      |          |
            bedrooms                |        |0.25      |
            bathrooms               |        |          |
                bathroom1           |        |0.5       |
                bathroom2           |        |          |
                outside_lavatory    |        |1         |
            attic                   |        |0.75      |
            kitchen                 |        |0.1       |
            living_rooms            |        |          |
                lounge              |        |          |
                dining_room         |        |          |
                conservatory        |        |          |
                playroom            |        |1         |
            basement                |        |          |
            garage                  |        |          |
            garden                  |        |0.8       |
        house2                      |60      |          |
            upstairs                |        |          |
                bedrooms            |        |          |
                    suite_1         |        |          |
                    suite_2         |        |          |
                    bedroom_3       |        |          |
                    bedroom_4       |        |          |
                bathroom            |        |          |
                toilet              |        |          |
                attics              |        |0.6       |
            groundfloor             |        |          |
                kitchen             |        |          |
                living_rooms        |        |          |
                    lounge          |        |          |
                    dining_room     |        |          |
                    conservatory    |        |          |
                    playroom        |        |          |
                wet_room_&_toilet   |        |          |
                garage              |        |          |
                garden              |        |0.9       |
                hot_tub_suite       |        |1         |
            basement                |        |          |
                cellars             |        |1         |
                wine_cellar         |        |1         |
                cinema              |        |0.75      |
    END

```

Output:

```
NAME_HIERARCHY                  |WEIGHT  |COVERAGE  |

cleaning                        |1       |0.41      |
    house1                      |40      |0.33      |
        bedrooms                |1       |0.25      |
        bathrooms               |1       |0.5       |
            bathroom1           |1       |0.5       |
            bathroom2           |1       |0         |
            outside_lavatory    |1       |1         |
        attic                   |1       |0.75      |
        kitchen                 |1       |0.1       |
        living_rooms            |1       |0.25      |
            lounge              |1       |0         |
            dining_room         |1       |0         |
            conservatory        |1       |0         |
            playroom            |1       |1         |
        basement                |1       |0         |
        garage                  |1       |0         |
        garden                  |1       |0.8       |
    house2                      |60      |0.46      |
        upstairs                |1       |0.15      |
            bedrooms            |1       |0         |
                suite_1         |1       |0         |
                suite_2         |1       |0         |
                bedroom_3       |1       |0         |
                bedroom_4       |1       |0         |
            bathroom            |1       |0         |
            toilet              |1       |0         |
            attics              |1       |0.6       |
        groundfloor             |1       |0.32      |
            kitchen             |1       |0         |
            living_rooms        |1       |0         |
                lounge          |1       |0         |
                dining_room     |1       |0         |
                conservatory    |1       |0         |
                playroom        |1       |0         |
            wet_room_&_toilet   |1       |0         |
            garage              |1       |0         |
            garden              |1       |0.9       |
            hot_tub_suite       |1       |1         |
        basement                |1       |0.92      |
            cellars             |1       |1         |
            wine_cellar         |1       |1         |
            cinema              |1       |0.75      |
```


[User]
Definitions

The   **fusc**   integer sequence is defined as:

:   :   * fusc(0) = 0
        * fusc(1) = 1
        * for **n**>1,   the   **n**th   term is defined as:

        :   :   * if   **n**   is even;     fusc(n) = fusc(n/2)
                * if   **n**   is   odd;     fusc(n) = fusc((n-1)/2)   +   fusc((n+1)/2)

Note that MathWorld's definition starts with unity, not zero.   This task will be using the OEIS' version   (above).

An observation
:   :   :   :   :   * fusc(A) = fusc(B)

where   **A**   is some non-negative integer expressed in binary,   and
where   **B**   is the binary value of   **A**   reversed.

Fusc numbers are also known as:

:   :   * fusc function   (named by Dijkstra, 1982)
        * Stern's Diatomic series   (although it starts with unity, not zero)
        * Stern-Brocot sequence   (although it starts with unity, not zero)

Task
:   :   * show the first   **61**   fusc numbers (starting at zero) in a horizontal format.
        * show the fusc number (and its index) whose length is greater than any previous fusc number length.

        :   :   * (the length is the number of decimal digits when the fusc number is expressed in base ten.)

        * show all numbers with commas   (if appropriate).
        * show all output here.

Related task
:   * Stern-Brocot sequence
    * Calkin-Wilf sequence.

Also see
:   :   * the MathWorld entry:   Stern's Diatomic Series.
        * the OEIS entry:   A2487.

[Assistant]
(formerly Perl 6)

### Recurrence

```
my @Fusc = 0, 1, 1, { |(@Fusc[$_ - 1] + @Fusc[$_], @Fusc[$_]) given ++$+1 } ... *;

sub comma { $^i.flip.comb(3).join(',').flip }

put "First 61 terms of the Fusc sequence:\n{@Fusc[^61]}" ~
    "\n\nIndex and value for first term longer than any previous:";

for flat 'Index', 'Value', 0, 0, (1..4).map({
    my $l = 10**$_;
    @Fusc.first(* > $l, :kv).map: &comma
  }) -> $i, $v {
      printf "%15s : %s\n", $i, $v
}

```

Output:

```
First 61 terms of the Fusc sequence:
0 1 1 2 1 3 2 3 1 4 3 5 2 5 3 4 1 5 4 7 3 8 5 7 2 7 5 8 3 7 4 5 1 6 5 9 4 11 7 10 3 11 8 13 5 12 7 9 2 9 7 12 5 13 8 11 3 10 7 11 4

Index and value for first term longer than any previous:
          Index : Value
              0 : 0
             37 : 11
          1,173 : 108
         35,499 : 1,076
        699,051 : 10,946

```

### Recursive

Alternative version using Raku's multiple-dispatch feature. This version is significantly slower than the one above, but it's definitely prettier.

```
multi fusc( 0 ) { 0 }
multi fusc( 1 ) { 1 }
multi fusc( $n where $n %% 2 ) { fusc $n div 2 }
multi fusc( $n ) { [+] map *.&fusc, ( $n - 1 ) div 2, ( $n + 1 ) div 2 }
put map *.&fusc, 0..60;

```

Output:

```
0 1 1 2 1 3 2 3 1 4 3 5 2 5 3 4 1 5 4 7 3 8 5 7 2 7 5 8 3 7 4 5 1 6 5 9 4 11 7 10 3 11 8 13 5 12 7 9 2 9 7 12 5 13 8 11 3 10 7 11 4
```


[User]
Problem Statement

Gabow's algorithm is an algorithm used to find strongly connected components (SCCs) in a digraph.

Given a directed graph (digraph) with *V* vertices and *E* edges, where vertices are represented as integers from 0 to *V-1* and edges are directed from one vertex to another, design an algorithm to identify all **strongly connected components (SCCs)**. A strongly connected component is a maximal subset of vertices in the digraph such that for every pair of vertices *v* and *w* in the subset, there exists a directed path from *v* to *w* and from *w* to *v*. The algorithm should:

1. Compute the number of SCCs in the digraph.
2. Assign each vertex to its corresponding SCC.
3. Provide a way to query whether two vertices belong to the same SCC.
4. Return the component identifier for any given vertex.

Input

* A directed graph *G* represented as an adjacency list, where:
  + *V* is the number of vertices (non-negative integer).
  + Edges are provided as pairs *(v, w)*, indicating a directed edge from vertex *v* to vertex *w*.
* The vertices are integers in the range [0, *V-1*].

Output

* The total number of strongly connected components in the digraph.
* An assignment of each vertex to a unique component identifier (an integer ≥ 0).
* A mechanism to check if two vertices *v* and *w* are strongly connected (i.e., belong to the same SCC).
* The ability to retrieve the component ID of any vertex *v*.

Constraints

* *V* ≥ 0 (the graph can be empty).
* Edges *(v, w)* must satisfy 0 ≤ *v*, *w* < *V*.
* The graph may contain cycles, self-loops, or parallel edges (though parallel edges are effectively ignored in this implementation as duplicates in adjacency lists are allowed but not explicitly handled).

Example

Consider a digraph with *V = 13* vertices and the following edges:

```
(4, 2), (2, 3), (3, 2), (6, 0), (0, 1), (2, 0), (11, 12), (12, 9), (9, 10),
(9, 11), (8, 9), (10, 12), (0, 5), (5, 4), (3, 5), (6, 4), (6, 9), (7, 6),
(7, 8), (8, 7), (5, 3), (0, 6)

```

* Compute the SCCs.
* Determine how many SCCs exist.
* List the vertices in each SCC.
* Check if specific pairs of vertices (e.g., 0 and 3, 0 and 7) are strongly connected.

[Assistant]
**Translation of**: Rust

```
# 20250415 Raku programming solution

my subset Vertex      of UInt;
my subset ComponentId of UInt;

class Digraph {
   has Int $.vertex-count is readonly;
   has Int $.edge-count is rw = 0;
   has     @.adjacency-lists;

   method new(Int $vertex-count where * >= 0) { # Constructor
      self.bless( vertex-count    => $vertex-count,
                  adjacency-lists => [ [] xx $vertex-count ] )
   }

   method add-edge(Vertex $from, Vertex $to) { # Add a directed edge
      self!validate-vertex($from);
      self!validate-vertex($to);
      @!adjacency-lists[$from].push($to);
      $!edge-count++;
   }

   method adjacency-list(Vertex $vertex) { # Get adjacency list for a vertex
      self!validate-vertex($vertex);
      @!adjacency-lists[$vertex];
   }

   method !validate-vertex(Vertex $vertex) { # Validate vertex index
      if $vertex >= $!vertex-count {
         die "Vertex $vertex is not between 0 and {$!vertex-count - 1}";
      }
   }

   method gist { # String representation
      return [~] [
         "Digraph has $!vertex-count vertices and $!edge-count edges\n",
         "Adjacency lists:\n"
      ].append( gather for ^$!vertex-count -> $vertex {
         take sprintf("%2d: ", $vertex);
         take @!adjacency-lists[$vertex].sort.Str ~ "\n"
      })
   }
}

class GabowSCC {
   has Bool   @.visited;
   has Int    @.component-ids; # Using Int with -1 as None equivalent
   has Int    @.preorders;     # Using Int with -1 as None equivalent
   has Int    $.preorder-count is rw = 0;
   has Int    $.scc-count is rw = 0;
   has Vertex @.visited-vertices-stack;
   has Vertex @.auxiliary-stack;

   method new(Digraph $digraph) { # Constructor
      my $n    = $digraph.vertex-count;
      my $self = self.bless(
         visited                => False xx $n,
         component-ids          => (-1) xx $n,
         preorders              => (-1) xx $n,
         visited-vertices-stack => [],
         auxiliary-stack        => []
      );

      for ^$n -> $vertex {
         $self!depth-first-search($digraph, $vertex) unless $self.visited[$vertex]
      }
      $self;
   }

   # Depth-first search for Gabow's algorithm
   method !depth-first-search(Digraph $digraph, Vertex $vertex) {
      @!visited[$vertex]   = True;
      @!preorders[$vertex] = $!preorder-count++;
      @!visited-vertices-stack.push($vertex);
      @!auxiliary-stack.push($vertex);

      for $digraph.adjacency-list($vertex).List -> $adjacent {
         if !@!visited[$adjacent] {
            self!depth-first-search($digraph, $adjacent)
         } else {
            if @!component-ids[$adjacent] == -1 {
               my $adjacent-preorder = @!preorders[$adjacent];
               while @!auxiliary-stack && @!preorders[@!auxiliary-stack[*-1]] > $adjacent-preorder {
                  @!auxiliary-stack.pop;
               }
            }
         }
      }

      if @!auxiliary-stack && @!auxiliary-stack[*-1] == $vertex {
         @!auxiliary-stack.pop;
         loop {
            my $scc-member = @!visited-vertices-stack.pop // die "Visited stack empty";
            @!component-ids[$scc-member] = $!scc-count;
            last if $scc-member == $vertex;
         }
         $!scc-count++;
      }
   }

   method get-component-id(Vertex $vertex) { # Get component ID for a vertex
       self!validate-vertex($vertex);
       @!component-ids[$vertex] == -1 ?? Nil !! @!component-ids[$vertex];
   }

   # Check if two vertices are strongly connected
   method is-strongly-connected(Vertex $v, Vertex $w) {
      self!validate-vertex($v);
      self!validate-vertex($w);
      @!component-ids[$v] != -1 && @!component-ids[$w] != -1 && @!component-ids[$v] == @!component-ids[$w];
   }

   method get-components() { # Get all components
      my @components = [] xx $!scc-count;
      for @!component-ids.kv -> $vertex, $id {
         if $id != -1 {
            $id < $!scc-count
               ?? @components[$id].push($vertex)
               !! note "Warning: Vertex $vertex has invalid SCC ID $id"
         }
      }
      @components.map: *.sort
   }

   method !validate-vertex(Vertex $vertex) { # Validate vertex index
      given my $n = @!visited.elems {
         die "Vertex $vertex is not between 0 and {$n - 1}" if $vertex >= $n
      }
   }
}

my @edges = [ <4 2>, <2 3>, <3 2>, <6 0>, <0 1>, <2 0>, <11 12>, <12 9>,
              <9 10>, <9 11>, <8 9>, <10 12>, <0 5>, <5 4>, <3 5>, <6 4>,
              <6 9>, <7 6>, <7 8>, <8 7>, <5 3>, <0 6>
            ].map: { ( from => .[0], to => .[1] ).Hash };
my $vertex-count = 13;
my $digraph = Digraph.new($vertex-count);

for @edges -> $edge { $digraph.add-edge($edge<from>, $edge<to>) }

print "Constructed digraph:" ~ $digraph.gist;

my $gabow-scc = GabowSCC.new($digraph);
say "It has $gabow-scc.scc-count() strongly connected components.";

my @components = $gabow-scc.get-components();
say "\nComponents:";
for @components.kv -> $i, @component {
   say "Component $i: " ~ @component.Str if @component.Bool;
}

say "\nExample connectivity checks:";
for ( <0 3>, <0 7>, <9 12> ) -> ($i,$j) {
   say "Vertices $i and $j strongly connected? {$gabow-scc.is-strongly-connected($i, $j)}"
}

say "Component ID of vertex 5: {$gabow-scc.get-component-id(5) // 'None'}";
say "Component ID of vertex 8: {$gabow-scc.get-component-id(8) // 'None'}";

(my $id = $gabow-scc.get-component-id(5)).defined
   ?? say "Component ID of vertex 5 (explicit handling): $id"
   !! say "Vertex 5 has no assigned component ID.";

```

You may Attempt This Online!


[User]
Example of a Galton Box at the end of animation.

A   **Galton device**   Sir Francis Galton's device   is also known as a   **bean machine**,   a   **Galton Board**,   or a   **quincunx**.

Description of operation

In a Galton box, there are a set of pins arranged in a triangular pattern.   A number of balls are dropped so that they fall in line with the top pin, deflecting to the left or the right of the pin.   The ball continues to fall to the left or right of lower pins before arriving at one of the collection points between and to the sides of the bottom row of pins.

Eventually the balls are collected into bins at the bottom   (as shown in the image),   the ball column heights in the bins approximate a   bell curve.   Overlaying   Pascal's triangle   onto the pins shows the number of different paths that can be taken to get to each bin.

Task

Generate an animated simulation of a Galton device.

Task requirements
:   :   * The box should have at least 5 pins on the bottom row.
        * A solution can use graphics or ASCII animation.
        * Provide a sample of the output/display such as a screenshot.
        * There can be one or more balls in flight at the same time.
        * If multiple balls are in flight, ensure they don't interfere with each other.
        * A solution should allow users to specify the number of balls, or it should run until full or a preset limit.
        * Optionally,   display the number of balls.

[Assistant]
(formerly Perl 6)

UPPER HALF BLOCK and LOWER HALF BLOCK alternate to give a somewhat smooth animation.

**Works with**: rakudo version 2015-09-12

```
my $row-count = 6;

constant $peg = "*";
constant @coin-icons = "\c[UPPER HALF BLOCK]", "\c[LOWER HALF BLOCK]";

sub display-board(@positions, @stats is copy, $halfstep) {
    my $coin = @coin-icons[$halfstep.Int];

    state @board-tmpl = {
        # precompute a board
        my @tmpl;
        sub out(*@stuff) {
            @tmpl.push: $[@stuff.join>>.ords.flat];
        }
        # three lines of space above
        for 1..3 {
            out "  ", " " x (2 * $row-count);
        }
        # $row-count lines of pegs
        for flat ($row-count...1) Z (1...$row-count) -> $spaces, $pegs {
            out "  ", " " x $spaces, ($peg xx $pegs).join(" "), " " x $spaces;
        }
        # four lines of space below
        for 1..4 {
            out "  ", " " x (2 * $row-count);
        }
        @tmpl
    }();

    my $midpos = $row-count + 2;

    my @output;
    {
        # collect all the output and output it all at once at the end
        sub say(Str $foo) {
            @output.push: $foo, "\n";
        }
        sub print(Str $foo) {
            @output.push: $foo;
        }

        # make some space above the picture
        say "" for ^10;

        my @output-lines = map { [ @$_ ] }, @board-tmpl;
        # place the coins
        for @positions.kv -> $line, $pos {
            next unless $pos.defined;
            @output-lines[$line][$pos + $midpos] = $coin.ord;
        }
        # output the board with its coins
        for @output-lines -> @line {
            say @line.chrs;
        }

        # show the statistics
        my $padding = 0;
        while any(@stats) > 0 {
            $padding++;
            print "  ";
            @stats = do for @stats -> $stat {
                given $stat {
                    when 1 {
                        print "\c[UPPER HALF BLOCK]";
                        $stat - 1;
                    }
                    when * <= 0 {
                        print " ";
                        0
                    }
                    default {
                        print "\c[FULL BLOCK]";
                        $stat - 2;
                    }
                }
            }
            say "";
        }
        say "" for $padding...^10;
    }
    say @output.join("");
}

sub simulate($coins is copy) {
    my $alive = True;

    sub hits-peg($x, $y) {
        if 3 <= $y < 3 + $row-count and -($y - 2) <= $x <= $y - 2 {
            return not ($x - $y) %% 2;
        }
        return False;
    }

    my @coins = Int xx (3 + $row-count + 4);
    my @stats = 0 xx ($row-count * 2);
    # this line will dispense coins until turned off.
    @coins[0] = 0;
    while $alive {
        $alive = False;
        # if a coin falls through the bottom, count it
        given @coins[*-1] {
            when *.defined {
                @stats[$_ + $row-count]++;
            }
        }

        # move every coin down one row
        for ( 3 + $row-count + 3 )...1 -> $line {
            my $coinpos = @coins[$line - 1];

            @coins[$line] = do if not $coinpos.defined {
                Nil
            } elsif hits-peg($coinpos, $line) {
                # when a coin from above hits a peg, it will bounce to either side.
                $alive = True;
                ($coinpos - 1, $coinpos + 1).pick;
            } else {
                # if there was a coin above, it will fall to this position.
                $alive = True;
                $coinpos;
            }
        }
        # let the coin dispenser blink and turn it off if we run out of coins
        if @coins[0].defined {
            @coins[0] = Nil
        } elsif --$coins > 0 {
            @coins[0] = 0
        }

        # smooth out the two halfsteps of the animation
        my $start-time;
        ENTER { $start-time = now }
        my $wait-time = now - $start-time;

        sleep 0.1 - $wait-time if $wait-time < 0.1;
        for @coin-icons.keys {
            sleep $wait-time max 0.1;
            display-board(@coins, @stats, $_);
        }
    }
}

sub MAIN($coins = 20, $peg-lines = 6) {
    $row-count = $peg-lines;
    simulate($coins);
}

```


[User]
Task

Implement one algorithm (or more) to compute the Gamma (

Γ
{\displaystyle {\displaystyle \Gamma }}
) function (in the real field only).

If your language has the function as built-in or you know a library which has it, compare your implementation's results with the results of the built-in/library function.

The Gamma function can be defined as:

:   :   :   :   :   :   Γ
                        (
                        x
                        )
                        =

                        ∫

                        0

                        ∞

                        t

                        x
                        −
                        1

                        e

                        −
                        t
                        d
                        t
                        {\displaystyle {\displaystyle \Gamma (x)=\displaystyle \int \_{0}^{\infty }t^{x-1}e^{-t}dt}}

This suggests a straightforward (but inefficient) way of computing the

Γ
{\displaystyle {\displaystyle \Gamma }}
 through numerical integration.

Better suggested methods:

* Lanczos approximation
* Stirling's approximation

[Assistant]
(formerly Perl 6)

```
sub Γ(\z) {
    constant g = 9;
    z < .5 ?? pi/ sin(pi * z) / Γ(1 - z) !!
    sqrt(2*pi) *
    (z + g - 1/2)**(z - 1/2) *
    exp(-(z + g - 1/2)) *
    [+] <
        1.000000000000000174663
     5716.400188274341379136
   -14815.30426768413909044
    14291.49277657478554025
    -6348.160217641458813289
     1301.608286058321874105
     -108.1767053514369634679
        2.605696505611755827729
       -0.7423452510201416151527e-2
        0.5384136432509564062961e-7
       -0.4023533141268236372067e-8
    > Z* 1, |map 1/(z + *), 0..*
}

say Γ($_) for 1/3, 2/3 ... 10/3;

```

Output:

```
2.67893853470775
1.3541179394264
1
0.892979511569248
0.902745292950934
1
1.190639348759
1.50457548825155
2
2.77815848043766
```


[User]
Numbers   (positive integers expressed in base ten)   that are (evenly) divisible by the number formed by the
first and last digit are known as   **gapful numbers**.

*Evenly divisible*   means divisible with   no   remainder.

All   one─   and two─digit   numbers have this property and are trivially excluded.   Only
numbers    ≥  **100**   will be considered for this Rosetta Code task.

Example

**187**   is a   **gapful**   number because it is evenly divisible by the
number   **17**   which is formed by the first and last decimal digits
of    **187**.

About   7.46%   of positive integers are   *gapful*.

Task
:   * Generate and show all sets of numbers (below) on one line (horizontally) with a title,   here on this page
    * Show the first   **30**   gapful numbers
    * Show the first   **15**   gapful numbers    ≥           **1,000,000**
    * Show the first   **10**   gapful numbers    ≥    **1,000,000,000**

Related tasks
:   * Harshad or Niven series.
    * palindromic gapful numbers.
    * largest number divisible by its digits.

Also see
:   * The OEIS entry:   A108343 gapful numbers.
    * numbersaplenty gapful numbers

[Assistant]
(formerly Perl 6)

**Works with**: Rakudo version 2019.07.1

Also test starting on a number that *doesn't* start with 1. Required to have titles, may as well make 'em noble. :-)

```
use Lingua::EN::Numbers;

for (1e2, 30, 1e6, 15, 1e9, 10, 7123, 25)».Int -> $start, $count {
    put "\nFirst $count gapful numbers starting at {comma $start}:\n" ~
    <Sir Lord Duke King>.pick ~ ": ", ~
    ($start..*).grep( { $_ %% .comb[0, *-1].join } )[^$count];
}

```

Output:

```
First 30 gapful numbers starting at 100:
Sir: 100 105 108 110 120 121 130 132 135 140 143 150 154 160 165 170 176 180 187 190 192 195 198 200 220 225 231 240 242 253

First 15 gapful numbers starting at 1,000,000:
Duke: 1000000 1000005 1000008 1000010 1000016 1000020 1000021 1000030 1000032 1000034 1000035 1000040 1000050 1000060 1000065

First 10 gapful numbers starting at 1,000,000,000:
King: 1000000000 1000000001 1000000005 1000000008 1000000010 1000000016 1000000020 1000000027 1000000030 1000000032

First 25 gapful numbers starting at 7,123:
King: 7125 7140 7171 7189 7210 7272 7275 7280 7296 7350 7373 7420 7425 7474 7488 7490 7560 7575 7630 7632 7676 7700 7725 7770 7777
```


[User]
Task

Invert matrix   **A**   using Gauss-Jordan method.

**A**   being an   **n** × **n**   matrix.

[Assistant]
(formerly Perl 6)

Uses bits and pieces from other tasks, Reduced row echelon form primarily.

```
sub gauss-jordan-invert (@m where &is-square) {
    ^@m .map: { @m[$_].append: identity(+@m)[$_] };
    @m.&rref[*]»[+@m .. *];
}

sub is-square (@m) { so @m == all @m[*] }

sub identity ($n) { [ 1, |(0 xx $n-1) ], *.rotate(-1).Array ... *.tail }

# reduced row echelon form (from 'Gauss-Jordan elimination' task)
sub rref (@m) {
    my ($lead, $rows, $cols) = 0, @m, @m[0];

    for ^$rows -> $r {
        $lead < $cols or return @m;
        my $i = $r;
        until @m[$i;$lead] {
            ++$i == $rows or next;
            $i = $r;
            ++$lead == $cols and return @m;
        }
        @m[$i, $r] = @m[$r, $i] if $r != $i;
        @m[$r] »/=» $ = @m[$r;$lead];
        for ^$rows -> $n {
            next if $n == $r;
            @m[$n] »-=» @m[$r] »×» (@m[$n;$lead] // 0);
        }
        ++$lead;
    }
    @m
}
sub rat-or-int ($num) {
    return $num unless $num ~~ Rat|FatRat;
    return $num.narrow if $num.narrow ~~ Int;
    $num.nude.join: '/';
}

sub say_it ($message, @array) {
    my $max;
    @array.map: {$max max= max $_».&rat-or-int.comb(/\S+/)».chars};
    say "\n$message";
    $_».&rat-or-int.fmt(" %{$max}s").put for @array;
}

multi to-matrix ($str) { [$str.split(';').map(*.words.Array)] }
multi to-matrix (@array) { @array }

sub hilbert-matrix ($h) {
    [ (1..$h).map( -> $n { [ ($n ..^ $n + $h).map: { (1/$_).FatRat } ] } ) ]
}

my @tests =
    '1 2 3; 4 1 6; 7 8 9',
    '2 -1 0; -1 2 -1; 0 -1 2',
    '-1 -2 3 2; -4 -1 6 2; 7 -8 9 1; 1 -2 1 3',
    '1 2 3 4; 5 6 7 8; 9 33 11 12; 13 14 15 17',
    '3 1 8 9 6; 6 2 8 10 1; 5 7 2 10 3; 3 2 7 7 9; 3 5 6 1 1',

    # Test with a Hilbert matrix
    hilbert-matrix 10;

@tests.map: {
    my @matrix = .&to-matrix;
    say_it( " {'=' x 20} Original Matrix: {'=' x 20}", @matrix );
    say_it( ' Gauss-Jordan Inverted:', my @invert = gauss-jordan-invert @matrix );
    say_it( ' Re-inverted:', gauss-jordan-invert @invert».Array );
}

```

Output:

```
 ==================== Original Matrix: ====================
 1  2  3
 4  1  6
 7  8  9

 Gauss-Jordan Inverted:
 -13/16     1/8    3/16
    1/8    -1/4     1/8
  25/48     1/8   -7/48

 Re-inverted:
 1  2  3
 4  1  6
 7  8  9

 ==================== Original Matrix: ====================
  2  -1   0
 -1   2  -1
  0  -1   2

 Gauss-Jordan Inverted:
 3/4  1/2  1/4
 1/2    1  1/2
 1/4  1/2  3/4

 Re-inverted:
  2  -1   0
 -1   2  -1
  0  -1   2

 ==================== Original Matrix: ====================
 -1  -2   3   2
 -4  -1   6   2
  7  -8   9   1
  1  -2   1   3

 Gauss-Jordan Inverted:
 -21/23   17/69  13/138   19/46
 -38/23   15/23    1/23   15/23
 -16/23   25/69  11/138    9/46
 -13/23   16/69   -2/69   13/23

 Re-inverted:
 -1  -2   3   2
 -4  -1   6   2
  7  -8   9   1
  1  -2   1   3

 ==================== Original Matrix: ====================
  1   2   3   4
  5   6   7   8
  9  33  11  12
 13  14  15  17

 Gauss-Jordan Inverted:
   19/184  -199/184     -1/46       1/2
     1/23     -2/23      1/23         0
 -441/184   813/184     -1/46      -3/2
        2        -3         0         1

 Re-inverted:
  1   2   3   4
  5   6   7   8
  9  33  11  12
 13  14  15  17

 ==================== Original Matrix: ====================
  3   1   8   9   6
  6   2   8  10   1
  5   7   2  10   3
  3   2   7   7   9
  3   5   6   1   1

 Gauss-Jordan Inverted:
 -4525/6238   2529/6238   -233/3119   1481/3119   -639/6238
  1033/6238  -1075/6238    342/3119   -447/3119    871/6238
  1299/6238   -289/6238   -204/3119   -390/3119    739/6238
   782/3119   -222/3119    237/3119   -556/3119   -177/3119
  -474/3119    -17/3119    -24/3119    688/3119   -140/3119

 Re-inverted:
  3   1   8   9   6
  6   2   8  10   1
  5   7   2  10   3
  3   2   7   7   9
  3   5   6   1   1

 ==================== Original Matrix: ====================
    1   1/2   1/3   1/4   1/5   1/6   1/7   1/8   1/9  1/10
  1/2   1/3   1/4   1/5   1/6   1/7   1/8   1/9  1/10  1/11
  1/3   1/4   1/5   1/6   1/7   1/8   1/9  1/10  1/11  1/12
  1/4   1/5   1/6   1/7   1/8   1/9  1/10  1/11  1/12  1/13
  1/5   1/6   1/7   1/8   1/9  1/10  1/11  1/12  1/13  1/14
  1/6   1/7   1/8   1/9  1/10  1/11  1/12  1/13  1/14  1/15
  1/7   1/8   1/9  1/10  1/11  1/12  1/13  1/14  1/15  1/16
  1/8   1/9  1/10  1/11  1/12  1/13  1/14  1/15  1/16  1/17
  1/9  1/10  1/11  1/12  1/13  1/14  1/15  1/16  1/17  1/18
 1/10  1/11  1/12  1/13  1/14  1/15  1/16  1/17  1/18  1/19

 Gauss-Jordan Inverted:
            100           -4950           79200         -600600         2522520        -6306300         9609600        -8751600         4375800         -923780
          -4950          326700        -5880600        47567520      -208107900       535134600      -832431600       770140800      -389883780        83140200
          79200        -5880600       112907520      -951350400      4281076800    -11237826600     17758540800    -16635041280      8506555200     -1829084400
        -600600        47567520      -951350400      8245036800    -37875637800    101001700800   -161602721280    152907955200    -78843164400     17071454400
        2522520      -208107900      4281076800    -37875637800    176752976400   -477233036280    771285715200   -735869534400    382086104400    -83223340200
       -6306300       535134600    -11237826600    101001700800   -477233036280   1301544644400  -2121035716800   2037792556800  -1064382719400    233025352560
        9609600      -832431600     17758540800   -161602721280    771285715200  -2121035716800   3480673996800  -3363975014400   1766086882560   -388375587600
       -8751600       770140800    -16635041280    152907955200   -735869534400   2037792556800  -3363975014400   3267861442560  -1723286307600    380449555200
        4375800      -389883780      8506555200    -78843164400    382086104400  -1064382719400   1766086882560  -1723286307600    912328045200   -202113826200
        -923780        83140200     -1829084400     17071454400    -83223340200    233025352560   -388375587600    380449555200   -202113826200     44914183600

 Re-inverted:
    1   1/2   1/3   1/4   1/5   1/6   1/7   1/8   1/9  1/10
  1/2   1/3   1/4   1/5   1/6   1/7   1/8   1/9  1/10  1/11
  1/3   1/4   1/5   1/6   1/7   1/8   1/9  1/10  1/11  1/12
  1/4   1/5   1/6   1/7   1/8   1/9  1/10  1/11  1/12  1/13
  1/5   1/6   1/7   1/8   1/9  1/10  1/11  1/12  1/13  1/14
  1/6   1/7   1/8   1/9  1/10  1/11  1/12  1/13  1/14  1/15
  1/7   1/8   1/9  1/10  1/11  1/12  1/13  1/14  1/15  1/16
  1/8   1/9  1/10  1/11  1/12  1/13  1/14  1/15  1/16  1/17
  1/9  1/10  1/11  1/12  1/13  1/14  1/15  1/16  1/17  1/18
 1/10  1/11  1/12  1/13  1/14  1/15  1/16  1/17  1/18  1/19
```


[User]
Task

Solve   **Ax=b**   using Gaussian elimination then backwards substitution.

**A**   being an   **n** by **n**   matrix.

Also,   **x** and **b**   are   **n** by **1**   vectors.

To improve accuracy, please use partial pivoting and scaling.

See also
:   * the Wikipedia entry:   Gaussian elimination

[Assistant]
(formerly Perl 6)

Gaussian elimination results in a matrix in row echelon form. Gaussian elimination with back-substitution (also known as Gauss-Jordan elimination) results in a matrix in reduced row echelon form. That being the case, we can reuse much of the code from the Reduced row echelon form task. Raku stores and does calculations on decimal numbers within its limit of precision using Rational numbers by default, meaning the calculations are exact.

```
sub gauss-jordan-solve (@a, @b) {
    @b.kv.map: { @a[$^k].append: $^v };
    @a.&rref[*]»[*-1];
}

# reduced row echelon form
sub rref (@m) {
    my ($lead, $rows, $cols) = 0, @m, @m[0];

    for ^$rows -> $r {
        $lead < $cols or return @m;
        my $i = $r;
        until @m[$i;$lead] {
            ++$i == $rows or next;
            $i = $r;
            ++$lead == $cols and return @m;
        }
        @m[$i, $r] = @m[$r, $i] if $r != $i;
        @m[$r] »/=» $ = @m[$r;$lead];
        for ^$rows -> $n {
            next if $n == $r;
            @m[$n] »-=» @m[$r] »×» (@m[$n;$lead] // 0);
        }
        ++$lead;
    }
    @m
}

sub rat-or-int ($num) {
    return $num unless $num ~~ Rat;
    return $num.narrow if $num.narrow ~~ Int;
    $num.nude.join: '/';
}

sub say-it ($message, @array, $fmt = " %8s") {
    say "\n$message";
    $_».&rat-or-int.fmt($fmt).put for @array;
}

my @a = (
    [ 1.00, 0.00, 0.00,  0.00,  0.00,   0.00 ],
    [ 1.00, 0.63, 0.39,  0.25,  0.16,   0.10 ],
    [ 1.00, 1.26, 1.58,  1.98,  2.49,   3.13 ],
    [ 1.00, 1.88, 3.55,  6.70, 12.62,  23.80 ],
    [ 1.00, 2.51, 6.32, 15.88, 39.90, 100.28 ],
    [ 1.00, 3.14, 9.87, 31.01, 97.41, 306.02 ],
);
my @b = ( -0.01, 0.61, 0.91, 0.99, 0.60, 0.02 );

say-it 'A matrix:', @a, "%6.2f";
say-it 'or, A in exact rationals:', @a;
say-it 'B matrix:', @b, "%6.2f";
say-it 'or, B in exact rationals:', @b;
say-it 'x matrix:', (my @gj = gauss-jordan-solve @a, @b), "%16.12f";
say-it 'or, x in exact rationals:', @gj, "%28s";

```

Output:

```
A matrix:
  1.00   0.00   0.00   0.00   0.00   0.00
  1.00   0.63   0.39   0.25   0.16   0.10
  1.00   1.26   1.58   1.98   2.49   3.13
  1.00   1.88   3.55   6.70  12.62  23.80
  1.00   2.51   6.32  15.88  39.90 100.28
  1.00   3.14   9.87  31.01  97.41 306.02

or, A in exact rationals:
        1         0         0         0         0         0
        1    63/100    39/100       1/4      4/25      1/10
        1     63/50     79/50     99/50   249/100   313/100
        1     47/25     71/20     67/10    631/50     119/5
        1   251/100    158/25    397/25    399/10   2507/25
        1    157/50   987/100  3101/100  9741/100  15301/50

B matrix:
 -0.01
  0.61
  0.91
  0.99
  0.60
  0.02

or, B in exact rationals:
   -1/100
   61/100
   91/100
   99/100
      3/5
     1/50

x matrix:
 -0.010000000000
  1.602790394502
 -1.613203059906
  1.245494121371
 -0.490989719585
  0.065760696175

or, x in exact rationals:
                      -1/100
   655870882787/409205648497
  -660131804286/409205648497
   509663229635/409205648497
  -200915766608/409205648497
    26909648324/409205648497

```


[User]
A Gaussian Integer is a complex number such that its real and imaginary parts are both integers.

```
   a + bi where a and b are integers and i is √-1.

```

The norm of a Gaussian integer is its product with its conjugate.

```
   N(a + bi) = (a + bi)(a − bi) = a² + b²

```

A Gaussian integer is a Gaussian prime if and only if either: both **a** and **b** are non-zero and its **norm** is a prime number, or, one of **a** or **b** is zero and it is the product of a unit **(±1, ±i)** and a prime integer of the form **4n + 3**.

Prime integers that are *not* of the form **4n + 3** can be factored into a Gaussian integer and its complex conjugate so are not a Gaussian prime.

```
   E.G. 5 = (2 + i)(2 − i) So 5 is not a Gaussian prime

```

Gaussian primes are octogonally symmetrical on a real / imaginary Cartesian field. If a particular complex norm **a² + b²** is prime, since addition is commutative, **b² + a²** is also prime, as are the complex conjugates and negated instances of both.

Task

Find and show, here on this page, the Gaussian primes with a norm of less than 100, (within a radius of 10 from the origin **0 + 0i** on a complex plane.)

Plot the points corresponding to the Gaussian primes on a Cartesian real / imaginary plane at least up to a radius of 50.

See also

* Wikipedia: Gaussian integers * Wikipedia: Gaussian primes * OEIS: Gaussian primes

[Assistant]
Plotting the points up to a radius of 150.

```
use List::Divvy;

my @next = { :1x, :1y, :2n },;

sub next-interval (Int $int) {
     @next.append: (^$int).map: { %( :x($int), :y($_), :n($int² + .²) ) };
     @next = |@next.sort: *.<n>;
}

my @gaussian = lazy gather {
    my $interval = 1;
    loop {
        my @this = @next.shift;
        @this.push: @next.shift while @next and @next[0]<n> == @this[0]<n>;
        for @this {
            .take if .<n>.is-prime || (!.<y> && .<x>.is-prime && (.<x> - 3) %% 4);
            next-interval(++$interval) if $interval == .<x>
        }
    }
}

# Primes within a radius of 10 from origin
say "Gaussian primes with a norm less than 100 sorted by norm:";
say @gaussian.&before(*.<n> > 10²).map( {
     my (\i, \j) = .<x y>;
    flat ((i,j),(-i,j),(-i,-j),(i,-j),(j,i),(-j,i),(-j,-i),(j,-i)).map: {
        .[0] ?? .[1] ?? (sprintf "%d%s%di", .[0], (.[1] ≥ 0 ?? '+' !! ''), .[1]) !! .[0] !! "{.[1]}i"
    }} )».subst('1i', 'i', :g)».fmt("%6s")».unique.flat.batch(10).join: "\n" ;

# Plot points within a 150 radius
use SVG;

my @points = unique flat @gaussian.&before(*.<n> > 150²).map: {
    my (\i, \j) = .<x y>;
    do for (i,j),(-i,j),(-i,-j),(i,-j),(j,i),(-j,i),(-j,-i),(j,-i) {
        :use['xlink:href'=>'#point', 'transform'=>"translate({500 + 3 × .[0]},{500 + 3 × .[1]})"]
    }
}

'gaussian-primes-raku.svg'.IO.spurt: SVG.serialize(
    svg => [
        :width<1000>, :height<1000>,
        :rect[:width<100%>, :height<100%>, :style<fill:black;>],
        :defs[:g[:id<point>, :circle[:0cx, :0cy, :2r, :fill('gold')]]],
        |@points
    ],
);

```

Output:

```
Gaussian primes with a norm less than 100 sorted by norm:
   1+i   -1+i   -1-i    1-i    2+i   -2+i   -2-i    2-i   1+2i  -1+2i
 -1-2i   1-2i      3     -3     3i    -3i   3+2i  -3+2i  -3-2i   3-2i
  2+3i  -2+3i  -2-3i   2-3i    4+i   -4+i   -4-i    4-i   1+4i  -1+4i
 -1-4i   1-4i   5+2i  -5+2i  -5-2i   5-2i   2+5i  -2+5i  -2-5i   2-5i
   6+i   -6+i   -6-i    6-i   1+6i  -1+6i  -1-6i   1-6i   5+4i  -5+4i
 -5-4i   5-4i   4+5i  -4+5i  -4-5i   4-5i      7     -7     7i    -7i
  7+2i  -7+2i  -7-2i   7-2i   2+7i  -2+7i  -2-7i   2-7i   6+5i  -6+5i
 -6-5i   6-5i   5+6i  -5+6i  -5-6i   5-6i   8+3i  -8+3i  -8-3i   8-3i
  3+8i  -3+8i  -3-8i   3-8i   8+5i  -8+5i  -8-5i   8-5i   5+8i  -5+8i
 -5-8i   5-8i   9+4i  -9+4i  -9-4i   9-4i   4+9i  -4+9i  -4-9i   4-9i
```

Off-site SVG image: gaussian-primes-raku.svg


[User]
Task

Write a generalized version of FizzBuzz that works for any list of factors, along with their words.

This is basically a "fizzbuzz" implementation where the user supplies the parameters.

The user will enter the max number, then they will enter the factors to be calculated along with the corresponding word to be printed.

For simplicity's sake, assume the user will input an integer as the max number and 3 factors, each with a word associated with them.

For example, given:

```
>20      #This is the maximum number, supplied by the user
>3 Fizz  #The user now enters the starting factor (3) and the word they want associated with it (Fizz)
>5 Buzz  #The user now enters the next factor (5) and the word they want associated with it (Buzz)
>7 Baxx  #The user now enters the next factor (7) and the word they want associated with it (Baxx)

```

In other words: For this example, print the numbers **1** through **20**, replacing every multiple of **3** with "Fizz", every multiple of **5** with "Buzz", and every multiple of **7** with "Baxx".

In the case where a number is a multiple of at least two factors, print each of the words associated with those factors in the order of least to greatest factor.

For instance, the number **15** is a multiple of both **3** and **5**; print "FizzBuzz".

If the max number was **105** instead of **20**, you would print "FizzBuzzBaxx" because it's a multiple of **3**, **5**, and **7**.

Output:

```
1
2
Fizz
4
Buzz
Fizz
Baxx
8
Fizz
Buzz
11
Fizz
13
Baxx
FizzBuzz
16
17
Fizz
19
Buzz

```

[Assistant]
(formerly Perl 6)

**Works with**: rakudo version 2015-09-20

```
# General case implementation of a "FizzBuzz" class.
# Defaults to standard FizzBuzz unless a new schema is passed in.
class FizzBuzz {
    has $.schema is rw = < 3 Fizz 5 Buzz >.hash;
    method filter (Int $this) {
        my $fb;
        for $.schema.sort: { +.key } -> $p { $fb ~= $this %% +$p.key ?? $p.value !! ''};
        return $fb || $this;
    }
}

# Sub implementing the specific requirements of the task.
sub GeneralFizzBuzz (Int $upto, @schema?) {
    my $ping = FizzBuzz.new;
    $ping.schema = @schema.hash if @schema;
    map { $ping.filter: $_ }, 1 .. $upto;
}

# The task
say 'Using: 20 ' ~ <3 Fizz 5 Buzz 7 Baxx>;
.say for GeneralFizzBuzz(20, <3 Fizz 5 Buzz 7 Baxx>);

say '';

# And for fun
say 'Using: 21 ' ~ <2 Pip 4 Squack 5 Pocketa 7 Queep>;
say join ', ', GeneralFizzBuzz(21, <2 Pip 4 Squack 5 Pocketa 7 Queep>);

```

Output:

```
Using: 20 3 Fizz 5 Buzz 7 Baxx
1
2
Fizz
4
Buzz
Fizz
Baxx
8
Fizz
Buzz
11
Fizz
13
Baxx
FizzBuzz
16
17
Fizz
19
Buzz

Using: 21 2 Pip 4 Squack 5 Pocketa 7 Queep
1, Pip, 3, PipSquack, Pocketa, Pip, Queep, PipSquack, 9, PipPocketa, 11, PipSquack, 13, PipQueep, Pocketa, PipSquack, 17, Pip, 19, PipSquackPocketa, Queep
```

Here's the same program in a more functional idiom:

```
sub genfizzbuzz($n, +@fb) {
    [Z~](
        do for @fb || <3 fizz 5 buzz> -> $i, $s {
            flat ('' xx $i-1, $s) xx *;
        }
    ) Z|| 1..$n
}

.say for genfizzbuzz(20, <3 Fizz 5 Buzz 7 Baxx>);

```


[User]
It is possible to implement floating point arithmetic in many different ways; though the standard IEEE arithmetic implementation on modern hardware usually uses a fixed-width binary implementation (using a total of 32 bits for single-precision floats — `float` in a number of languages — and 64 bits for double-precision floats — `double`) many other schemes can be used. For example, the base need not be binary (alternatives include decimal, binary-coded decimal, and even balanced ternary) and there is no requirement that a fixed number of digits be used.

Define addition for floating point numbers where the digits are stored in an arbitrary base; e.g. the digits can be stored as binary, decimal, binary-coded decimal, or even balanced ternary.
You should implement the code in a generalised form (such as a Template, Module or Mixin etc) that permits reusing of the code for different Bases.

If it is not possible to implement code by providing an implementation that uses the *syntax* of the specific language then:

* Note the reason why this is.
* Demonstrate that the language still supports the semantics of generalised floating point by implementing the *test case* using built-in code or a library.

**Test case:**

Define arbitrary precision addition on floating point numbers (e.g., encoding those numbers using Binary Coded Decimal, or using an arbitrary precision integer arithmetic library). Calculate the terms for -7 to 21 in this sequence of calculations:

Calculate the terms for -7 to 21 in this sequence of calculations

| Number | Term calculation | Result |
| --- | --- | --- |
| -7 | 12345679e63 × 81 + 1e63 | 1e72 |
| -6 | 12345679012345679e54 × 81 + 1e54 | 1e72 |
| -5 | 12345679012345679012345679e45 × 81 + 1e45 | 1e72 |
| -4 | 12345679012345679012345679012345679e36 × 81 + 1e36 | 1e72 |
| etc. | The final calculation will be over 256 digits wide | 1e72 |

You will either need to implement multiplication, or perform the multiplication by 81 by using repeated additions. The results will always be 1e72.

Bonus

Make the template (module, class, mixing, etc.) able to successfully handle using other bases to perform the above test case. Demonstrate using balanced ternary.

[Assistant]
(formerly Perl 6)
As long as all values are kept as rationals (type `Rat`) calculations are done full precision.

```
my $e = 63;
for -7..21 -> $n {
    my $num = '12345679' ~ '012345679' x ($n+7);
    my $sum = $_ + ($num * $_) * 81 given $e > -20 ?? 10**$e !! Rat.new(1,10**abs $e);
    printf "$n:%s ", 10**72 == $sum ?? 'Y' !! 'N';
    $e -= 9;
}

```

Output:

```
-7:Y -6:Y -5:Y -4:Y -3:Y -2:Y -1:Y 0:Y 1:Y 2:Y 3:Y 4:Y 5:Y 6:Y 7:Y 8:Y 9:Y 10:Y 11:Y 12:Y 13:Y 14:Y 15:Y 16:Y 17:Y 18:Y 19:Y 20:Y 21:Y

```


[User]
**Chess960** is a variant of chess created by world champion Bobby Fischer. Unlike other variants of the game, Chess960 does not require a different material, but instead relies on a random initial position, with a few constraints:

* as in the standard chess game, all eight white pawns must be placed on the second rank.
* White pieces must stand on the first rank as in the standard game, in random column order but with the two following constraints:
  + the bishops must be placed on opposite color squares (i.e. they must be an odd number of spaces apart or there must be an even number of spaces between them)
  + the King must be between two rooks (with any number of other pieces between them all)
* Black pawns and pieces must be placed respectively on the seventh and eighth ranks, mirroring the white pawns and pieces, just as in the standard game. (That is, their positions are not independently randomized.)

With those constraints there are **960** possible starting positions, thus the name of the variant.

Task

The purpose of this task is to write a program that can randomly generate any one of the 960 Chess960 initial positions. You will show the result as the first rank displayed using either the chess symbols in Unicode (♔♕♖♗♘), the letters **K**ing **Q**ueen **R**ook **B**ishop k**N**ight, or the corresponding letters in a language other than English.

[Assistant]
(formerly Perl 6)
First, using a list with three rooks and no king, we keep generating a random piece order until the two bishops are on opposite colors. Then we sneakily promote the second of the three rooks to a king.

```
repeat until m/ '♗' [..]* '♗' / { $_ = < ♖ ♖ ♖ ♕ ♗ ♗ ♘ ♘ >.pick(*).join }
s:2nd['♖'] = '♔';
say .comb;

```

Output:

```
♕ ♗ ♖ ♘ ♔ ♖ ♗ ♘
```

Here's a more "functional" solution that avoids side effects

```
sub chess960 {
    .subst(:nth(2), /'♜'/, '♚') given
    first rx/ '♝' [..]* '♝' /,
    < ♛ ♜ ♜ ♜ ♝ ♝ ♞ ♞ >.pick(*).join xx *;
}

say chess960;

```

Output:

```
♛♝♜♚♝♞♞♜
```

We can also pregenerate the list of 960 positions, though the method we use below is a bit wasteful, since it
generates 40320 candidates only to throw most of them away. This is essentially the same filtering algorithm
but written in the form of a list comprehension rather than nested map and grep. (The list comprehension is actually faster currently.) Note that the constant is calculated at compile time, because, well, it's a constant. Just a big fancy one.

```
constant chess960 =
   < ♛ ♜ ♜ ♜ ♝ ♝ ♞ ♞ >.permutations».join.unique.grep( / '♝' [..]* '♝' / )».subst(:nth(2), /'♜'/, '♚');

.say for chess960;

```

Here's a much faster way (about 30x) to generate all 960 variants by construction. No need to filter for uniqueness, since it produces exactly 960 entries.

```
constant chess960 = gather for 0..3 -> $q {
    (my @q = <♜ ♚ ♜>).splice($q, 0, '♛');
    for 0 .. @q -> $n1 {
        (my @n1 = @q).splice($n1, 0, '♞');
        for $n1 ^.. @n1 -> $n2 {
            (my @n2 = @n1).splice($n2, 0, '♞');
            for 0 .. @n2 -> $b1 {
                (my @b1 = @n2).splice($b1, 0, '♝');
                for $b1+1, $b1+3 ...^ * > @b1 -> $b2 {
                    (my @b2 = @b1).splice($b2, 0, '♝');
                    take @b2.join;
                }
            }
        }
    }
}

CHECK { note "done compiling" }
note +chess960;
say chess960.pick;

```

Output:

```
done compiling
960
♜♚♝♜♞♛♞♝
```

If you run this you'll see that most of the time is spent in compilation, so in the case of separate precompilation the table of 960 entries merely needs to be deserialized back into memory. Picking from those entries guarantees uniform distribution over all possible boards.

```
♛♝♜♚♝♞♞♜
```

### Raku: Generate from SP-ID

There is a standard numbering scheme for Chess960 positions, assigning each an index in the range 0..959. This function will generate the corresponding position from a given index number (or fall back to a random one if no index is specified, making it yet another solution to the general problem).

```
subset Pos960 of Int where { $_ ~~ ^960 };
sub chess960(Pos960 $position = (^960).pick) {

  # We remember the remainder used to place first bishop in order to place the
  # second
  my $b1;

  # And likewise remember the chosen combination for knights between those
  # placements
  my @n;

  # Piece symbols and positioning rules in order.  Start with the position
  # number. At each step, divide by the divisor; the quotient becomes the
  # dividend for the next step.  Feed the remainder into the specified code block
  # to get a space number N, then place the piece in the Nth empty space left in
  # the array.
  my @rules = (
    #divisor, mapping function,                      piece
    ( 4,      { $b1 = $_; 2 * $_ + 1 },              '♝'  ),
    ( 4,      { 2 * $_ - ($_ > $b1 ?? 1 !! 0) },     '♝'  ),
    ( 6,      { $_ },                                '♛'  ),
    (10,      { @n = combinations(5,2)[$_]; @n[0] }, '♞'  ),
    ( 1,      { @n[1]-1 },                           '♞'  ),
    ( 1,      { 0 },                                 '♜'  ),
    ( 1,      { 0 },                                 '♚'  ),
    ( 1,      { 0 },                                 '♜'  )

  );

  # Initial array, using '-' to represent empty spaces
  my @array = «-» xx 8;

  # Working value that starts as the position number but is divided by the
  # divisor at each placement step.
  my $p = $position;

  # Loop over the placement rules
  for @rules -> ($divisor, $block, $piece) {

    # get remainder when divided by divisor
    (my $remainder, $p) = $p.polymod($divisor);

    # apply mapping function
    my $space = $block($remainder);

    # find index of the $space'th element of the array that's still empty
    my $index = @array.kv.grep(-> $i,$v { $v eq '-' })[$space][0];

    # and place the piece
    @array[$index] = $piece;
  }
  return @array;
}

# demo code
say chess960(518); #standard optning position
say chess960; # (it happened to pick #300)

```

Output:

```
♜ ♞ ♝ ♛ ♚ ♝ ♞ ♜
♛ ♝ ♞ ♜ ♚ ♜ ♝ ♞
```