## Perl Weekly Challenge 258: Sum of Values

These are some answers to the Week 258, Task 2, of the Perl Weekly Challenge organized by Mohammad S. Anwar.

*Spoiler Alert:* This weekly challenge deadline is due in a couple of days from now (on March 3, 2024 at 23:59). This blog post provides some solutions to this challenge. Please don’t read on if you intend to complete the challenge on your own.

## Task 2: Sum of Values

*You are given an array of integers, @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[4] = 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
```

### Sum of Values in Raku

Although it could easily be done in a one-liner, I've decided to split the solution in two statements, for the sake of clarity. The first statement finds the indexes whose binary representation contains exactly `$k`

"1" (sum of digits equal to `$k`

) and populates the `@eligibles`

array with the corresponding input values in `@in`

. The second statement simply returns the sum oh those values.

```
sub sum-of-values ($k, @in) {
my @eligibles = map { @in[$_] },
grep {$_.base(2).comb.sum == $k}, 0..@in.end;
return @eligibles.sum;
}
my @tests = (1, <2 5 9 11 3>),
(2, <2 5 9 11 3>),
(0, <2 5 9 11 3>);
for @tests -> @test {
printf "%-15s => ", "@test[]";
say sum-of-values @test[0], @test[1];
}
```

This program displays the following output:

```
$ raku ./sum-of-values.raku
1 2 5 9 11 3 => 17
2 2 5 9 11 3 => 11
0 2 5 9 11 3 => 2
```

### Sum of Values in Perl

This is a port to Perl of the above Raku program. I counted the number of "1" using the `tr///`

operator because has no built-in `sum`

function, only to find moments later that I needed to implement a `sum`

subroutine anyway.

```
use strict;
use warnings;
use feature 'say';
sub sum {
my $sum = 0;
$sum += $_ for @_;
return $sum;
}
sub sum_of_values {
my ($k, @in) = @_;
my @eligibles = map { $in[$_] }
grep {sprintf ("%b", $_) =~ tr/1/1/ == $k} 0..$#in;
return sum @eligibles;
}
my @tests = ( [1, [<2 5 9 11 3>]],
[2, [<2 5 9 11 3>]],
[0, [<2 5 9 11 3>]] );
for my $test (@tests) {
printf "%-3s - %-15s => ", "$test->[0]", "@{$test->[1]}";
say sum_of_values $test->[0], @{$test->[1]};
}
```

This program displays the following output:

```
$ perl ./sum-of-values.pl
1 - 2 5 9 11 3 => 17
2 - 2 5 9 11 3 => 11
0 - 2 5 9 11 3 => 2
```

## Wrapping up

The next week Perl Weekly Challenge will start soon. If you want to participate in this challenge, please check https://perlweeklychallenge.org/ and make sure you answer the challenge before 23:59 BST (British summer time) on March 10, 2024. And, please, also spread the word about the Perl Weekly Challenge if you can.

## Leave a comment