Words and Digits
with Raku

by Arne Sommer

Words and Digits with Raku

[251] Published 19. August 2023.

This is my response to The Weekly Challenge #230.

Challenge #230.1: Separate Digits

You are given an array of positive integers.

Write a script to separate the given array into single digits.

Example 1:
Input: @ints = (1, 34, 5, 6)
Output: (1, 3, 4, 5, 6)
Example 2:
Input: @ints = (1, 24, 51, 60)
Output: (1, 2, 4, 5, 1, 6, 0)
File: separate-digits
#! /usr/bin/env raku

subset PosInt of Int where * >= 1;                                    # [1]

unit sub MAIN (*@ints where @ints.elems > 0 && all(@ints) ~~ PosInt); # [2]

say "({ @ints.map( *.comb ).flat.join(", ") })";                      # [3]
 ### ( ########### 3a ##### # 3b # 3c ###### ) ##   

[1] «Positive Integers» does not match any built in types in Raku, so we set up a custom one, with subset. It is a subset of the Int type, with a where clause preventing negative values and zero.

See docs.raku.org/language/typesystem#index-entry-subset-subset for more information about subset.

[2] At least one element, and they must all be positive integers.

[3] Print the outermost parens, then use map to convert the numbers into individual characters (with comb [3a]). The result is a two-dimentional list, so we apply flat [3b] to get back to a one-dimentional world. The join [3c] inserts commas between the values, so that we get the output exactly as given in the challenge.

Running it:

$ ./separate-digits 1 34 5 6
(1, 3, 4, 5, 6)

$ ./separate-digits 1 24 51 60
(1, 2, 4, 5, 1, 6, 0)

Looking good.

Challenge #230.2: Count Words

You are given an array of words made up of alphabetic characters and a prefix.

Write a script to return the count of words that starts with the given prefix.

Example 1:
Input: @words  = ("pay", "attention", "practice", "attend")
       $prefix = "at"
Ouput: 2

Two words "attention" and "attend" starts with the given prefix "at".
Example 2:
Input: @words  = ("janet", "julia", "java", "javascript")
       $prefix = "ja"
Ouput: 3

Three words "janet", "java" and "javascript" starts with the given
prefix "ja".
File: count-words
#! /usr/bin/env raku

unit sub MAIN ($prefix, *@words where @words.elems > 0, :v(:$verbose));  # [1]

my @matching = @words.grep( *.starts-with($prefix) );                    # [2]

say ": Matches: { @matching.map('"' ~ * ~ '"').join(", ") }" if $verbose;

say @matching.elems;                                                     # [3]

[1] The first argument is the prefix, and the rest of them are the words.

[2] We use the starts-with method (together with grep) to hold on to the words that starts with the prefix.

See docs.raku.org/routine/starts-with for more information about starts-with.

[3] Print the number of matching words.

Running it:

$ ./count-words at pay attention practice attend
2

$ ./count-words ja janet julia java javascript
3

Looking good.

With verbose mode:

$ ./count-words -v at pay attention practice attend
: Matches: "attention", "attend"
2

$ ./count-words -v ja janet julia java javascript
: Matches: "janet", "java", "javascript"
3

And that's it.