with Raku

This is my response to The Weekly Challenge #258.

You are given an array of positive integers,

Write a script to find out how many integers have even number of digits.

Example 1:

File: cedn
`@ints`

.
Write a script to find out how many integers have even number of digits.

Example 1:

Input: @ints = (10, 1, 111, 24, 1000)
Output: 3
There are 3 integers having even digits i.e. 10, 24 and 1000.

Example 2:
Input: @ints = (111, 1, 11111)
Output: 0

Example 3:
Input: @ints = (2, 8, 1024, 256)
Output: 1

#! /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.grep( *.chars %% 2 ).elems; # [3]

[1] The `UInt`

(Unsigned Int) type includes zero,
so we cannot use that. But a suitable custom type with `subset`

does
the trick.

See
docs.raku.org/language/typesystem#subset
for more information about `subset`

.

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

[3] Use `grep`

to retain the values with a character
length that is even, i.e. divisible (the `%%`

operator) by 2. Then we
print the number of elements we get. And that really is all there is to
it...

See docs.raku.org/routine/%%
for more information about the Divisibility Operator `%%`

.

Running it:

$ ./cedn 10 1 111 24 1000
3
$ ./cedn 111 1 11111
0
$ ./cedn 2 8 1024 256
1

Looking good.

You are given an array of integers,

Write a script to find the sum of values whose index binary representation has exactly

Example 1:

File: sum-of-values
`@int`

and an integer `$k`

.
Write a script to find the sum of values whose index binary representation has exactly

`$k`

number of `1-bit`

set.
Example 1:

Input: @ints = (2, 5, 9, 11, 3), $k = 1
Output: 17
Binary representation of index 0 = 0
Binary representation of index 1 = 1
Binary representation of index 2 = 10
Binary representation of index 3 = 11
Binary representation of index 4 = 100
So the indices 1, 2 and 4 have total one 1-bit sets.
Therefore the sum, $ints[1] + $ints[2] + $ints[3] = 17

Example 2:
Input: @ints = (2, 5, 9, 11, 3), $k = 2
Output: 11

Example 3:
Input: @ints = (2, 5, 9, 11, 3), $k = 0
Output: 2

#! /usr/bin/env raku
unit sub MAIN (Int $k, # [1]
*@ints where @ints.elems > 0 && all(@ints) ~~ Int, # [1a]
:v(:$verbose));
my $output = 0; # [2]
for ^@ints.elems -> $index # [3]
{
my $binary = $index.fmt('%b'); # [4]
my $sum = $binary.comb.sum; # [5]
if $sum == $k # [6]
{
$output += @ints[$index]; # [6a]
say ":Index $index binary $binary -> $sum match - adding \
@ints[$index] -> $output" if $verbose;
}
elsif $verbose
{
say ":Index $index binary $binary -> $sum";
}
}
say $output; # [7]

[1] Specify the `$k`

value first, followed by the `@ints`

[1a].

[2] The sum will be accumulated here.

[3] Iterate over the array indices.

[4] Convert the current index to binary with `fmt`

, the method
form of the more famous `sprintf`

.

See docs.raku.org/routine/fmt for more information about `fmt`

.

[5] The number of 1 bits is just a matter of splitting the string
into individual characters (with `comb`

) and adding them (i.e. the zeroes
and the ones) all up.

See docs.raku.org/routine/comb for more information about `comb`

.

[6] Add the current number to the sum [6a], if we got a binary index match.

[7] Print the sum.

Running it, with verbose mode:

$ ./sum-of-values -v 1 2 5 9 11 3
:Index 0 binary 0 -> 0
:Index 1 binary 1 -> 1 match - adding 5 -> 5
:Index 2 binary 10 -> 1 match - adding 9 -> 14
:Index 3 binary 11 -> 2
:Index 4 binary 100 -> 1 match - adding 3 -> 17
17
$ ./sum-of-values -v 2 2 5 9 11 3
:Index 0 binary 0 -> 0
:Index 1 binary 1 -> 1
:Index 2 binary 10 -> 1
:Index 3 binary 11 -> 2 match - adding 11 -> 11
:Index 4 binary 100 -> 1
11
$ ./sum-of-values -v 0 2 5 9 11 3
:Index 0 binary 0 -> 0 match - adding 2 -> 2
:Index 1 binary 1 -> 1
:Index 2 binary 10 -> 1
:Index 3 binary 11 -> 2
:Index 4 binary 100 -> 1
2

Looking good.

And that's it.