[User]
Brace expansion is a type of parameter expansion made popular by Unix shells, where it allows users to specify multiple similar string parameters without having to type them all out. E.g. the parameter `enable_{audio,video}` would be interpreted as if both `enable_audio` and `enable_video` had been specified.

Task

Write a function that can perform brace expansion on any input string, according to the following specification.
Demonstrate how it would be used, and that it passes the four test cases given below.

Specification

In the input string, balanced pairs of braces containing comma-separated substrings (details below) represent *alternations* that specify multiple alternatives which are to appear at that position in the output. In general, one can imagine the information conveyed by the input string as a tree of nested alternations interspersed with literal substrings, as shown in the middle part of the following diagram:

|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| It{{em,alic}iz,erat}e{d,} | *parse*  ―――――▶  | |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | It | |  |  |  |  |  |  |  |  | | --- | --- | --- | --- | --- | --- | --- | --- | | ⎧ ⎨ ⎩ | |  |  |  | | --- | --- | --- | | ⎧ ⎨ ⎩ | em | ⎫ ⎬ ⎭ | | alic | | iz | ⎫ ⎬ ⎭ | | erat | | | e | |  |  |  | | --- | --- | --- | | ⎧ ⎨ ⎩ | d | ⎫ ⎬ ⎭ | |  | | | *expand*  ―――――▶  | Itemized Itemize Italicized Italicize  Iterated Iterate |
| input string |  | alternation tree |  | output *(list of strings)* |

This tree can in turn be transformed into the intended list of output strings by, colloquially speaking, determining all the possible ways to walk through it from left to right while only descending into *one* branch of each alternation one comes across *(see the right part of the diagram)*. When implementing it, one can of course combine the parsing and expansion into a single algorithm, but this specification discusses them separately for the sake of clarity.

**Expansion** of alternations can be more rigorously described by these rules:

|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| |  |  |  |  |  |  |  |  |  |  |  |  |  |  | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | a | |  |  |  | | --- | --- | --- | | ⎧ ⎨ ⎩ | 2 | ⎫ ⎬ ⎭ | | 1 | | b | |  |  |  | | --- | --- | --- | | ⎧ ⎨ ⎩ | X | ⎫ ⎬ ⎭ | | Y | | X | | c | | ⟶ | |  | | --- | | a2bXc | | a2bYc | | a2bXc | | a1bXc | | a1bYc | | a1bXc | |

* An alternation causes the list of alternatives that will be produced by its parent branch to be increased 𝑛-fold, each copy featuring one of the 𝑛 alternatives produced by the alternation's child branches, in turn, at that position.
* This means that multiple alternations inside the same branch are cumulative  *(i.e. the complete list of alternatives produced by a branch is the string-concatenating "Cartesian product" of its parts)*.
* All alternatives (even duplicate and empty ones) are preserved, and they are ordered like the examples demonstrate  *(i.e. "lexicographically" with regard to the alternations)*.
* The alternatives produced by the root branch constitute the final output.

**Parsing** the input string involves some additional complexity to deal with escaped characters and "incomplete" brace pairs:

