### Perl Weekly Challenge: Week 258

#### Challenge 1:

**Count Even Digits Number**

You are given a array of positive integers,

`@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
```

Raku once again comes through with a one-liner.

```
@*ARGS.grep({$_.chars %% 2}).elems.say
```

Using the command-line arguments as input, we filter them with `.grep()`

, finding the length of each one with `.chars()`

and seeing if it is evenly divisible by two with the `%%`

operator. Then we count how many we found with `.elems()`

and output the result with `.say()`

.

The Perl version is slightly longer because we don't have `%%`

and have to do an explicit comparison to 0 instead.

```
say scalar grep {(length $_) % 2 == 0} @ARGV
```

#### Challenge 2:

**Sum of Values**

You are given an array of integers,

`@ints`

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
```

Raku can do this one (albeit very long) line but I've spread it out to make it more intelligable.

I'm assuming `$k`

is the first command-line argument and `@ints`

is all the rest.

We start by getting the indices of each element in `@ints`

with what has become one of my favorite methods of late, `.keys()`

.

```
@ints
.keys
```

Then each index is converted to binary via `.map()`

and `.base(2)`

```
.map({ $_.base(2) })
```

Now we can find which indices meet the specs' criterion. We do this with a call to `.grep()`

which...

```
.grep({
```

...splits the index into its' constituent digits with `.comb()`

,,,

```
$_
.comb
```

...finds the digits which are 1's with another `.grep()`

...

```
.grep({ $_ == 1 })
```

... counts how many 1's there were with `.elems()`

and compares that number to `$k`

.

```
.elems == $k
})
```

Now we know which indices we need, we can find the values of their respective elements by transforming them with `.map()`

.
We have to prefix `0b`

to each index in order for it to be recognized as a binary number literal.

```
.map({ @ints["0b$_"] })
```

Then we add up all the values with `.sum()`

...

```
.sum
```

...and print the result.

```
.say;
```

Perl works the same way although the visual order of the operations is reversed. And we have to provide our own `sum()`

function.

```
say sum(
```

Unfortunately, it seems that Perl does not allow you to use a binary literal as an array index so it has to first be converted
back into base 10 with the badly named `oct()`

.

```
map { $ints[oct "0b$_"] }
grep { scalar (grep { $_ == 1 } (split //, $_)) == $k }
```

We don't have `.base()`

either but `sprintf('%b')`

can do the conversion for us.

```
map { sprintf '%b', $_ } keys @ints
);
```