## 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 2

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

``````

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

``````

Example 3

``````Input: @ints = (5,6,7) and \$start = 2
Output: 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.