|  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| a\\{\\\{b,c\,d} | ⟶ | |  |  |  |  |  |  | | --- | --- | --- | --- | --- | --- | | a\\ | |  |  |  | | --- | --- | --- | | ⎧ ⎨ ⎩ | \\\{b | ⎫ ⎬ ⎭ | | c\,d | | |
| {a,b{c{,{d}}e}f | ⟶ | |  |  |  |  |  |  |  | | --- | --- | --- | --- | --- | --- | --- | | {a,b{c | |  |  |  | | --- | --- | --- | | ⎧ ⎨ ⎩ |  | ⎫ ⎬ ⎭ | | {d} | | e}f | |

* An unescaped *backslash* which precedes another character, escapes that character (to force it to be treated as literal). The backslashes are passed along to the output unchanged.
* Balanced *brace pairs* are identified by, conceptually, going through the string from left to right and associating each unescaped closing brace that is encountered with the nearest still unassociated unescaped opening brace to its left (if any). Furthermore, each unescaped *comma* is associated with the innermost brace pair that contains it (if any). With that in mind:
  + Each brace pair that has at least one comma associated with it, forms an alternation (whose branches are the brace pair's contents split at its commas). The associated brace and comma characters themselves do not become part of the output.
  + Brace characters from pairs without any associated comma, as well as unassociated brace and comma characters, as well as all characters that are not covered by the preceding rules, are instead treated as literals.

For every possible input string, your implementation should produce exactly the output which this specification mandates. Please comply with this even when it's inconvenient, to ensure that all implementations are comparable. However, none of the above should be interpreted as instructions (or even recommendations) for **how** to implement it. Try to come up with a solution that is idiomatic in your programming language. *(See #Perl for a reference implementation.)*

Test Cases

:   :   :   | Input *(single string)* | Ouput *(list/array of strings)* |
            | --- | --- |
            | `~/{Downloads,Pictures}/*.{jpg,gif,png}` | `~/Downloads/*.jpg`  `~/Downloads/*.gif`  `~/Downloads/*.png`  `~/Pictures/*.jpg`  `~/Pictures/*.gif`  `~/Pictures/*.png` |
            | `It{{em,alic}iz,erat}e{d,}, please.` | `Itemized, please.`  `Itemize, please.`  `Italicized, please.`  `Italicize, please.`  `Iterated, please.`  `Iterate, please.` |
            | `{,{,gotta have{ ,\, again\, }}more }cowbell!` | `cowbell!`  `more cowbell!`  `gotta have more cowbell!`  `gotta have\, again\, more cowbell!` |
            | `{}} some }{,{\\{ edge, edge} \,}{ cases, {here} \\\\\}` | `{}} some }{,{\\ edge \,}{ cases, {here} \\\\\}`  `{}} some }{,{\\ edge \,}{ cases, {here} \\\\\}` |

---

Other tasks related to string operations:

Metrics

* Array length
* String length
* Copy a string
* Empty string  (assignment)

Counting

* Word frequency
* Letter frequency
* Jewels and stones
* I before E except after C
* Bioinformatics/base count
* Count occurrences of a substring
* Count how many vowels and consonants occur in a string

Remove/replace

* XXXX redacted
* Conjugate a Latin verb
* Remove vowels from a string
* String interpolation (included)
* Strip block comments
* Strip comments from a string
* Strip a set of characters from a string
* Strip whitespace from a string -- top and tail
* Strip control codes and extended characters from a string

Anagrams/Derangements/shuffling

* Word wheel
* ABC problem
* Sattolo cycle
* Knuth shuffle
* Ordered words
* Superpermutation minimisation
* Textonyms (using a phone text pad)
* Anagrams
* Anagrams/Deranged anagrams
* Permutations/Derangements

Find/Search/Determine

* ABC words
* Odd words
* Word ladder
* Semordnilap
* Word search
* Wordiff  (game)
* String matching
* Tea cup rim text
* Alternade words
* Changeable words
* State name puzzle
* String comparison
* Unique characters
* Unique characters in each string
* Extract file extension
* Levenshtein distance
* Palindrome detection
* Common list elements
* Longest common suffix
* Longest common prefix
* Compare a list of strings
* Longest common substring
* Find common directory path
* Words from neighbour ones
* Change e letters to i in words
* Non-continuous subsequences
* Longest common subsequence
* Longest palindromic substrings
* Longest increasing subsequence
* Words containing "the" substring
* Sum of the digits of n is substring of n
* Determine if a string is numeric
* Determine if a string is collapsible
* Determine if a string is squeezable
* Determine if a string has all unique characters
* Determine if a string has all the same characters
* Longest substrings without repeating characters
* Find words which contains all the vowels
* Find words which contain the most consonants
* Find words which contains more than 3 vowels
* Find words whose first and last three letters are equal
* Find words with alternating vowels and consonants

Formatting

* Substring
* Rep-string
* Word wrap
* String case
* Align columns
* Literals/String
* Repeat a string
* Brace expansion
* Brace expansion using ranges
* Reverse a string
* Phrase reversals
* Comma quibbling
* Special characters
* String concatenation
* Substring/Top and tail
* Commatizing numbers
* Reverse words in a string
* Suffixation of decimal numbers
* Long literals, with continuations
* Numerical and alphabetical suffixes
* Abbreviations, easy
* Abbreviations, simple
* Abbreviations, automatic

Song lyrics/poems/Mad Libs/phrases

* Mad Libs
* Magic 8-ball
* 99 bottles of beer
* The Name Game (a song)
* The Old lady swallowed a fly
* The Twelve Days of Christmas

Tokenize

* Text between
* Tokenize a string
* Word break problem
* Tokenize a string with escaping
* Split a character string based on change of character

Sequences

* Show ASCII table
* De Bruijn sequences
* Summarize and say sequence
* Generate lower case ASCII alphabet

:   * Brace\_expansion\_using\_ranges

[Assistant]
(formerly Perl 6)
The task description allows the taking of shortcuts, but please note that we are not taking any shortcuts here. The solution is short because this particular problem happens to map quite naturally to the strengths of Raku.

First, the parsing is handled with a grammar that can backtrack in the few places this problem needs it. The + quantifier matches one or more alternatives (we handle the case of a single alternative in the walk now), and the % modifier requires a comma between each quantified item to its left. Note that the \* quantifiers do *not* backtrack here, because the token keyword suppresses that; all the backtracking here fails over to a different alternative in an outer alternation (that is, things separated by the | character in the grammar. Most of these failovers just nibble an uninteresting character and continue.)

On the other end, we recursively walk the parse tree returning expanded sublists, and we do the cartesian concatenation of sublists at each level by use of the X~ operator, which is a "cross" metaoperator used on a simple ~ concatenation. As a list infix operator, X~ does not care how many items are on either side, which is just what you want in this case, since some of the arguments are strings and some are lists. Here we use a fold or reduction form in square brackets to interpose the cross-concat between each value generated by the map, which returns a mixture of lists and literal strings. One other thing that might not be obvious: if we bind to the match variable, $/, we automatically get all the syntactic sugar for its submatches. In this case, $0 is short for $/[0], and represents all the submatches captured by 0th set of parens in either TOP or alt. $<meta> is likewise short for $/<meta>, and retrieves what was captured by that named submatch.

```
grammar BraceExpansion {
    token TOP  { ( <meta> | . )* }
    token meta { '{' <alts> '}' | \\ .  }
    token alts { <alt>+ % ',' }
    token alt  { ( <meta> | <-[ , } ]> )* }
}

sub crosswalk($/) {
    |[X~] flat '', $0.map: -> $/ { $<meta><alts><alt>.&alternatives or ~$/ }
}

sub alternatives($_) {
    when :not { () }
    when 1    { '{' X~ $_».&crosswalk X~ '}' }
    default   { $_».&crosswalk }
}

sub brace-expand($s) { crosswalk BraceExpansion.parse($s) }

# Testing:

sub bxtest(*@s) {
    for @s -> $s {
        say "\n$s";
        for brace-expand($s) {
            say "    ", $_;
        }
    }
}

bxtest Q:to/END/.lines;
    ~/{Downloads,Pictures}/*.{jpg,gif,png}
    It{{em,alic}iz,erat}e{d,}, please.
    {,{,gotta have{ ,\, again\, }}more }cowbell!
    a{b{1,2}c
    a{1,2}b}c
    a{1,{2},3}b
    more{ darn{ cowbell,},}
    ab{c,d\,e{f,g\h},i\,j{k,l\,m}n,o\,p}qr
    {a,{\,b}c
    a{b,{{c}}
    {a{\}b,c}d
    END

```

Output:

```
~/{Downloads,Pictures}/*.{jpg,gif,png}
    ~/Downloads/*.jpg
    ~/Downloads/*.gif
    ~/Downloads/*.png
    ~/Pictures/*.jpg
    ~/Pictures/*.gif
    ~/Pictures/*.png

It{{em,alic}iz,erat}e{d,}, please.
    Itemized, please.
    Itemize, please.
    Italicized, please.
    Italicize, please.
    Iterated, please.
    Iterate, please.

{,{,gotta have{ ,\, again\, }}more }cowbell!
    cowbell!
    more cowbell!
    gotta have more cowbell!
    gotta have\, again\, more cowbell!

{}} some {\\{edge,edgy} }{ cases, here\\\}
    {}} some {\\edge }{ cases, here\\\}
    {}} some {\\edgy }{ cases, here\\\}

a{b{1,2}c
    a{b1c
    a{b2c

a{1,2}b}c
    a1b}c
    a2b}c

a{1,{2},3}b
    a1b
    a{2}b
    a3b

more{ darn{ cowbell,},}
    more darn cowbell
    more darn
    more

ab{c,d\,e{f,g\h},i\,j{k,l\,m}n,o\,p}qr
    abcqr
    abd\,efqr
    abd\,eg\hqr
    abi\,jknqr
    abi\,jl\,mnqr
    abo\,pqr

{a,{\,b}c
    {a,{\,b}c

a{b,{{c}}
    a{b,{{c}}

{a{\}b,c}d
    {a\}bd
    {acd
```


[User]
This task has been clarified. Its programming examples are in need of review to ensure that they still fit the requirements of the task.

Task

Write and test a function which expands one or more Unix-style **numeric and alphabetic range braces** embedded in a larger string.

Specification

The brace strings used by Unix shells permit expansion of both:

1. Recursive comma-separated lists (covered by the **related task**: Brace\_expansion, and can be ignored here)
2. ordered numeric and alphabetic **ranges**, which are the object of this task.

The general pattern of brace ranges is:

```
{<START>..<END>}
```

and, in more recent shells:

```
{<START>..<END>..<INCR>}
```

(See https://wiki.bash-hackers.org/syntax/expansion/brace)

Expandable ranges of this kind can be ascending or descending:

```
simpleNumber{1..3}.txt
simpleAlpha-{Z..X}.txt
```

and may have a third INCR element specifying ordinal intervals larger than one.
The increment value can be preceded by a **-** minus sign, but not by a **+** sign.

The effect of the minus sign is to always to **reverse** the natural order suggested by the START and END values.

Any level of zero-padding used in either the START or END value of a numeric range is adopted in the expansions.

```
steppedDownAndPadded-{10..00..5}.txt
minusSignFlipsSequence {030..20..-5}.txt
```

A single string may contain more than one expansion range:

```
combined-{Q..P}{2..1}.txt
```

Alphabetic range values are limited to a single character for START and END
but these characters are not confined to the ASCII alphabet.

```
emoji{🌵..🌶}{🌽..🌾}etc
```

Unmatched braces are simply ignored, as are empty braces, and braces which contain no range (or list).

```
li{teral
rangeless{}empty
rangeless{random}string
```

Tests

Generate and display here the expansion of (at least) each of the ten example lines shown below.

The JavaScript implementation below uses parser combinators, aiming to encode a more or less full and legible description of the

```
<PREAMBLE><AMBLE><POSTSCRIPT>
```

range brace grammar, but you should use any resource that suggests itself in your language, including parser libraries.

(The grammar of range expansion, unlike that of nested list expansion, is not recursive, so even regular expressions should prove serviceable here).

The output of the JS implementation, which aims to match the brace expansion behaviour of the default **zsh** shell on current versions of macOS:

```
simpleNumberRising{1..3}.txt ->
    simpleNumberRising1.txt
    simpleNumberRising2.txt
    simpleNumberRising3.txt

simpleAlphaDescending-{Z..X}.txt ->
    simpleAlphaDescending-Z.txt
    simpleAlphaDescending-Y.txt
    simpleAlphaDescending-X.txt

steppedDownAndPadded-{10..00..5}.txt ->
    steppedDownAndPadded-10.txt
    steppedDownAndPadded-05.txt
    steppedDownAndPadded-00.txt

minusSignFlipsSequence {030..20..-5}.txt ->
    minusSignFlipsSequence 020.txt
    minusSignFlipsSequence 025.txt
    minusSignFlipsSequence 030.txt

reverseSteppedNumberRising{1..6..-2}.txt ->
    reverseSteppedNumberRising5.txt
    reverseSteppedNumberRising3.txt
    reverseSteppedNumberRising1.txt

combined-{Q..P}{2..1}.txt ->
    combined-Q2.txt
    combined-Q1.txt
    combined-P2.txt
    combined-P1.txt

emoji{🌵..🌶}{🌽..🌾}etc ->
    emoji🌵🌽etc
    emoji🌵🌾etc
    emoji🌶🌽etc
    emoji🌶🌾etc

li{teral ->
    li{teral

rangeless{}empty ->
    rangeless{}empty

rangeless{random}string ->
    rangeless{random}string
```

Other tasks related to string operations:

Metrics

* Array length
* String length
* Copy a string
* Empty string  (assignment)

Counting

* Word frequency
* Letter frequency
* Jewels and stones
* I before E except after C
* Bioinformatics/base count
* Count occurrences of a substring
* Count how many vowels and consonants occur in a string

Remove/replace

* XXXX redacted
* Conjugate a Latin verb
* Remove vowels from a string
* String interpolation (included)
* Strip block comments
* Strip comments from a string
* Strip a set of characters from a string
* Strip whitespace from a string -- top and tail
* Strip control codes and extended characters from a string

Anagrams/Derangements/shuffling

* Word wheel
* ABC problem
* Sattolo cycle
* Knuth shuffle
* Ordered words
* Superpermutation minimisation
* Textonyms (using a phone text pad)
* Anagrams
* Anagrams/Deranged anagrams
* Permutations/Derangements

Find/Search/Determine

* ABC words
* Odd words
* Word ladder
* Semordnilap
* Word search
* Wordiff  (game)
* String matching
* Tea cup rim text
* Alternade words
* Changeable words
* State name puzzle
* String comparison
* Unique characters
* Unique characters in each string
* Extract file extension
* Levenshtein distance
* Palindrome detection
* Common list elements
* Longest common suffix
* Longest common prefix
* Compare a list of strings
* Longest common substring
* Find common directory path
* Words from neighbour ones
* Change e letters to i in words
* Non-continuous subsequences
* Longest common subsequence
* Longest palindromic substrings
* Longest increasing subsequence
* Words containing "the" substring
* Sum of the digits of n is substring of n
* Determine if a string is numeric
* Determine if a string is collapsible
* Determine if a string is squeezable
* Determine if a string has all unique characters
* Determine if a string has all the same characters
* Longest substrings without repeating characters
* Find words which contains all the vowels
* Find words which contain the most consonants
* Find words which contains more than 3 vowels
* Find words whose first and last three letters are equal
* Find words with alternating vowels and consonants

Formatting

* Substring
* Rep-string
* Word wrap
* String case
* Align columns
* Literals/String
* Repeat a string
* Brace expansion
* Brace expansion using ranges
* Reverse a string
* Phrase reversals
* Comma quibbling
* Special characters
* String concatenation
* Substring/Top and tail
* Commatizing numbers
* Reverse words in a string
* Suffixation of decimal numbers
* Long literals, with continuations
* Numerical and alphabetical suffixes
* Abbreviations, easy
* Abbreviations, simple
* Abbreviations, automatic

Song lyrics/poems/Mad Libs/phrases

* Mad Libs
* Magic 8-ball
* 99 bottles of beer
* The Name Game (a song)
* The Old lady swallowed a fly
* The Twelve Days of Christmas

Tokenize

* Text between
* Tokenize a string
* Word break problem
* Tokenize a string with escaping
* Split a character string based on change of character

Sequences

* Show ASCII table
* De Bruijn sequences
* Summarize and say sequence
* Generate lower case ASCII alphabet

* range expansion

[Assistant]
**Works with**: Rakudo version 2020.08.1

Also implements some of the string list functions described on the bash-hackers page.

```
my $range = rx/ '{' $<start> = <-[.]>+? '..' $<end> = <-[.]>+? ['..' $<incr> = ['-'?\d+] ]? '}' /;
my $list  = rx/ ^ $<prefix> = .*? '{' (<-[,}]>+) +%% ',' '}' $<postfix> = .* $/;

sub expand (Str $string) {
    my @return = $string;
    if $string ~~ $range {
        quietly my ($start, $end, $incr) = $/<start end incr>».Str;
        $incr ||= 1;
        ($end, $start) = $start, $end if $incr < 0;
        $incr.=abs;

        if try all( +$start, +$end ) ~~ Numeric {
            $incr = - $incr if $start > $end;

            my ($sl, $el) = 0, 0;
            $sl = $start.chars if $start.starts-with('0');
            $el = $end.chars   if   $end.starts-with('0');

            my @this = $start < $end ?? (+$start, * + $incr …^ * > +$end) !! (+$start, * + $incr …^ * < +$end);
            @return  = @this.map: { $string.subst($range, sprintf("%{'0' ~ max $sl, $el}d", $_) ) }
        }
        elsif try +$start ~~ Numeric or +$end ~~ Numeric {
            return $string #fail
        }
        else {
            my @this;
            if $start.chars + $end.chars > 2 {
                return $string if $start.succ eq $start or $end.succ eq $end; # fail
                @this = $start lt $end ?? ($start, (*.succ xx $incr).tail …^ * gt $end) !! ($start, (*.pred xx $incr).tail …^ * lt $end);
            }
            else {
                $incr = -$incr if $start gt $end;
                @this = $start lt $end ?? ($start, (*.ord + $incr).chr …^ * gt $end) !! ($start, (*.ord + $incr).chr …^ * lt $end);
            }
            @return = @this.map: { $string.subst($range, sprintf("%s", $_) ) }
        }
    }
    if $string ~~ $list {
        my $these = $/[0]».Str;
        my ($prefix, $postfix) = $/<prefix postfix>».Str;
        if ($prefix ~ $postfix).chars {
            @return = $these.map: { $string.subst($list, $prefix ~ $_ ~ $postfix) } if $these.elems > 1
        }
        else {
            @return = $these.join: ' '
        }
    }
    my $cnt = 1;
    while $cnt != +@return {
        $cnt = +@return;
        @return.=map: { |.&expand }
    }
    @return
}

for qww<
    # Required tests

    simpleNumberRising{1..3}.txt
    simpleAlphaDescending-{Z..X}.txt
    steppedDownAndPadded-{10..00..5}.txt
    minusSignFlipsSequence{030..20..-5}.txt
    combined-{Q..P}{2..1}.txt
    emoji{🌵..🌶}{🌽..🌾}etc
    li{teral
    rangeless{}empty
    rangeless{random}string

    # Test some other features

    'stop point not in sequence-{02..10..3}.txt'
    steppedAlphaRising{P..Z..2}.txt
    'simple {just,give,me,money} list'
    {thatʼs,what,I,want}
    'emoji {☃,☄}{★,🇺🇸,☆} lists'
    'alphanumeric mix{ab7..ac1}.txt'
    'alphanumeric mix{0A..0C}.txt'

    # fail by design

    'mixed terms fail {7..C}.txt'
    'multi char emoji ranges fail {🌵🌵..🌵🌶}'
  > -> $test {
     say "$test ->";
     say ('    ' xx * Z~ expand $test).join: "\n";
     say '';
}

```

Output:

```
simpleNumberRising{1..3}.txt ->
    simpleNumberRising1.txt
    simpleNumberRising2.txt
    simpleNumberRising3.txt

simpleAlphaDescending-{Z..X}.txt ->
    simpleAlphaDescending-Z.txt
    simpleAlphaDescending-Y.txt
    simpleAlphaDescending-X.txt

steppedDownAndPadded-{10..00..5}.txt ->
    steppedDownAndPadded-10.txt
    steppedDownAndPadded-05.txt
    steppedDownAndPadded-00.txt

minusSignFlipsSequence{030..20..-5}.txt ->
    minusSignFlipsSequence020.txt
    minusSignFlipsSequence025.txt
    minusSignFlipsSequence030.txt

combined-{Q..P}{2..1}.txt ->
    combined-Q2.txt
    combined-Q1.txt
    combined-P2.txt
    combined-P1.txt

emoji{🌵..🌶}{🌽..🌾}etc ->
    emoji🌵🌽etc
    emoji🌵🌾etc
    emoji🌶🌽etc
    emoji🌶🌾etc

li{teral ->
    li{teral

rangeless{}empty ->
    rangeless{}empty

rangeless{random}string ->
    rangeless{random}string

stop point not in sequence-{02..10..3}.txt ->
    stop point not in sequence-02.txt
    stop point not in sequence-05.txt
    stop point not in sequence-08.txt

steppedAlphaRising{P..Z..2}.txt ->
    steppedAlphaRisingP.txt
    steppedAlphaRisingR.txt
    steppedAlphaRisingT.txt
    steppedAlphaRisingV.txt
    steppedAlphaRisingX.txt
    steppedAlphaRisingZ.txt

simple {just,give,me,money} list ->
    simple just list
    simple give list
    simple me list
    simple money list

{thatʼs,what,I,want} ->
    thatʼs what I want

emoji {☃,☄}{★,🇺🇸,☆} lists ->
    emoji ☃★ lists
    emoji ☃🇺🇸 lists
    emoji ☃☆ lists
    emoji ☄★ lists
    emoji ☄🇺🇸 lists
    emoji ☄☆ lists

alphanumeric mix{ab7..ac1}.txt ->
    alphanumeric mixab7.txt
    alphanumeric mixab8.txt
    alphanumeric mixab9.txt
    alphanumeric mixac0.txt
    alphanumeric mixac1.txt

alphanumeric mix{0A..0C}.txt ->
    alphanumeric mix0A.txt
    alphanumeric mix0B.txt
    alphanumeric mix0C.txt

mixed terms fail {7..C}.txt ->
    mixed terms fail {7..C}.txt

multi char emoji ranges fail {🌵🌵..🌵🌶} ->
    multi char emoji ranges fail {🌵🌵..🌵🌶}

```


[User]
Brazilian numbers are so called as they were first formally presented at the 1994 math Olympiad *Olimpiada Iberoamericana de Matematica* in Fortaleza, Brazil.

Brazilian numbers are defined as:

The set of positive integer numbers where each number **N** has at least one natural number **B** where **1 < B < N-1** where the representation of **N** in **base B** has all equal digits.

E.G.

:   * **1, 2 & 3** can not be Brazilian; there is no base **B** that satisfies the condition **1 < B < N-1**.
    * **4** is not Brazilian; **4** in **base 2** is **100**. The digits are not all the same.
    * **5** is not Brazilian; **5** in **base 2** is **101**, in **base 3** is **12**. There is no representation where the digits are the same.
    * **6** is not Brazilian; **6** in **base 2** is **110**, in **base 3** is **20**, in **base 4** is **12**. There is no representation where the digits are the same.
    * **7** *is* Brazilian; **7** in **base 2** is **111**. There is at least one representation where the digits are all the same.
    * **8** *is* Brazilian; **8** in **base 3** is **22**. There is at least one representation where the digits are all the same.
    * *and so on...*

All even integers **2P >= 8** are Brazilian because **2P = 2(P-1) + 2**, which is **22** in **base P-1** when **P-1 > 2**. That becomes true when **P >= 4**.
More common: for all all integers **R** and **S**, where **R > 1** and also **S-1 > R**, then **R\*S** is Brazilian because **R\*S = R(S-1) + R**, which is **RR** in **base S-1**
The only problematic numbers are squares of primes, where R = S. Only 11^2 is brazilian to base 3.
All prime integers, that are brazilian, can only have the digit **1**. Otherwise one could factor out the digit, therefore it cannot be a prime number. Mostly in form of **111** to base Integer(sqrt(prime number)). Must be an odd count of **1** to stay odd like primes > 2

Task

Write a routine (function, whatever) to determine if a number is Brazilian and use the routine to show here, on this page;

:   * the first **20** Brazilian numbers;
    * the first **20 odd** Brazilian numbers;
    * the first **20 prime** Brazilian numbers;

See also

:   * **OEIS:A125134 - Brazilian numbers**
    * **OEIS:A257521 - Odd Brazilian numbers**
    * **OEIS:A085104 - Prime Brazilian numbers**

[Assistant]
(formerly Perl 6)

**Works with**: Rakudo version 2019.07.1

```
multi is-Brazilian (Int $n where $n %% 2 && $n > 6) { True }

multi is-Brazilian (Int $n) {
    LOOP: loop (my int $base = 2; $base < $n - 1; ++$base) {
        my $digit;
        for $n.polymod( $base xx * ) {
            $digit //= $_;
            next LOOP if $digit != $_;
        }
        return True
    }
    False
}

my $upto = 20;

put "First $upto Brazilian numbers:\n", (^Inf).hyper.grep( &is-Brazilian )[^$upto];

put "\nFirst $upto odd Brazilian numbers:\n", (^Inf).hyper.map( * * 2 + 1 ).grep( &is-Brazilian )[^$upto];

put "\nFirst $upto prime Brazilian numbers:\n", (^Inf).hyper(:8degree).grep( { .is-prime && .&is-Brazilian } )[^$upto];

```

Output:

```
First 20 Brazilian numbers:
7 8 10 12 13 14 15 16 18 20 21 22 24 26 27 28 30 31 32 33

First 20 odd Brazilian numbers:
7 13 15 21 27 31 33 35 39 43 45 51 55 57 63 65 69 73 75 77

First 20 prime Brazilian numbers:
7 13 31 43 73 127 157 211 241 307 421 463 601 757 1093 1123 1483 1723 2551 2801
```


[User]
Show how to access private or protected members of a class in an object-oriented language from outside an instance of the class, without calling non-private or non-protected members of the class as a proxy.
The intent is to show how a debugger, serializer, or other meta-programming tool might access information that is barred by normal access methods to the object but can nevertheless be accessed from within the language by some provided escape hatch or reflection mechanism.
The intent is specifically not to demonstrate heroic measures such as peeking and poking raw memory.

Note that cheating on your type system is almost universally regarded
as unidiomatic at best, and poor programming practice at worst.
Nonetheless, if your language intentionally maintains a double-standard for OO privacy, here's where you can show it off.

[Assistant]
(formerly Perl 6)

**Works with**: Rakudo version 2015.12

We may call into the MOP (Meta-Object Protocol) via the .^ operator, and the MOP knows all about the object, including any supposedly private bits. We ask for its attributes, find the correct one, and get its value.

```
class Foo {
    has $!shyguy = 42;
}
my Foo $foo .= new;

say $foo.^attributes.first('$!shyguy').get_value($foo);

```

Output:

```
42
```


[User]
**Brilliant numbers** are a subset of semiprime numbers. Specifically, they are numbers that are the product of exactly two prime numbers **that both have the same number of digits when expressed in base 10**.

*Brilliant numbers are useful in cryptography and when testing prime factoring algorithms.*

E.G.

* **3 × 3** (9) is a brilliant number.
* **2 × 7** (14) is a brilliant number.
* **113 × 691** (78083) is a brilliant number.
* **2 × 31** (62) is semiprime, but is **not** a brilliant number (different number of digits in the two factors).

Task

* Find and display the first 100 brilliant numbers.
* For the orders of magnitude 1 through 6, find and show the first brilliant number greater than or equal to the order of magnitude, and, its position in the series (or the count of brilliant numbers up to that point).

Stretch

* Continue for larger orders of magnitude.

See also

* Numbers Aplenty - Brilliant numbers * - Like the task upper Limit 1E201 * OEIS:A078972 - Brilliant numbers: semiprimes whose prime factors have the same number of decimal digits

[Assistant]
1 through 7 are fast. 8 and 9 take a bit longer.

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

# Find an abundance of primes to use to generate brilliants
my %primes = (2..100000).grep( &is-prime ).categorize: { .chars };

# Generate brilliant numbers
my @brilliant = lazy flat (1..*).map: -> $digits {
    sort flat (^%primes{$digits}).race.map: { %primes{$digits}[$_] X× (flat %primes{$digits}[$_ .. *]) }
};

# The task
put "First 100 brilliant numbers:\n" ~ @brilliant[^100].batch(10)».fmt("%4d").join("\n") ~ "\n" ;

for 1 .. 7 -> $oom {
    my $threshold = exp $oom, 10;
    my $key = @brilliant.first: :k, * >= $threshold;
    printf "First >= %13s is %9s in the series: %13s\n", comma($threshold), ordinal-digit(1 + $key, :u), comma @brilliant[$key];
}

```

Output:

```
First 100 brilliant numbers:
   4    6    9   10   14   15   21   25   35   49
 121  143  169  187  209  221  247  253  289  299
 319  323  341  361  377  391  403  407  437  451
 473  481  493  517  527  529  533  551  559  583
 589  611  629  649  667  671  689  697  703  713
 731  737  767  779  781  793  799  803  817  841
 851  869  871  893  899  901  913  923  943  949
 961  979  989 1003 1007 1027 1037 1067 1073 1079
1081 1121 1139 1147 1157 1159 1189 1207 1219 1241
1247 1261 1271 1273 1333 1343 1349 1357 1363 1369

First >=            10 is       4ᵗʰ in the series:            10
First >=           100 is      11ᵗʰ in the series:           121
First >=         1,000 is      74ᵗʰ in the series:         1,003
First >=        10,000 is     242ⁿᵈ in the series:        10,201
First >=       100,000 is    2505ᵗʰ in the series:       100,013
First >=     1,000,000 is   10538ᵗʰ in the series:     1,018,081
First >=    10,000,000 is  124364ᵗʰ in the series:    10,000,043
First >=   100,000,000 is  573929ᵗʰ in the series:   100,140,049
First >= 1,000,000,000 is 7407841ˢᵗ in the series: 1,000,000,081
```


[User]
Objective

Develop a program that identifies and lists all maximal cliques within an undirected graph. A *maximal clique* is a subset of vertices where every two distinct vertices are adjacent (i.e., there's an edge connecting them), and the clique cannot be extended by including any adjacent vertex not already in the clique.

Background

In graph theory, a *clique* is a subset of vertices of an undirected graph such that every two distinct vertices in the clique are connected by an edge. A *maximal clique* is a clique that cannot be extended by adding one more adjacent vertex, meaning it's not a subset of a larger clique.

The Bron-Kerbosch algorithm is a recursive backtracking algorithm used to find all maximal cliques in an undirected graph efficiently. The algorithm is particularly effective due to its use of pivot selection, which reduces the number of recursive calls and improves performance.

Program Functionality

1. **Input Representation:**

* The graph is represented as a list of edges, where each edge is a tuple of two vertices (e.g., `('a', 'b')` indicates an undirected edge between vertices `'a'` and `'b'`).

1. **Graph Construction:**

* Convert the list of edges into an adjacency list using a `HashMap<String, HashSet<String>>`. Each key in the hashmap represents a vertex, and its corresponding hash set contains all adjacent vertices (neighbors).

1. **Bron-Kerbosch Algorithm Implementation:**

* **Sets Used:**
  + *R* (Current Clique): *A set representing the current clique being constructed.*
  + *P* (Potential Candidates): *A set of vertices that can be added to* R *to form a larger clique.*
  + *X* (Excluded Vertices): *A set of vertices that have already been processed and should not be reconsidered for the current clique.*

* **Algorithm Steps:**
  + If both *P* and *X* are empty, and *R* contains more than two vertices, *R* is a maximal clique and is added to the list of cliques.
  + Otherwise, select a *pivot vertex* from the union of *P* and *X* that has the maximum number of neighbors. This pivot helps minimize the number of recursive calls.
  + Iterate over all vertices in *P* that are \*\*not\*\* neighbors of the pivot. For each such vertex:
    - Add the vertex to *R*.
    - Update *P* and *X* to include only those vertices that are neighbors of the added vertex.
    - Recursively call the Bron-Kerbosch function with the updated sets.
    - After recursion, move the vertex from *P* to *X* to mark it as processed.

1. **Output:**

* After executing the algorithm, the program prints all maximal cliques with more than two vertices. Each clique is displayed as a comma-separated list of its constituent vertices.

Example

Given the following edges:

```
('a', 'b'), ('b', 'a'), ('a', 'c'), ('c', 'a'), ('b', 'c'), ('c', 'b'),
('d', 'e'), ('e', 'd'), ('d', 'f'), ('f', 'd'), ('e', 'f'), ('f', 'e')

```

**Expected Output:**

```
a, b, c
d, e, f

```

These outputs represent the two maximal cliques in the graph: one comprising vertices `a`, `b`, and `c`, and the other comprising vertices `d`, `e`, and `f`.

Pseudocode

Below is the pseudocode for the Bron-Kerbosch algorithm with pivoting, closely following the Rust implementation provided earlier.

```
FUNCTION BronKerbosch(R, P, X, G, Cliques)
    // R: Current clique (Set)
    // P: Potential candidates to expand the clique (Set)
    // X: Vertices already processed (Set)
    // G: Graph represented as an adjacency list (Dictionary)
    // Cliques: List to store all maximal cliques (List of Lists)

    IF P is empty AND X is empty THEN
        IF size of R > 2 THEN
            SORT R lexicographically
            ADD R to Cliques
        END IF
        RETURN
    END IF

    // Select a pivot vertex from P ∪ X with the maximum degree
    Pivot := vertex in (P ∪ X) with the highest number of neighbors in G

    // Candidates are vertices in P that are not neighbors of the pivot
    Candidates := P - Neighbors(Pivot)

    FOR EACH vertex v IN Candidates DO
        // New clique including vertex v
        NewR := R ∪ {v}

        // New potential candidates are neighbors of v in P
        Neighbors_v := G[v]
        NewP := P ∩ Neighbors_v

        // New excluded vertices are neighbors of v in X
        NewX := X ∩ Neighbors_v

        // Recursive call with updated sets
        BronKerbosch(NewR, NewP, NewX, G, Cliques)

        // Move vertex v from P to X
        P := P - {v}
        X := X ∪ {v}
    END FOR
END FUNCTION

FUNCTION Main()
    // Define input edges as a list of tuples
    Input := [
        ('a', 'b'), ('b', 'a'), ('a', 'c'), ('c', 'a'),
        ('b', 'c'), ('c', 'b'), ('d', 'e'), ('e', 'd'),
        ('d', 'f'), ('f', 'd'), ('e', 'f'), ('f', 'e')
    ]

    // Build the graph as an adjacency list
    Graph := empty Dictionary
    FOR EACH (src, dest) IN Input DO
        IF src NOT IN Graph THEN
            Graph[src] := empty Set
        END IF
        ADD dest TO Graph[src]
    END FOR

    // Initialize R, P, X
    R := empty Set
    P := set of all vertices in Graph
    X := empty Set

    // Initialize list to store cliques
    Cliques := empty List

    // Execute the Bron-Kerbosch algorithm
    BronKerbosch(R, P, X, Graph, Cliques)

    // Sort the cliques for consistent output
    SORT Cliques lexicographically

    // Print each clique
    FOR EACH Clique IN Cliques DO
        PRINT elements of Clique separated by commas
    END FOR
END FUNCTION

```

[Assistant]
```
# Returns all maximal Cliques as sorted List of Lists.
sub BronKerbosch ( @undirected_edges ) {

    #| Adjacency list of the whole Graph, as immutable hash (Map) of immutable Sets.
    my Map $G = @undirected_edges
                .map({ |( .[0,1], .[1,0] ) })
                .classify( {.[0]}, :as{.[1]} )
                .duckmap( *.Set )
                .Map;

    #| Number of neighbors in G
    my Map $degree = $G.map({ .key => .value.elems }).Map;

    return gather BK();

    sub BK (
        Set     :$R         = Set.new,              #= Current clique
        SetHash :$P is copy = SetHash.new($G.keys), #= Potential candidates to expand the clique
        SetHash :$X is copy = SetHash.new,          #= Vertices already processed
    ) {
        if !$P and !$X {
            take $R.keys.sort.cache if $R.elems > 2;
            return;
        }

        my $Pivot = ($P ∪ $X).max({ $degree{$_} }).key;

        my @Candidates = ( $P (-) $G{$Pivot} ).keys;

        for $G{@Candidates}:kv -> $v, $Neighbors_of_v {

            &?ROUTINE.(     # Recursive call with updated sets
                R => ($R ∪ $v),
                P => ($P ∩ $Neighbors_of_v),
                X => ($X ∩ $Neighbors_of_v),
            );

            # Move vertex v from P to X
            $P{$v} = False;
            $X{$v} = True;
        }
    }
}

say .join(",") for sort BronKerbosch <a-b a-c b-c d-e d-f e-f>».split("-");

```

Output:

```
a,b,c
d,e,f
```


[User]
|  |
| --- |
| This page uses content from **Wikipedia**. The original article was at Brownian\_tree. The list of authors can be seen in the page history. As with Rosetta Code, the text of Wikipedia is available under the GNU FDL. (See links for details on variance) |

Task

Generate and draw a   Brownian Tree.

A Brownian Tree is generated as a result of an initial seed, followed by the interaction of two processes.

1. The initial "seed" is placed somewhere within the field. Where is not particularly important; it could be randomized, or it could be a fixed point.
2. Particles are injected into the field, and are individually given a (typically random) motion pattern.
3. When a particle collides with the seed or tree, its position is fixed, and it's considered to be part of the tree.

Because of the lax rules governing the random nature of the particle's placement and motion, no two resulting trees are really expected to be the same, or even necessarily have the same general shape.

[Assistant]
(formerly Perl 6)

This solution spawns new Particles at a growing square border and displays the Tree every 50 particles and at the end using unicode UPPER/LOWER HALF BLOCK and FULL BLOCK.

**Works with**: Rakudo version 2015.12

```
constant size = 100;
constant particlenum = 1_000;

constant mid = size div 2;

my $spawnradius = 5;
my @map;

sub set($x, $y) {
    @map[$x][$y] = True;
}

sub get($x, $y) {
    return @map[$x][$y] || False;
}

set(mid, mid);
my @blocks = " ","\c[UPPER HALF BLOCK]", "\c[LOWER HALF BLOCK]","\c[FULL BLOCK]";

sub infix:<█>($a, $b) {
    @blocks[$a + 2 * $b]
}

sub display {
    my $start = 0;
    my $end = size;
    say (for $start, $start + 2 ... $end -> $y {
        (for $start..$end -> $x {
            if abs(($x&$y) - mid) < $spawnradius {
                get($x, $y) █ get($x, $y+1);
            } else {
                " "
            }
        }).join
    }).join("\n")
}

for ^particlenum -> $progress {
    my Int $x;
    my Int $y;
    my &reset = {
        repeat {
            ($x, $y) = (mid - $spawnradius..mid + $spawnradius).pick, (mid - $spawnradius, mid + $spawnradius).pick;
            ($x, $y) = ($y, $x) if (True, False).pick();
        } while get($x,$y);
    }
    reset;

    while not get($x-1|$x|$x+1, $y-1|$y|$y+1) {
        $x = ($x-1, $x, $x+1).pick;
        $y = ($y-1, $y, $y+1).pick;
        if (False xx 3, True).pick {
            $x = $x >= mid ?? $x - 1 !! $x + 1;
            $y = $y >= mid ?? $y - 1 !! $y + 1;
        }
        if abs(($x | $y) - mid) > $spawnradius {
            reset;
        }
    }
    set($x,$y);
    if $spawnradius < mid && abs(($x|$y) - mid) > $spawnradius - 5 {
        $spawnradius = $spawnradius + 1;
    }
}

display;

```


[User]
Description

The Brzozowski Algebraic Method is a technique used in automata theory, specifically for constructing the minimal deterministic finite automaton (DFA) from a given nondeterministic finite automaton (NFA). It was introduced by Janusz Brzozowski in 1962 and involves the use of algebraic transformations to simplify and optimize automata.

As the workings of the algorithm are clearly described in the linked article they will not be repeated here.

Task

Implement the Brzozowski Algebraic Method to convert an NFA representation into a regular expression. The implementation should:

1. Take as input:

```
  - A 2D array 'a' representing the transition matrix of the NFA
  - An array 'b' representing the final states

```

2. Include functionality to:

```
  - Handle basic regular expression operations (Empty, Epsilon, Character, Union, Concatenation, Star)
  - Print regular expressions in a readable format
  - Simplify regular expressions using algebraic rules

```

3. Apply the Brzozowski algorithm to:

```
  - Process the transition matrix in reverse order
  - Update transitions using Star and Concatenation operations
  - Combine paths using Union operations
  - Generate a final regular expression representing the language accepted by the NFA

```

4. Include simplification rules for:

```
  - Eliminating redundant unions (e + e → e)
  - Handling identity elements (e·1 → e, 1·e → e)
  - Handling zero elements (e·0 → 0, 0·e → 0)
  - Simplifying star operations (0* → 1, 1* → 1)

```

The implementation should be able to process the given example input and produce both the raw and simplified regular expressions as output.

[Assistant]
**Translation of**: Python

```
# 20241120 Raku programming solution

role RE1 { has $.c }
role RE2 { has ( $.e, $.f ) }

class Empty           { method Str { '0' } }
class Epsilon         { method Str { '1' } }
class Car    does RE1 { method Str { $.c } } # Caractère ?
class Star   does RE1 { method Str { "($.c)*" } }
class Union  does RE2 { method Str { "$.e+$.f" } }
class Concat does RE2 { method Str { "($.e)($.f)" } }

my ($empty, $epsilon) = (Empty, Epsilon)>>.new;

sub simple-re($e is rw) {
   sub do-simple($e) {
      given $e {
         when Union {
            my ($ee,$ef) = ($e.e, $e.f).map: { do-simple $_ };
            if    $ee ~~ $ef   { return $ee }
            elsif $ee ~~ Union { do-simple(Union.new(e => $ee.e, f => Union.new(e => $ee.f, f => $ef))) }
            elsif $ee ~~ Empty { return $ef }
            elsif $ef ~~ Empty { return $ee }
            else  { Union.new: e => $ee, f => $ef }
         }
         when Concat {
            my ($ee,$ef) = ($e.e, $e.f).map: { do-simple $_ };
            if    $ee ~~ Epsilon { return $ef }
            elsif $ef ~~ Epsilon {  return $ee }
            elsif $ee ~~ Empty || $ef ~~ Empty { return Empty }
            elsif $ee ~~ Concat { do-simple(Concat.new(e => $ee.e, f => Concat.new(e => $ee.f, f => $ef))) }
            else { Concat.new: e => $ee, f => $ef }
         }
         when Star {
            given do-simple($e.c) {
               $_ ~~ Empty | Epsilon ?? return Epsilon !! Star.new: c => $_
            }
         }
         default { $e }
      }
   }
   my $prev = '';
   until $e === $prev or $e.Str eq $prev { ($prev, $e) = $e, do-simple($e) }
   return $e;
}

sub brzozowski(@a, @b) {
   for @a.elems - 1 ... 0 -> \n {
      @b[n] = Concat.new(e => Star.new(c => @a[n;n]), f => @b[n]);
      for ^n -> \j {
         @a[n;j] = Concat.new(e => Star.new(c => @a[n;n]), f => @a[n;j]);
      }
      for ^n -> \i {
         @b[i] = Union.new(e => @b[i], f => Concat.new(e => @a[i;n], f => @b[n]));
         for ^n -> \j {
            @a[i;j] = Union.new(e => @a[i;j], f => Concat.new(e => @a[i;n], f => @a[n;j]));
         }
      }
      for ^n -> \i { @a[i;n] = $empty }
   }
   return @b[0]
}

my @a = [
    [$empty, Car.new(c => 'a'), Car.new(c => 'b')],
    [Car.new(c => 'b'), $empty, Car.new(c => 'a')],
    [Car.new(c => 'a'), Car.new(c => 'b'), $empty],
];
my @b = [$epsilon, $empty, $empty];

say ( my $re = brzozowski(@a, @b) ).Str;
say simple-re($re).Str;

```

You may Attempt This Online!


[User]
Bulls and Cows   is an old game played with pencil and paper that was later implemented using computers.

Task

Create a four digit random number from the digits   **1**   to   **9**,   without duplication.

The program should:

:   :   :   :   :   :   * ask for guesses to this number
                        * reject guesses that are malformed
                        * print the score for the guess

The score is computed as:

1. The player wins if the guess is the same as the randomly chosen number, and the program ends.
2. A score of one **bull** is accumulated for each digit in the guess that equals the corresponding digit in the randomly chosen initial number.
3. A score of one **cow** is accumulated for each digit in the guess that also appears in the randomly chosen number, but in the wrong position.

Related tasks

* Bulls and cows/Player
* Guess the number
* Guess the number/With Feedback
* Mastermind

[Assistant]
(formerly Perl 6)

**Translation of**: Python

**Works with**: Rakudo version 2015.12

```
my $size = 4;
my @secret = pick $size, '1' .. '9';

for 1..* -> $guesses {
    my @guess;
    loop {
        @guess = (prompt("Guess $guesses: ") // exit).comb;
        last if @guess == $size and
            all(@guess) eq one(@guess) & any('1' .. '9');
        say 'Malformed guess; try again.';
    }
    my ($bulls, $cows) = 0, 0;
    for ^$size {
        when @guess[$_] eq @secret[$_] { ++$bulls; }
        when @guess[$_] eq any @secret { ++$cows; }
    }
    last if $bulls == $size;
    say "$bulls bulls, $cows cows.";
}

say 'A winner is you!';

```


[User]
Task

Write a *player* of the Bulls and Cows game, rather than a scorer. The player should give intermediate answers that respect the scores to previous attempts.

One method is to generate a list of all possible numbers that could be the answer, then to prune the list by keeping only those numbers that would give an equivalent score to how your last guess was scored. Your next guess can be any number from the pruned list.
Either you guess correctly or run out of numbers to guess, which indicates a problem with the scoring.

Related tasks

* Bulls and cows
* Guess the number
* Guess the number/With Feedback (Player)

[Assistant]
(formerly Perl 6)

**Works with**: Rakudo version 2018.12

**Translation of**: Perl

```
# we use the [] reduction meta operator along with the Cartesian Product
# operator X to create the Cartesian Product of four times [1..9] and then get
# all the elements where the number of unique digits is four.
my @candidates = ([X] [1..9] xx 4).grep: *.unique == 4;

repeat {
	my $guess = @candidates.pick;
	my ($bulls, $cows) = read-score;
	@candidates .= grep: &score-correct;

	# note how we declare our two subroutines within the repeat block. This
	# limits the scope in which the routines are known to the scope in which
	# they are needed and saves us a lot of arguments to our two routines.
	sub score-correct($a) {
		my $exact = [+] $a >>==<< $guess;

		# number of elements of $a that match any element of $b
		my $loose = +$a.grep: any @$guess;

		return $bulls == $exact && $cows == $loose - $exact;
	}

	sub read-score() {
		loop {
			my $score = prompt "My guess: {$guess.join}.\n";

			if $score ~~ m:s/^ $<bulls>=(\d) $<cows>=(\d) $/
				and $<bulls> + $<cows> <= 4 {
				return +$<bulls>, +$<cows>;
			}

			say "Please specify the number of bulls and cows";
		}
	}
} while @candidates > 1;

say @candidates
	?? "Your secret number is {@candidates[0].join}!"
	!! "I think you made a mistake with your scoring.";

```

Output:

```
My guess: 4235.
2 1
My guess: 1435.
2 1
My guess: 1245.
2 1
Your secret number is 1234!
```


[User]
|  |
| --- |
| This page uses content from **Wikipedia**. The original article was at Burrows–Wheeler\_transform. The list of authors can be seen in the page history. As with Rosetta Code, the text of Wikipedia is available under the GNU FDL. (See links for details on variance) |

The Burrows–Wheeler transform (BWT, also called block-sorting compression) rearranges a character string into runs of similar characters.

This is useful for compression, since it tends to be easy to compress a string that has runs of repeated characters by techniques such as move-to-front transform and run-length encoding.

More importantly, the transformation is reversible, without needing to store any additional data.

The BWT is thus a "free" method of improving the efficiency of text compression algorithms, costing only some extra computation.

Source: Burrows–Wheeler transform

[Assistant]
(formerly Perl 6)

**Works with**: Rakudo version 2018.06

```
# STX can be any character that doesn't appear in the text.
# Using a visible character here for ease of viewing.

constant \STX = '👍';

# Burrows-Wheeler transform
sub transform (Str $s is copy) {
    note "String can't contain STX character." and exit if $s.contains: STX;
    $s = STX ~ $s;
    (^$s.chars).map({ $s.comb.list.rotate: $_ }).sort[*;*-1].join
}

# Burrows-Wheeler inverse transform
sub ɯɹoɟsuɐɹʇ (Str $s) {
    my @t = $s.comb.sort;
    @t = ($s.comb Z~ @t).sort for 1..^$s.chars;
    @t.first( *.ends-with: STX ).chop
}

# TESTING
for |<BANANA dogwood SIX.MIXED.PIXIES.SIFT.SIXTY.PIXIE.DUST.BOXES>,
    'TO BE OR NOT TO BE OR WANT TO BE OR NOT?', "Oops{STX}"
    -> $phrase {
    say 'Original:            ', $phrase;
    say 'Transformed:         ', transform $phrase;
    say 'Inverse transformed: ', ɯɹoɟsuɐɹʇ transform $phrase;
    say '';
}

```

Output:

```
Original:            BANANA
Transformed:         BNN👍AAA
Inverse transformed: BANANA

Original:            dogwood
Transformed:         👍ooodwgd
Inverse transformed: dogwood

Original:            SIX.MIXED.PIXIES.SIFT.SIXTY.PIXIE.DUST.BOXES
Transformed:         TEXYDST.E.IXIXIXXSSMPPS.B..E.👍.UESFXDIIOIIITS
Inverse transformed: SIX.MIXED.PIXIES.SIFT.SIXTY.PIXIE.DUST.BOXES

Original:            TO BE OR NOT TO BE OR WANT TO BE OR NOT?
Transformed:         OOORREEETTRTW   BBB  ATTT   NNOOONOO👍   ?
Inverse transformed: TO BE OR NOT TO BE OR WANT TO BE OR NOT?

Original:            Oops👍
String can't contain STX character.
```


[User]
You are given two planar quadratic Bézier curves, having control points

(
−
1
,
0
)
,
(
0
,
10
)
,
(
1
,
0
)
{\displaystyle {\displaystyle (-1,0),(0,10),(1,0)}}
 and

(
2
,
1
)
,
(
−
8
,
2
)
,
(
2
,
3
)
{\displaystyle {\displaystyle (2,1),(-8,2),(2,3)}}
, respectively. They are parabolas intersecting at four points, as shown in the following diagram:

The task is to write a program that finds all four intersection points and prints their

(
x
,
y
)
{\displaystyle {\displaystyle (x,y)}}
 coordinates. You may use any algorithm you know of or can think of, including any of those that others have used.

### See also

* Bitmap/Bézier curves/Quadratic
* Steffensen's method

[Assistant]
**Translation of**: Go

```
# 20231025 Raku programming solution

class Point { has ($.x, $.y) is rw is default(0) }

class QuadSpline { has ($.c0, $.c1, $.c2) is rw is default(0) }

class QuadCurve { has QuadSpline ($.x, $.y) is rw }

class Workset { has QuadCurve ($.p, $.q) }

sub subdivideQuadSpline($q, $t) {
   my $s = 1.0 - $t;
   my ($c0,$c1,$c2) = do given $q { .c0, .c1, .c2 };
   my $u_c1 = $s*$c0 + $t*$c1;
   my $v_c1 = $s*$c1 + $t*$c2;
   my $u_c2 = $s*$u_c1 + $t*$v_c1;
   return ($c0, $u_c1, $u_c2), ($u_c2, $v_c1, $c2)
}

sub subdivideQuadCurve($q, $t, $u is rw, $v is rw) {
   with (subdivideQuadSpline($q.x,$t),subdivideQuadSpline($q.y,$t))».List.flat {
      $u=QuadCurve.new(x => QuadSpline.new(c0 => .[0],c1 => .[1],c2 => .[2]),
                       y => QuadSpline.new(c0 => .[6],c1 => .[7],c2 => .[8]));
      $v=QuadCurve.new(x => QuadSpline.new(c0 => .[3],c1 => .[4],c2 => .[5]),
                       y => QuadSpline.new(c0 => .[9],c1 => .[10],c2 => .[11]))
   }
}

sub seemsToBeDuplicate(@intersects, $xy, $spacing) {
   my $seemsToBeDup = False;
   for @intersects {
      $seemsToBeDup = abs(.x - $xy.x) < $spacing && abs(.y - $xy.y) < $spacing;
      last if $seemsToBeDup;
   }
   return $seemsToBeDup;
}

sub rectsOverlap($xa0, $ya0, $xa1, $ya1, $xb0, $yb0, $xb1, $yb1) {
   return $xb0 <= $xa1 && $xa0 <= $xb1 && $yb0 <= $ya1 && $ya0 <= $yb1
}

sub testIntersect($p,$q,$tol,$exclude is rw,$accept is rw,$intersect is rw) {
   my $pxmin = min($p.x.c0, $p.x.c1, $p.x.c2);
   my $pymin = min($p.y.c0, $p.y.c1, $p.y.c2);
   my $pxmax = max($p.x.c0, $p.x.c1, $p.x.c2);
   my $pymax = max($p.y.c0, $p.y.c1, $p.y.c2);
   my $qxmin = min($q.x.c0, $q.x.c1, $q.x.c2);
   my $qymin = min($q.y.c0, $q.y.c1, $q.y.c2);
   my $qxmax = max($q.x.c0, $q.x.c1, $q.x.c2);
   my $qymax = max($q.y.c0, $q.y.c1, $q.y.c2);
   ($exclude, $accept) = True, False;

   if rectsOverlap($pxmin,$pymin,$pxmax,$pymax,$qxmin,$qymin,$qxmax,$qymax) {
      $exclude = False;
      my ($xmin,$xmax) = max($pxmin, $qxmin), min($pxmax, $pxmax);
      if ($xmax < $xmin) { die "Assertion failure: $xmax < $xmin\n" }
      my ($ymin,$ymax) = max($pymin, $qymin), min($pymax, $qymax);
      if ($ymax < $ymin) { die "Assertion failure: $ymax < $ymin\n" }
      if $xmax - $xmin <= $tol and $ymax - $ymin <= $tol {
         $accept = True;
         given $intersect { (.x, .y) = 0.5 X* $xmin+$xmax, $ymin+$ymax }
      }
   }
}

sub find-intersects($p, $q, $tol, $spacing) {
   my Point @intersects;
   my @workload = Workset.new(p => $p, q => $q);

   while my $work = @workload.pop {
      my ($intersect,$exclude,$accept) = Point.new, False, False;
      testIntersect($work.p, $work.q, $tol, $exclude, $accept, $intersect);
      if $accept {
         unless seemsToBeDuplicate(@intersects, $intersect, $spacing) {
            @intersects.push: $intersect;
         }
      } elsif not $exclude {
         my QuadCurve ($p0, $p1, $q0, $q1);
         subdivideQuadCurve($work.p, 0.5, $p0, $p1);
         subdivideQuadCurve($work.q, 0.5, $q0, $q1);
         for $p0, $p1 X $q0, $q1 {
            @workload.push: Workset.new(p => .[0], q => .[1])
         }
      }
   }
   return @intersects;
}

my $p = QuadCurve.new( x => QuadSpline.new(c0 => -1.0,c1 =>  0.0,c2 => 1.0),
                       y => QuadSpline.new(c0 =>  0.0,c1 => 10.0,c2 => 0.0));
my $q = QuadCurve.new( x => QuadSpline.new(c0 =>  2.0,c1 => -8.0,c2 => 2.0),
                       y => QuadSpline.new(c0 =>  1.0,c1 =>  2.0,c2 => 3.0));
my $spacing = ( my $tol = 0.0000001 ) * 10;
.say for find-intersects($p, $q, $tol, $spacing);

```

You may Attempt This Online!


[User]
Task

Implement a Caesar cipher, both encoding and decoding.
The key is an integer from 1 to 25.

This cipher rotates (either towards left or right) the letters of the alphabet (A to Z).

The encoding replaces each letter with the 1st to 25th next letter in the alphabet (wrapping Z to A).

So key 2 encrypts "HI" to "JK", but key 20 encrypts "HI" to "BC".

This simple "mono-alphabetic substitution cipher" provides almost no security, because an attacker who has the encoded message can either use frequency analysis to guess the key, or just try all 25 keys.

Caesar cipher is identical to Vigenère cipher with a key of length 1.
Also, Rot-13 is identical to Caesar cipher with key 13.

Related tasks

* Rot-13
* Substitution Cipher
* Vigenère Cipher/Cryptanalysis

[Assistant]
(formerly Perl 6)

**Works with**: Rakudo version 2015.12

```
my @alpha = 'A' .. 'Z';
sub encrypt ( $key where 1..25, $plaintext ) {
    $plaintext.trans( @alpha Z=> @alpha.rotate($key) );
}
sub decrypt ( $key where 1..25, $cyphertext ) {
    $cyphertext.trans( @alpha.rotate($key) Z=> @alpha );
}

my $original = 'THE FIVE BOXING WIZARDS JUMP QUICKLY';
my $en = encrypt( 13, $original );
my $de = decrypt( 13, $en );

.say for $original, $en, $de;

say 'OK' if $original eq all( map { .&decrypt(.&encrypt($original)) }, 1..25 );
```

Output:

```
THE FIVE BOXING WIZARDS JUMP QUICKLY
GUR SVIR OBKVAT JVMNEQF WHZC DHVPXYL
THE FIVE BOXING WIZARDS JUMP QUICKLY
OK
```


[User]
Task

Calculate the value of   *e*.

(*e*   is also known as   *Euler's number*   and   *Napier's constant*.)

See details: Calculating the value of e

[Assistant]
(formerly Perl 6)

**Works with**: Rakudo version 2023.09

```
# If you need high precision: Sum of a Taylor series method.
# Adjust the terms parameter to suit. Theoretically the
# terms could be ∞. Practically, calculating an infinite
# series takes an awfully long time so limit to 500.

constant 𝑒 = [\+] flat 1, [\/] 1.FatRat..*;

.say for 𝑒[500].comb(80);

say '';

# Or, if you don't need high precision, it's a built-in.
say e;

```

Output:

```
2.718281828459045235360287471352662497757247093699959574966967627724076630353547
59457138217852516642742746639193200305992181741359662904357290033429526059563073
81323286279434907632338298807531952510190115738341879307021540891499348841675092
44761460668082264800168477411853742345442437107539077744992069551702761838606261
33138458300075204493382656029760673711320070932870912744374704723069697720931014
16928368190255151086574637721112523897844250569536967707854499699679468644549059
87931636889230098793127736178215424999229576351482208269895193668033182528869398
49646510582093923982948879332036250944311730123819706841614039701983767932068328
23764648042953118023287825098194558153017567173613320698112509961818815930416903
51598888519345807273866738589422879228499892086805825749279610484198444363463244
96848756023362482704197862320900216099023530436994184914631409343173814364054625
31520961836908887070167683964243781405927145635490613031072085103837505101157477
04171898610687396965521267154688957035035402123407849819334321068170121005627880
23519303322474501585390473041995777709350366041699732972508868769664035557071622
68447162560798827

2.718281828459045
```


[User]
Create a routine that will generate a text calendar for any year.
Test the calendar by generating a calendar for the year 1969, on a device of the time.
Choose one of the following devices:

* A line printer with a width of 132 characters.
* An IBM 3278 model 4 terminal (80×43 display with accented characters). Target formatting the months of the year to fit nicely across the 80 character width screen. Restrict number of lines in test output to 43.

(Ideally, the program will generate well-formatted calendars for any page width from 20 characters up.)

Kudos (κῦδος) for routines that also transition from Julian to Gregorian calendar.

This task is inspired by Real Programmers Don't Use PASCAL by Ed Post, Datamation, volume 29 number 7, July 1983.

```
THE REAL PROGRAMMER'S NATURAL HABITAT
"Taped to the wall is a line-printer Snoopy calender for the year 1969."

```

For further Kudos see task CALENDAR, where all code is to be in UPPERCASE.

For economy of size, do not actually include Snoopy generation in either the code or the output, instead just output a place-holder.

See Also
:   * Snoopy calendar 1969-2025 Marcel van der Veer - The deck is credited as being one of the first FOSS programs.

Related task
:   * Five weekends

[Assistant]
(formerly Perl 6)

```
my $months-per-row = 3;
my @weekday-names  = <Mo Tu We Th Fr Sa Su>;
my @month-names    = <Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec>;

my Int() $year = @*ARGS.shift || 1969;
say fmt-year($year);

sub fmt-year ($year) {
    my @month-strs;
    @month-strs[$_] = [fmt-month($year, $_).lines] for 1 .. 12;
    my @C = ' ' x 30 ~ $year, '';
    for 1, 1+$months-per-row ... 12 -> $month {
        while @month-strs[$month] {
            for ^$months-per-row -> $column {
                @C[*-1] ~= @month-strs[$month+$column].shift ~ ' ' x 3 if @month-strs[$month+$column];
            }
            @C.push: '';
        }
        @C.push: '';
    }
    @C.join: "\n";
}

sub fmt-month ($year, $month) {
    my $date = Date.new($year,$month,1);
    @month-names[$month-1].fmt("%-20s\n") ~ @weekday-names ~ "\n" ~
    (('  ' xx $date.day-of-week - 1), (1..$date.days-in-month)».fmt('%2d')).flat.rotor(7, :partial).join("\n") ~
    (' ' if $_ < 7) ~ ('  ' xx 7-$_).join(' ') given Date.new($year, $month, $date.days-in-month).day-of-week;
}

```


[User]
Task

Provide an algorithm as per the Calendar task, except the entire code for the algorithm must be presented   *entirely without lowercase*.

Also - as per many 1969 era line printers - format the calendar to nicely fill a page that is 132 characters wide.

(Hint: manually convert the code from the Calendar task to all UPPERCASE)

This task also is inspired by Real Programmers Don't Use PASCAL by Ed Post, Datamation, volume 29 number 7, July 1983.

```
THE REAL PROGRAMMER'S NATURAL HABITAT
"Taped to the wall is a line-printer Snoopy calender for the year 1969."

```

Moreover this task is further inspired by the *long lost* corollary article titled:

```
"Real programmers think in UPPERCASE"!

```

Note: Whereas today we *only* need to worry about ASCII, UTF-8, UTF-16, UTF-32, UTF-7 and UTF-EBCDIC encodings, in the 1960s having code in UPPERCASE was often mandatory as characters were often stuffed into 36-bit words as 6 lots of 6-bit characters. More extreme words sizes include 60-bit words of the CDC 6000 series computers. The Soviets even had a national character set that was inclusive of all
4-bit,
5-bit,
6-bit &
7-bit depending on how the file was opened... **And** one rogue Soviet university went further and built a 1.5-bit based computer.

Of course... as us Boomers have turned into Geezers we have become HARD OF HEARING,
and suffer from chronic Presbyopia, hence programming in UPPERCASE
is less to do with computer architecture and more to do with practically. :-)

For economy of size, do not actually include Snoopy generation
in either the code or the output, instead just output a place-holder.

FYI: a nice ASCII art file of Snoopy can be found at textfiles.com. Save with a .txt extension.

**Trivia:** The terms uppercase and lowercase date back to the early days of the mechanical printing press. Individual metal alloy casts of each needed letter, or punctuation symbol, were meticulously added to a press block, by hand, before rolling out copies of a page. These metal casts were stored and organized in wooden cases. The more often needed *minuscule* letters were placed closer to hand, in the lower cases of the work bench. The less often needed, capitalized, *majuscule* letters, ended up in the harder to reach upper cases.

[Assistant]
(formerly Perl 6)
Uppercase is no challenge, who needs letters at all?
[Requires the year to be supplied as a command-line argument, and Unixish *cal* command.]

```
$_="\0".."~";<
115 97 121 32 34 91 73 78 83 69 82 84 32 83 78 79 79 80 89 32 72 69 82 69 93 34
59 114 117 110 32 60 99 97 108 62 44 64 42 65 82 71 83 91 48 93 47 47 49 57 54 57
>."$_[99]$_[104]$_[114]$_[115]"()."$_[69]$_[86]$_[65]$_[76]"()

```


[User]
The **Calkin-Wilf sequence** contains every nonnegative rational number exactly once.

It can be calculated recursively as follows:

```
       a1   =  1
       an+1  =  1/(2⌊an⌋+1-an) for n > 1

```

Task part 1

* Show on this page terms 1 through 20 of the Calkin-Wilf sequence.

To avoid floating point error, you may want to use a rational number data type.

It is also possible, given a non-negative rational number, to determine where it appears in the sequence without calculating the sequence. The procedure is to get the continued fraction representation of the rational and use it as the run-length encoding of the binary representation of the term number, beginning from the end of the continued fraction.
It only works if the number of terms in the continued fraction is odd- use either of the two equivalent representations to achieve this:

```
       [a0; a1, a2, ..., an]  =  [a0; a1, a2 ,..., an-1, 1]

```

Example

The fraction   **9/4**   has odd continued fraction representation      2; 3, 1,     giving a binary representation of   **100011**,

which means   **9/4**   appears as the   **35th**   term of the sequence.

Task part 2

* Find the position of the number   **83116****/****51639**   in the Calkin-Wilf sequence.

Related tasks
:   * Fusc sequence.

See also

* Wikipedia entry: Calkin-Wilf tree
* Continued fraction
* Continued fraction/Arithmetic/Construct from rational number

[Assistant]
In Raku, arrays are indexed from 0. The Calkin-Wilf sequence does not have a term defined at 0.

This implementation includes a bogus undefined value at position 0, having the bogus first term shifts the indices up by one, making the ordinal position and index match. Useful due to how reversibility function works.

```
my @calkin-wilf = Any, 1, {1 / (.Int × 2 + 1 - $_)} … *;

# Rational to Calkin-Wilf index
sub r2cw (Rat $rat) { :2( join '', flat (flat (1,0) xx *) Zxx reverse r2cf $rat ) }

# The task

say "First twenty terms of the Calkin-Wilf sequence: ",
    @calkin-wilf[1..20]».&prat.join: ', ';

say "\n99991st through 100000th: ",
    (my @tests = @calkin-wilf[99_991 .. 100_000])».&prat.join: ', ';

say "\nCheck reversibility: ", @tests».Rat».&r2cw.join: ', ';

say "\n83116/51639 is at index: ", r2cw 83116/51639;

# Helper subs
sub r2cf (Rat $rat is copy) { # Rational to continued fraction
    gather loop {
	    $rat -= take $rat.floor;
	    last if !$rat;
	    $rat = 1 / $rat;
    }
}

sub prat ($num) { # pretty Rat
    return $num unless $num ~~ Rat|FatRat;
    return $num.numerator if $num.denominator == 1;
    $num.nude.join: '/';
}

```

Output:

```
First twenty terms of the Calkin-Wilf sequence: 1, 1/2, 2, 1/3, 3/2, 2/3, 3, 1/4, 4/3, 3/5, 5/2, 2/5, 5/3, 3/4, 4, 1/5, 5/4, 4/7, 7/3, 3/8

99991st through 100000th: 1085/303, 303/1036, 1036/733, 733/1163, 1163/430, 430/987, 987/557, 557/684, 684/127, 127/713

Check reversibility: 99991, 99992, 99993, 99994, 99995, 99996, 99997, 99998, 99999, 100000

83116/51639 is at index: 123456789
```


[User]
Task

Show how a foreign language function can be called from the language.

As an example, consider calling functions defined in the C language. Create a string containing "Hello World!" of the string type typical to the language. Pass the string content to C's `strdup`. The content can be copied if necessary. Get the result from `strdup` and print it using language means. Do not forget to free the result of `strdup` (allocated in the heap).

Notes

* It is not mandated if the C run-time library is to be loaded statically or dynamically. You are free to use either way.
* C++ and C solutions can take some other language to communicate with.
* It is *not* mandatory to use `strdup`, especially if the foreign function interface being demonstrated makes that uninformative.

See also

* Use another language to call a function

[Assistant]
(formerly Perl 6)

**Works with**: rakudo version 2016.07

```
use NativeCall;

sub strdup(Str $s --> Pointer) is native {*}
sub puts(Pointer $p --> int32) is native {*}
sub free(Pointer $p --> int32) is native {*}

my $p = strdup("Success!");
say 'puts returns ', puts($p);
say 'free returns ', free($p);

```

Output:

```
Success!
puts returns 9
free returns 0
```


[User]
Task

Demonstrate the different syntax and semantics provided for calling a function.

This may include:

:   * Calling a function that requires no arguments
    * Calling a function with a fixed number of arguments
    * Calling a function with optional arguments
    * Calling a function with a variable number of arguments
    * Calling a function with named arguments
    * Using a function in statement context
    * Using a function in first-class context within an expression
    * Obtaining the return value of a function
    * Distinguishing built-in functions and user-defined functions
    * Distinguishing subroutines and functions
    * Stating whether arguments are passed by value or by reference
    * Is partial application possible and how

This task is *not* about defining functions.

[Assistant]
(formerly Perl 6)

### Theory

Fundamentally, nearly everything you do in Raku is a function call if you look hard enough.
At the lowest level, a function call merely requires a reference to any
kind of invokable object, and a call to its postcircumfix:<( )> method.
However, there are various forms of sugar and indirection that you
can use to express these function calls differently. In particular,
operators are all just sugar for function calls.

Calling a function that requires no arguments:

```
foo               # as list operator
foo()             # as function
foo.()            # as function, explicit postfix form
$ref()            # as object invocation
$ref.()           # as object invocation, explicit postfix
&foo()            # as object invocation
&foo.()           # as object invocation, explicit postfix
::($name)()       # as symbolic ref
```

Calling a function with exactly one argument:

```
foo 1             # as list operator
foo(1)            # as named function
foo.(1)           # as named function, explicit postfix
$ref(1)           # as object invocation (must be hard ref)
$ref.(1)          # as object invocation, explicit postfix
1.$foo            # as pseudo-method meaning $foo(1) (hard ref only)
1.$foo()          # as pseudo-method meaning $foo(1) (hard ref only)
1.&foo            # as pseudo-method meaning &foo(1) (is hard foo)
1.&foo()          # as pseudo-method meaning &foo(1) (is hard foo)
1.foo             # as method via dispatcher
1.foo()           # as method via dispatcher
1."$name"()       # as method via dispatcher, symbolic
+1                # as operator to prefix:<+> function
```

Method calls are included here because they do eventually dispatch to a true
function via a dispatcher. However, the dispatcher in question is not going
to dispatch to the same set of functions that a function call of that name
would invoke. That's why there's a dispatcher, after all. Methods are declared
with a different keyword, method, in Raku, but all that does is
install the actual function into a metaclass. Once it's there, it's merely
a function that expects its first argument to be the invocant object. Hence we
feel justified in including method call syntax as a form of indirect function call.

Operators like + also go through a dispatcher, but in this case it is
multiply dispatched to all lexically scoped candidates for the function. Hence
the candidate list is bound early, and the function itself can be bound early
if the type is known. Raku maintains a clear distinction between early-bound
linguistic constructs that force Perlish semantics, and late-bound OO dispatch
that puts the objects and/or classes in charge of semantics. (In any case, &foo,
though being a hard ref to the function named "foo", may actually be a ref to
a dispatcher to a list of candidates that, when called, makes all the candidates behave as a single unit.)

Calling a function with exactly two arguments:

```
foo 1,2           # as list operator
foo(1,2)          # as named function
foo.(1,2)         # as named function, explicit postfix
$ref(1,2)         # as object invocation (must be hard ref)
$ref.(1,2)        # as object invocation, explicit postfix
1.$foo: 2         # as pseudo-method meaning $foo(1,2) (hard ref only)
1.$foo(2)         # as pseudo-method meaning $foo(1,2) (hard ref only)
1.&foo: 2         # as pseudo-method meaning &foo(1,2) (is hard foo)
1.&foo(2)         # as pseudo-method meaning &foo(1,2) (is hard foo)
1.foo: 2          # as method via dispatcher
1.foo(2)          # as method via dispatcher
1."$name"(2)      # as method via dispatcher, symbolic
1 + 2             # as operator to infix:<+> function
```

Optional arguments don't look any different from normal arguments.
The optionality is all on the binding end.

Calling a function with a variable number of arguments (varargs):

```
foo @args         # as list operator
foo(@args)        # as named function
foo.(@args)       # as named function, explicit postfix
$ref(@args)       # as object invocation (must be hard ref)
$ref.(@args)      # as object invocation, explicit postfix
1.$foo: @args     # as pseudo-method meaning $foo(1,@args) (hard ref)
1.$foo(@args)     # as pseudo-method meaning $foo(1,@args) (hard ref)
1.&foo: @args     # as pseudo-method meaning &foo(1,@args)
1.&foo(@args)     # as pseudo-method meaning &foo(1,@args)
1.foo: @args      # as method via dispatcher
1.foo(@args)      # as method via dispatcher
1."$name"(@args)  # as method via dispatcher, symbolic
@args X @blargs   # as list infix operator to infix:<X>
```

Note: whether a function may actually be called with a variable number of arguments depends entirely
on whether a signature accepts a list at that position in the argument list, but
describing that is not the purpose of this task. Suffice to say that we assume here that the
foo function is declared with a signature of the form (\*@params). The calls above might be interpreted as having a single array argument if the signature indicates a normal parameter instead of a variadic one. What you cannot do in Raku (unlike Perl 5) is pass an array as several fixed arguments. By default it must either represent a single argument, or be part of a variadic list. You can force the extra level of argument list interpolation using a prefix | however:

```
my @args = 1,2,3;
foo(|@args);  # equivalent to foo(1,2,3)
```

Calling a function with named arguments:

```
foo :a, :b(4), :!c, d => "stuff"
foo(:a, :b(4), :!c, d => "stuff")
```

...and so on. Operators may also be called with named arguments, but only
colon adverbials are allowed:

```
1 + 1 :a :b(4) :!c :d("stuff")   # calls infix:<+>(1,1,:a, :b(4), :!c, d => "stuff")
```

Using a function in statement context:

```
foo(); bar(); baz();    # evaluate for side effects
```

Using a function in first class context within an expression:

```
1 / find-a-func(1,2,3)(4,5,6) ** 2;
```

Obtaining the return value of a function:

```
my $result = somefunc(1,2,3) + 2;
```

There is no difference between calling builtins and user-defined functions and operators (or
even control stuctures). This was a major design goal of Raku, and apart from a very few
low-level primitives, all of Raku can be written in Raku.

There is no difference between calling subroutines and functions in Raku, other than that
calling a function in void context that has no side effects is likely to get you a "Useless use of..." warning.
And, of course, the fact that pure functions can participate in more optimizations such as constant folding.

By default, arguments are passed readonly, which allows the implementation to decide whether pass-by-reference or pass-by-value is more efficient on a case-by-case basis. Explicit lvalue, reference, or copy semantics may be requested on a parameter-by-parameter basis, and the entire argument list may be processed raw if that level of control is needed.

### Practice

Demonstrating each of the above-mentioned function calls with actual running code, along with the various extra definitions required to make them work (in certain cases). Arguments are checked, and function name / run-sequence number are displayed upon success.

```
{
state $n;

multi f ()          {                                    print ' f' ~ ++$n }
multi f ($a)        { die if 1  != $a;                   print ' f' ~ ++$n }
multi f ($a,$b)     { die if 3  != $a+$b;                print ' f' ~ ++$n }
multi f (@a)        { die if @a != [2,3,4];              print ' f' ~ ++$n }
multi f ($a,$b,$c)  { die if 2  != $a || 4 != $c;        print ' f' ~ ++$n }
sub   g ($a,*@b)    { die if @b != [2,3,4] || 1 != $a;   print ' g' ~ ++$n }

my \i = ->          {                                    print ' i' ~ ++$n }
my \l = -> $a       { die if 1 != $a;                    print ' l' ~ ++$n }
my \m = -> $a,$b    { die if 1 != $a || 2 != $b;         print ' m' ~ ++$n }
my \n = -> @a       { die if @a != [2,3,4];              print ' n' ~ ++$n }

Int.^add_method( 'j', method ()
                    { die if 1 != self;                  print ' j' ~ ++$n } );
Int.^add_method( 'k', method ($a)
                    { die if 1 != self || 2 != $a;       print ' k' ~ ++$n } );
Int.^add_method( 'h', method (@a)
                    { die if @a != [2,3,4] || 1 != self; print ' h' ~ ++$n } );

my $ref   =  &f;  # soft ref
my $f    :=  &f;  # hard ref
my $g    :=  &g;  # hard ref
my $f-sym = '&f'; # symbolic ref
my $g-sym = '&g'; # symbolic ref
my $j-sym =  'j'; # symbolic ref
my $k-sym =  'k'; # symbolic ref
my $h-sym =  'h'; # symbolic ref

# Calling a function with no arguments:

f;            #  1  as list operator
f();          #  2  as function
i.();         #  3  as function, explicit postfix form  # defined via pointy-block
$ref();       #  4  as object invocation
$ref.();      #  5  as object invocation, explicit postfix
&f();         #  6  as object invocation
&f.();        #  7  as object invocation, explicit postfix
::($f-sym)(); #  8  as symbolic ref

# Calling a function with exactly one argument:

f 1;          #   9  as list operator
f(1);         #  10  as named function
l.(1);        #  11  as named function, explicit postfix  # defined via pointy-block
$f(1);        #  12  as object invocation (must be hard ref)
$ref.(1);     #  13  as object invocation, explicit postfix
1.$f;         #  14  as pseudo-method meaning $f(1) (hard ref only)
1.$f();       #  15  as pseudo-method meaning $f(1) (hard ref only)
1.&f;         #  16  as pseudo-method meaning &f(1) (is hard f)
1.&f();       #  17  as pseudo-method meaning &f(1) (is hard f)
1.j;          #  18  as method via dispatcher             # requires custom method, via 'Int.^add_method'
1.j();        #  19  as method via dispatcher
1."$j-sym"(); #  20  as method via dispatcher, symbolic

# Calling a function with exactly two arguments:

f 1,2;         #  21  as list operator
f(1,2);        #  22  as named function
m.(1,2);       #  23  as named function, explicit postfix  # defined via pointy-block
$ref(1,2);     #  24  as object invocation (must be hard ref)
$ref.(1,2);    #  25  as object invocation, explicit postfix
1.$f: 2;       #  26  as pseudo-method meaning $f(1,2) (hard ref only)
1.$f(2);       #  27  as pseudo-method meaning $f(1,2) (hard ref only)
1.&f: 2;       #  28  as pseudo-method meaning &f(1,2) (is hard f)
1.&f(2);       #  29  as pseudo-method meaning &f(1,2) (is hard f)
1.k: 2;        #  30  as method via dispatcher             # requires custom method, via 'Int.^add_method'
1.k(2);        #  31  as method via dispatcher
1."$k-sym"(2); #  32  as method via dispatcher, symbolic

# Calling a function with a variable number of arguments (varargs):

my @args = 2,3,4;

f @args;           #  33  as list operator
f(@args);          #  34  as named function
n.(@args);         #  35  as named function, explicit postfix   # defined via pointy-block
$ref(@args);       #  36  as object invocation (must be hard ref)
$ref.(@args);      #  37  as object invocation, explicit postfix
1.$g: @args;       #  38  as pseudo-method meaning $f(1,@args) (hard ref)
1.$g(@args);       #  39  as pseudo-method meaning $f(1,@args) (hard ref)
1.&g: @args;       #  40  as pseudo-method meaning &f(1,@args)
1.&g(@args);       #  41  as pseudo-method meaning &f(1,@args)
1.h: @args;        #  42  as method via dispatcher              # requires custom method, via 'Int.^add_method'
1.h(@args);        #  43  as method via dispatcher
1."$h-sym"(@args); #  44  as method via dispatcher, symbolic
f(|@args);         #  45  equivalent to f(1,2,3)

}
```

Output:

```
f1 f2 i3 f4 f5 f6 f7 f8 f9 f10 l11 f12 f13 f14 f15 f16 f17 j18 j19 j20 f21 f22 m23 f24 f25 f26 f27 f28 f29 k30 k31 k32 f33 f34 n35 f36 f37 g38 g39 g40 g41 h42 h43 h44 f45
```


[User]
Show how to call a function in a shared library (without dynamically linking to it at compile-time). In particular, show how to call the shared library function if the library is available, otherwise use an internal equivalent function.

This is a special case of calling a foreign language function where the focus is close to the ABI level and not at the normal API level.

Related task

* OpenGL -- OpenGL is usually maintained as a shared library.

[Assistant]
(formerly Perl 6)

**Works with**: Rakudo version 2018.11

```
use NativeCall;

sub XOpenDisplay(Str $s --> int64) is native('X11') {*}
sub XCloseDisplay(int64 $i --> int32) is native('X11') {*}

if try my $d = XOpenDisplay ":0.0" {
    say "ID = $d";
    XCloseDisplay($d);
}
else {
    say "No X11 library!";
    say "Use this window instead --> ⬜";
}

```

Output:

```
ID = 94722089782960
```


[User]
In object-oriented programming a method is a function associated with a particular class or object. In most forms of object oriented implementations methods can be static, associated with the class itself; or instance, associated with an instance of a class.

Show how to call a static or class method, and an instance method of a class.

[Assistant]
(formerly Perl 6)

**Works with**: Rakudo version 2015.12

### Basic method calls

```
class Thing {
  method regular-example() { say 'I haz a method' }

  multi method multi-example() { say 'No arguments given' }
  multi method multi-example(Str $foo) { say 'String given' }
  multi method multi-example(Int $foo) { say 'Integer given' }
};

# 'new' is actually a method, not a special keyword:
my $thing = Thing.new;

# No arguments: parentheses are optional
$thing.regular-example;
$thing.regular-example();
$thing.multi-example;
$thing.multi-example();

# Arguments: parentheses or colon required
$thing.multi-example("This is a string");
$thing.multi-example: "This is a string";
$thing.multi-example(42);
$thing.multi-example: 42;

# Indirect (reverse order) method call syntax: colon required
my $foo = new Thing: ;
multi-example $thing: 42;

```

### Meta-operators

The `.` operator can be decorated with meta-operators.

```
my @array = <a z c d y>;
@array .= sort;  # short for @array = @array.sort;

say @array».uc;  # uppercase all the strings: A C D Y Z

```

### Classless methods

A method that is not in a class can be called by using the `&` sigil explicitly.

```
my $object = "a string";  # Everything is an object.
my method example-method {
    return "This is { self }.";
}

say $object.&example-method;  # Outputs "This is a string."

```


[User]
Definition

Let **n** be a positive integer having **k** divisors (other than **1** and **n** itself) where **k** is exactly divisible by 3.

Add the first three eligible divisors, then the next three, and so on until the eligible divisors are exhausted. If the resulting partial sums are prime numbers, then **n** is called a Calmo number.

Example

Consider n = 165.

It has 6 eligible divisors, namely [3 5 11 15 33 55].

The sum of the first three is: 3 + 5 + 11 = 19 which is a prime number.

The sum of the next three is: 15 + 33 + 55 = 103 which is also a prime number.

Hence n is a Calmo number.

Task

Find and show here all Calmo numbers under 1000.

[Assistant]
```
use Prime::Factor;
use List::Divvy;

my $upto = 1e3;

my @found = (2..Inf).hyper.grep({
    (so my @d = .&proper-divisors(:s)) &&
    (@d.elems %% 3) &&
    (all @d.batch(3)».sum».is-prime)
}).&upto($upto);

put "{+@found} found before $upto using sums of proper-divisors:\n" ~
@found.batch(10)».fmt("%4d").join: "\n";

@found = (2..Inf).hyper.grep({
    (so my @d = .&proper-divisors(:s).&after: 1) &&
    (@d.elems %% 3) &&
    (all @d.batch(3)».sum».is-prime)
}).&upto($upto);

put "\n{+@found} found before $upto using sums of some bizarre\nbespoke definition for divisors:\n" ~
@found.batch(10)».fmt("%4d").join: "\n";

```

Output:

```
85 found before 1000 using sums of proper-divisors:
   8   21   27   35   39   55   57   65   77   85
 111  115  125  129  155  161  185  187  201  203
 205  209  221  235  237  265  291  299  305  309
 319  323  327  335  341  365  371  377  381  391
 413  415  437  451  485  489  493  497  505  515
 517  535  579  611  623  649  655  667  669  671
 687  689  697  707  731  737  755  767  779  781
 785  831  835  851  865  893  899  901  917  921
 939  955  965  979  989

9 found before 1000 using sums of some bizarre
bespoke definition for divisors:
 165  273  385  399  561  595  665  715  957
```


[User]
Definition

Let p(1), p(2), p(3), ... , p(n) be consecutive prime numbers. If the sum of any consecutive sub-sequence of these numbers is a prime number, then the numbers in such a sub-sequence are called **CalmoSoft primes**.

Task

Find and show here the longest sequence of CalmoSoft primes for p(n) < 100.

Stretch

Show a shortened version (first and last 6 primes) of the same for p(n) < fifty million.
Tip: if it takes longer than twenty seconds, you're doing it wrong.

[Assistant]
Longest sliding window prime sums

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

sub sliding-window(@list, $window) { (^(+@list - $window)).map: { @list[$_ .. $_+$window] } }

for flat (1e2, 1e3, 1e4, 1e5).map: { (1, 2.5, 5) »×» $_ } -> $upto {

    my @primes = (^$upto).grep: &is-prime;

    for +@primes ... 1 {
        my @sums = @primes.&sliding-window($_).grep: { .sum.is-prime }
        next unless @sums;
        say "\nFor primes up to {$upto.Int.&cardinal}:\nLongest sequence of consecutive primes yielding a prime sum: elements: {comma 1+$_}";
        for @sums {  say " {join '...', .[0..5, *-5..*]».&comma».join(' + ')}, sum: {.sum.&comma}" }
        last
    }
}

```

Output:

```
For primes up to one hundred:
Longest sequence of consecutive primes yielding a prime sum: elements: 21
 7 + 11 + 13 + 17 + 19 + 23...71 + 73 + 79 + 83 + 89, sum: 953

For primes up to two hundred fifty:
Longest sequence of consecutive primes yielding a prime sum: elements: 49
 11 + 13 + 17 + 19 + 23 + 29...227 + 229 + 233 + 239 + 241, sum: 5,813

For primes up to five hundred:
Longest sequence of consecutive primes yielding a prime sum: elements: 85
 31 + 37 + 41 + 43 + 47 + 53...467 + 479 + 487 + 491 + 499, sum: 21,407

For primes up to one thousand:
Longest sequence of consecutive primes yielding a prime sum: elements: 163
 13 + 17 + 19 + 23 + 29 + 31...971 + 977 + 983 + 991 + 997, sum: 76,099

For primes up to two thousand, five hundred:
Longest sequence of consecutive primes yielding a prime sum: elements: 359
 7 + 11 + 13 + 17 + 19 + 23...2,411 + 2,417 + 2,423 + 2,437 + 2,441, sum: 408,479

For primes up to five thousand:
Longest sequence of consecutive primes yielding a prime sum: elements: 665
 7 + 11 + 13 + 17 + 19 + 23...4,967 + 4,969 + 4,973 + 4,987 + 4,993, sum: 1,543,127

For primes up to ten thousand:
Longest sequence of consecutive primes yielding a prime sum: elements: 1,223
 3 + 5 + 7 + 11 + 13 + 17...9,887 + 9,901 + 9,907 + 9,923 + 9,929, sum: 5,686,633
 7 + 11 + 13 + 17 + 19 + 23...9,907 + 9,923 + 9,929 + 9,931 + 9,941, sum: 5,706,497

For primes up to twenty-five thousand:
Longest sequence of consecutive primes yielding a prime sum: elements: 2,759
 7 + 11 + 13 + 17 + 19 + 23...24,967 + 24,971 + 24,977 + 24,979 + 24,989, sum: 32,405,707

For primes up to fifty thousand:
Longest sequence of consecutive primes yielding a prime sum: elements: 5,131
 5 + 7 + 11 + 13 + 17 + 19...49,943 + 49,957 + 49,991 + 49,993 + 49,999, sum: 121,013,303

For primes up to one hundred thousand:
Longest sequence of consecutive primes yielding a prime sum: elements: 9,590
 2 + 3 + 5 + 7 + 11 + 13...99,907 + 99,923 + 99,929 + 99,961 + 99,971, sum: 454,196,557

For primes up to two hundred fifty thousand:
Longest sequence of consecutive primes yielding a prime sum: elements: 22,041
 7 + 11 + 13 + 17 + 19 + 23...249,947 + 249,967 + 249,971 + 249,973 + 249,989, sum: 2,623,031,141

For primes up to five hundred thousand:
Longest sequence of consecutive primes yielding a prime sum: elements: 41,530
 2 + 3 + 5 + 7 + 11 + 13...499,801 + 499,819 + 499,853 + 499,879 + 499,883, sum: 9,910,236,647
```


[User]
Two common conventions for naming of computer program variables are **Snake Case** and
**Camel Case**.

**Snake case** variables are generally all lower case, with an underscore between words in the variable, as in **snake\_case\_variable'**. **Camel case** variables are generally lower case first (except in some Pascal conventions or with class names in many other languages), with captalization of the initial letter of the words within the variable, as in '**camelCaseVariable'**.

Leading underscores are not used in such variables except as part of a different naming convention, usually for special internal or system variables. White space is not permitted as part of camel case or snake case variable names.

Task

:   * Write two functions, one to change snake case to camel case and one to change camel case to snake case. If possible, generalize the function enough to apply to strings containing spaces between words or a `-` dash between words, assuming that in those cases a space or hyphen is a also a separator character, like `\_`, for the purpose of creating a new variable name. Leading or trailing whitespace may be ignored.

:   * Show the results on changing to both snake case and camel case for each of the following strings:

```
"snakeCase", "snake_case", "variable_10_case", "variable10Case", "ɛrgo rE tHis",
"hurry-up-joe!", "c://my-docs/happy_Flag-Day/12.doc", "  spaces  "

```

Related tasks

* Naming\_conventions

[Assistant]
The specs are a little vague, but taking a wild stab at it... *(May be completely wrong but without any examples of expected output it is hard to judge. This is what **I** would expect at least...)*

```
my @tests = qww<
  snakeCase  snake_case  variable_10_case  variable10Case  "ɛrgo rE tHis"
  hurry-up-joe!  c://my-docs/happy_Flag-Day/12.doc  "  spaces  "
>;

sub to_snake_case (Str $snake_case_string is copy) {
    $snake_case_string.=trim;
    return $snake_case_string if $snake_case_string.contains: / \s | '/' /;
    $snake_case_string.=subst: / <after <:Ll>> (<:Lu>|<:digit>+) /, {'_' ~ $0.lc}, :g;
    $snake_case_string.=subst: / <after <:digit>> (<:Lu>) /, {'_' ~ $0.lc}, :g;
}

sub toCamelCase (Str $CamelCaseString is copy) {
    $CamelCaseString.=trim;
    return $CamelCaseString if $CamelCaseString.contains: / \s | '/' /;
    $CamelCaseString.=subst: / ('_') (\w) /, {$1.uc}, :g;
}

sub to-kebab-case (Str $kebab-case-string is copy) {
    $kebab-case-string.=trim;
    return $kebab-case-string if $kebab-case-string.contains: / \s | '/' /;
    $kebab-case-string.=subst: / ('_') (\w) /, {'-' ~ $1.lc}, :g;
    $kebab-case-string.=subst: / <after <:Ll>> (<:Lu>|<:digit>+) /, {'-' ~ $0.lc}, :g;
    $kebab-case-string.=subst: / <after <:digit>> (<:Lu>) /, {'-' ~ $0.lc}, :g;
}

say   "{' ' x 30}to_snake_case";
printf "%33s ==> %s\n", $_, .&to_snake_case for @tests;
say "\n{' ' x 30}toCamelCase";
printf "%33s ==> %s\n", $_,   .&toCamelCase for @tests;
say "\n{' ' x 30}to-kabab-case";
printf "%33s ==> %s\n", $_, .&to-kebab-case for @tests;

```

Output:

```
                              to_snake_case
                        snakeCase ==> snake_case
                       snake_case ==> snake_case
                 variable_10_case ==> variable_10_case
                   variable10Case ==> variable_10_case
                     ɛrgo rE tHis ==> ɛrgo rE tHis
                    hurry-up-joe! ==> hurry-up-joe!
c://my-docs/happy_Flag-Day/12.doc ==> c://my-docs/happy_Flag-Day/12.doc
                         spaces   ==> spaces

                              toCamelCase
                        snakeCase ==> snakeCase
                       snake_case ==> snakeCase
                 variable_10_case ==> variable10Case
                   variable10Case ==> variable10Case
                     ɛrgo rE tHis ==> ɛrgo rE tHis
                    hurry-up-joe! ==> hurry-up-joe!
c://my-docs/happy_Flag-Day/12.doc ==> c://my-docs/happy_Flag-Day/12.doc
                         spaces   ==> spaces

                              to-kabab-case
                        snakeCase ==> snake-case
                       snake_case ==> snake-case
                 variable_10_case ==> variable-10-case
                   variable10Case ==> variable-10-case
                     ɛrgo rE tHis ==> ɛrgo rE tHis
                    hurry-up-joe! ==> hurry-up-joe!
c://my-docs/happy_Flag-Day/12.doc ==> c://my-docs/happy_Flag-Day/12.doc
                         spaces   ==> spaces
```


[User]
Task

Write a program that performs so-called canny edge detection on an image.

A possible algorithm consists of the following steps:

1. **Noise reduction.**   May be performed by Gaussian filter.
2. Compute **intensity gradient**   (matrices

   G

   x
   {\displaystyle {\displaystyle G\_{x}}}
    and

   G

   y
   {\displaystyle {\displaystyle G\_{y}}}
   )   and its **magnitude**

   G
   {\displaystyle {\displaystyle G}}
   :

   G
   =

   G

   x

   2
   +

   G

   y

   2
   {\displaystyle {\displaystyle G={\sqrt {G\_{x}^{2}+G\_{y}^{2}}}}}

   May be performed by convolution of an image with Sobel operators.
3. **Non-maximum suppression.**
   For each pixel compute the orientation of intensity gradient vector:

   θ
   =

   a
   t
   a
   n
   2

   (

   G

   y
   ,

   G

   x
   )
   {\displaystyle {\displaystyle \theta ={\rm {atan2}}\left(G\_{y},\,G\_{x}\right)}}
   .
   Transform   angle

   θ
   {\displaystyle {\displaystyle \theta }}
      to one of four directions:   0, 45, 90, 135 degrees.
   Compute new array

   N
   {\displaystyle {\displaystyle N}}
   :     if

   G

   (

   p

   a
   )
   <
   G

   (
   p
   )
   <
   G

   (

   p

   b
   )
   {\displaystyle {\displaystyle G\left(p\_{a}\right)<G\left(p\right)<G\left(p\_{b}\right)}}

   where

   p
   {\displaystyle {\displaystyle p}}
      is the current pixel,

   p

   a
   {\displaystyle {\displaystyle p\_{a}}}
      and

   p

   b
   {\displaystyle {\displaystyle p\_{b}}}
      are the two neighbour pixels in the direction of gradient,
   then

   N
   (
   p
   )
   =
   G
   (
   p
   )
   {\displaystyle {\displaystyle N(p)=G(p)}}
   ,       otherwise

   N
   (
   p
   )
   =
   0
   {\displaystyle {\displaystyle N(p)=0}}
   .
   Nonzero pixels in resulting array correspond to local maxima of

   G
   {\displaystyle {\displaystyle G}}
      in direction

   θ
   (
   p
   )
   {\displaystyle {\displaystyle \theta (p)}}
   .
4. **Tracing edges with hysteresis.**
   At this stage two thresholds for the values of

   G
   {\displaystyle {\displaystyle G}}
      are introduced:

   T

   m
   i
   n
   {\displaystyle {\displaystyle T\_{min}}}
      and

   T

   m
   a
   x
   {\displaystyle {\displaystyle T\_{max}}}
   .
   Starting from pixels with

   N
   (
   p
   )
   ⩾

   T

   m
   a
   x
   {\displaystyle {\displaystyle N(p)\geqslant T\_{max}}}
   ,
   find all paths of pixels with

   N
   (
   p
   )
   ⩾

   T

   m
   i
   n
   {\displaystyle {\displaystyle N(p)\geqslant T\_{min}}}
      and put them to the resulting image.

[Assistant]
Admittedly laziness always prevails so an off-the-shelf function from ImageMagick is used instead.

cannyedge.c

```
#include <stdio.h>
#include <string.h>
#include <magick/MagickCore.h>

int CannyEdgeDetector(
   const char *infile, const char *outfile,
   double radius, double sigma, double lower, double upper ) {

   ExceptionInfo   *exception;
   Image           *image, *processed_image, *output;
   ImageInfo       *input_info;

   exception   = AcquireExceptionInfo();
   input_info  = CloneImageInfo((ImageInfo *) NULL);
   (void) strcpy(input_info->filename, infile);
   image       = ReadImage(input_info, exception);
   output      = NewImageList();
   processed_image = CannyEdgeImage(image,radius,sigma,lower,upper,exception);
   (void) AppendImageToList(&output, processed_image);
   (void) strcpy(output->filename, outfile);
   WriteImage(input_info, output);
                                    // after-party clean up
   DestroyImage(image);
   output=DestroyImageList(output);
   input_info=DestroyImageInfo(input_info);
   exception=DestroyExceptionInfo(exception);
   MagickCoreTerminus();

   return 0;
}

```

cannyedge.raku

```
# 20220103 Raku programming solution

use NativeCall;

sub CannyEdgeDetector(CArray[uint8], CArray[uint8], num64, num64, num64, num64
) returns int32 is native( '/home/hkdtam/LibCannyEdgeDetector.so' ) {*};

CannyEdgeDetector( # imagemagick.org/script/command-line-options.php#canny
   CArray[uint8].new(  'input.jpg'.encode.list, 0), # pbs.org/wgbh/nova/next/wp-content/uploads/2013/09/fingerprint-1024x575.jpg
   CArray[uint8].new( 'output.jpg'.encode.list, 0),
   0e0, 2e0, 0.05e0, 0.05e0
)

```

Output:

```
export PKG_CONFIG_PATH=/usr/lib/pkgconfig
gcc -Wall -fPIC -shared -o LibCannyEdgeDetector.so  cannyedge.c `pkg-config --cflags --libs MagickCore`
raku -c cannyedge.raku && ./cannyedge.raku
```

Output: (Offsite image file)