Perl Weekly Challenge 261: Multiply by Two
These are some answers to the Week 261, 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 24, 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: Multiply by Two
You are given an array of integers, @ints
and an integer $start
.
Write a script to do the following:
a) Look for
$start
in the array@ints
, if found multiply the number by 2b) If not found stop the process otherwise repeat
In the end return the final value.
Example 1
Input: @ints = (5,3,6,1,12) and $start = 3
Output: 24
Step 1: 3 is in the array so 3 x 2 = 6
Step 2: 6 is in the array so 6 x 2 = 12
Step 3: 12 is in the array so 12 x 2 = 24
24 is not found in the array so return 24.
Example 2
Input: @ints = (1,2,4,3) and $start = 1
Output: 8
Step 1: 1 is in the array so 1 x 2 = 2
Step 2: 2 is in the array so 2 x 2 = 4
Step 3: 4 is in the array so 4 x 2 = 8
8 is not found in the array so return 8.
Example 3
Input: @ints = (5,6,7) and $start = 2
Output: 2
2 is not found in the array so return 2.
First, let's note that if $start
is equal to 0 and if 0 is also found in the input array of integers, we will enter in an endless loop. We will add a condition to avoid that from happening.
Multiply by Two in Raku
In Raku, we will start by storing the input array of integers into a Bag, i.e. a collection of distinct objects with integer weights, to enable fast lookup. We could also have used a Set
instead of a bag, since we don't really need integer weights, but a Bag
is what came to my mind first. Then, we simply multiply $start
by two until it is no longer found in the Bag
.
sub multiply-by-two ($start is copy where * != 0, @in) {
my $bag = @in.Bag;
$start *= 2 while $bag{$start};
return $start;
}
my @tests = (3, (5,3,6,1,12)), (1, (1,2,4,3)), (2, (5,6,7));
for @tests -> @test {
printf "%d - %-15s => ", @test[0], "@test[1]";
say multiply-by-two @test[0], @test[1];
}
This program displays the following output:
$ raku ./multiply-by-two.raku
3 - 5 3 6 1 12 => 24
1 - 1 2 4 3 => 8
2 - 5 6 7 => 2
Multiply by Two in Perl
This is a port to Perl of the above Raku program. Perl doesn't have Bags
, but we can use a hash to the same effect.
use strict;
use warnings;
use feature 'say';
sub multiply_by_two {
my $start = shift;
die "$start cannot be 0" if $start == 0;
my %present = map { $_ => 1 } @_;
$start *= 2 while $present{$start};
return $start;
}
my @tests = ( [3, [5,3,6,1,12]], [1, [1,2,4,3]], [2, [5,6,7]] );
for my $test (@tests) {
printf "%d - %-15s => ", $test->[0], "@{$test->[1]}";
say multiply_by_two @$test[0], @{$test->[1]};
}
This program displays the following output:
$ raku ./multiply-by-two.raku
3 - 5 3 6 1 12 => 24
1 - 1 2 4 3 => 8
2 - 5 6 7 => 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 31, 2024. And, please, also spread the word about the Perl Weekly Challenge if you can.
Leave a comment