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