This is my response to The Weekly Challenge #305.
Input: @binary = (1, 0, 1)
Output: (false, true, true)
Sub-arrays (base-10):
(1): 1 - not prime
(1, 0): 2 - prime
(1, 0, 1): 5 - prime
Example 2:
Input: @binary = (1, 1, 0)
Output: (false, true, false)
Sub-arrays (base-10):
(1): 1 - not prime
(1, 1): 3 - prime
(1, 1, 0): 6 - not prime
Example 3:
Input: @binary = (1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0,
0, 0, 1)
Output: (false, true, true, false, false, true, false, false, false,
false, false, false, false, false, false, false, false, false,
false, true)
#! /usr/bin/env raku
unit sub MAIN (*@binary where @binary.elems > 0 && all(@binary) eq any(0,1),
:v(:$verbose)); # [1]
my $current = ""; # [2]
my @result; # [3]
for @binary -> $digit # [4]
{
$current ~= $digit; # [5]
my $int = $current.parse-base(2); # [6]
my $prime = $int.is-prime; # [7]
say ": Binary:$current Int:$int { $prime ?? "prime" !! "not prime" }"
if $verbose;
@result.push: $prime; # [8]
}
say "({ @result.join(", ") })"; # [9]
[1] At least one value, and they must be either 0 or 1.
[2] We are going to build the partial binary number here.
[3] The resulting array of Boolean values.
[4] Iterate over each binary digit.
[5] Add the digit to the partial binary number.
[6] Convert the binary string to a (decimal) number
with parse-base
.
See docs.raku.org/routine/parse-base for more information about parse-base
.
[7] Is the current number a prime?
See docs.raku.org/routine/is-prime for more information about is-prime
.
[8] Add the Boolean value to the result.
[9] Pretty print the result.
Running it:
$ ./binary-prefix 1 0 1
(False, True, True)
$ ./binary-prefix 1 1 0
(False, True, False)
$ ./binary-prefix -v 1 1 1 1 0 1 0 0 0 0 1 0 1 0 0 1 0 0 0 1
(False, True, True, False, False, True, False, False, False, False, False, \
False, False, False, False, False, False, False, False, True)
Looking good.
With verbose mode:
$ ./binary-prefix -v 1 0 1
: Binary:1 Int:1 not prime
: Binary:10 Int:2 prime
: Binary:101 Int:5 prime
(False, True, True)
$ ./binary-prefix -v 1 1 0
: Binary:1 Int:1 not prime
: Binary:11 Int:3 prime
: Binary:110 Int:6 not prime
(False, True, False)
$ ./binary-prefix -v 1 1 1 1 0 1 0 0 0 0 1 0 1 0 0 1 0 0 0 1
: Binary:1 Int:1 not prime
: Binary:11 Int:3 prime
: Binary:111 Int:7 prime
: Binary:1111 Int:15 not prime
: Binary:11110 Int:30 not prime
: Binary:111101 Int:61 prime
: Binary:1111010 Int:122 not prime
: Binary:11110100 Int:244 not prime
: Binary:111101000 Int:488 not prime
: Binary:1111010000 Int:976 not prime
: Binary:11110100001 Int:1953 not prime
: Binary:111101000010 Int:3906 not prime
: Binary:1111010000101 Int:7813 not prime
: Binary:11110100001010 Int:15626 not prime
: Binary:111101000010100 Int:31252 not prime
: Binary:1111010000101001 Int:62505 not prime
: Binary:11110100001010010 Int:125010 not prime
: Binary:111101000010100100 Int:250020 not prime
: Binary:1111010000101001000 Int:500040 not prime
: Binary:11110100001010010001 Int:1000081 prime
(False, True, True, False, False, True, False, False, False, False, \
False, False, False, False, False, False, False, False, False, True)
Input: @words = ("perl", "python", "raku")
@alien = qw/h l a b y d e f g i r k m n o p q j s t u v w x c z/
Output: ("raku", "python", "perl")
Example 2:
Input: @words = ("the", "weekly", "challenge")
@alien = qw/c o r l d a b t e f g h i j k m n p q s w u v x y z/
Output: ("challenge", "the", "weekly")
#! /usr/bin/env raku
unit sub MAIN (*@words where @words.elems > 1
&& all(@words) ~~ /^<[a..z]>+$/, # [1]
:a(:$alien) where $alien.comb.sort.join eq
"abcdefghijklmnopqrstuvwxyz", # [2]
:v(:$verbose));
my @alien = $alien.comb; # [3]
my @alpha = 'a' .. 'z'; # [4]
my %alien; # [5]
my %words; # [6]
for @alpha -> $char # [7]
{
%alien{$char} = @alien.shift; # [7a]
say ": char $char -> %alien{$char}" if $verbose;
}
for @words -> $word # [8]
{
%words{$word} = alienate($word); # [8a]
say ": word $word -> %words{$word}" if $verbose;
}
sub alien ($char) # [9]
{
return %alien{$char}; # [9a]
}
sub alienate ($string) # [10]
{
return $string.comb>>.&alien.join; # [10a]
}
my @sorted = @words.sort({ %words{$^a} cmp %words{$^b} }); # [11]
say "({ @sorted.map('"' ~ * ~ '"').join(", ") })"; # [12]
[1] At least two words, using one or more of the letters a..z only.
[2] The alien alphabet as a string (and a named argument).
We ensure that it is complete (i.e. has all the letters a..z) by turning
the string into a list of characters (with comb
), sorting that list
(with sort
), joining the result together into a string again (with
join
), and finally ensuring that we get the whole alphabet.
See docs.raku.org/routine/comb for more information about comb
.
[3] The alien letters as a list.
[4] The normal alphabet.
[5] The mapping between alien and normal letters will end up here.
[6] The mapping between alien and normal words will end up here.
[7] Iterate over the normal alphabet, and assign the corresponding alien letter [7a].
[8] Iterate over the normal words, and assign the corresponding alien word [8a] using the «alienate» procedure.
[9] Procedure returning the alien twin of the normal letter.
[10] Procedure returning the alien version of the normal
word. Note the use of >>.
to apply the method on each element in
the array, and the use of the .&
prefix to call a procedure as a
method.
See
docs.raku.org/language/operators#methodop_.& for more information
about the special procedure invocation syntax .&
.
[11] Sort the words, based on the alien versions.
[12] Pretty print the result.
Running it:
$ ./alien-dictionary -a=hlabydefgirkmnopqjstuvwxcz perl python raku
("raku", "python", "perl")
$ ./alien-dictionary -a=corldabtefghijkmnpqswuvxyz the weekly challenge
("challenge", "the", "weekly")
Looking good.
With verbose mode:
$ ./alien-dictionary -v -a=hlabydefgirkmnopqjstuvwxcz perl python raku
: char a -> h
: char b -> l
: char c -> a
: char d -> b
: char e -> y
: char f -> d
: char g -> e
: char h -> f
: char i -> g
: char j -> i
: char k -> r
: char l -> k
: char m -> m
: char n -> n
: char o -> o
: char p -> p
: char q -> q
: char r -> j
: char s -> s
: char t -> t
: char u -> u
: char v -> v
: char w -> w
: char x -> x
: char y -> c
: char z -> z
: word perl -> pyjk
: word python -> pctfon
: word raku -> jhru
("raku", "python", "perl")
$ ./alien-dictionary -v -a=corldabtefghijkmnpqswuvxyz the weekly challenge
: char a -> c
: char b -> o
: char c -> r
: char d -> l
: char e -> d
: char f -> a
: char g -> b
: char h -> t
: char i -> e
: char j -> f
: char k -> g
: char l -> h
: char m -> i
: char n -> j
: char o -> k
: char p -> m
: char q -> n
: char r -> p
: char s -> q
: char t -> s
: char u -> w
: char v -> u
: char w -> v
: char x -> x
: char y -> y
: char z -> z
: word the -> std
: word weekly -> vddghy
: word challenge -> rtchhdjbd
("challenge", "the", "weekly")
And that's it.