Perl Weekly Challenge 210: Kill and Win and Number Collision
These are some answers to the Week 210 of the Perl Weekly Challenge organized by Mohammad S. Anwar.
Task 1: Kill and Win
You are given a list of integers.
Write a script to get the maximum points. You are allowed to take out (kill) any integer and remove from the list. However if you do that then all integers exactly one-less or one-more would also be removed. Find out the total of integers removed.
Example 1
Input: @int = (2, 3, 1)
Output: 6
First we delete 2 and that would also delete 1 and 3. So the maximum points we get is 6.
Example 2
Input: @int = (1, 1, 2, 2, 2, 3)
Output: 11
First we delete 2 and that would also delete both the 1's and the 3. Now we have (2, 2).
Then we delete another 2 and followed by the third deletion of 2. So the maximum points we get is 11.
In my understanding of the process, we will always be able to pick a few integers and thereby remove all integers from the list. So, the sum of removed integers is the sum of the input integer.
Kill and Win in Raku
sub sum-deleted-digits (@in) {
# we can always delete all digits
return [+] @in;
}
for <2 3 1>, <1 1 2 2 2 3> -> @test {
say "@test[]".fmt("%-15s => "), sum-deleted-digits @test;
}
This program displays the following output:
$ raku ./kill-and-win.raku
2 3 1 => 6
1 1 2 2 2 3 => 11
Kill and Win in Perl
sub sum_deleted_digits {
# we can always delete all digits
my $sum = 0;
$sum += $_ for @_;
return $sum;
}
for my $test ([<2 3 1>], [<1 1 2 2 2 3>]) {
printf "%-15s => %d \n", "@$test", sum_deleted_digits @$test;
}
This program displays the following output:
$ perl ./kill-and-win.pl
2 3 1 => 6
1 1 2 2 2 3 => 11
Task 2: Number Collision
You are given an array of integers which can move in right direction if it is positive and left direction when negative. If two numbers collide then the smaller one will explode. And if both are same then they both explode. We take the absolute value in consideration when comparing.
All numbers move at the same speed, therefore any 2 numbers moving in the same direction will never collide.
Write a script to find out who survives the collision.
Example 1:
Input: @list = (2, 3, -1)
Output: (2, 3)
The numbers 3 and -1 collide and -1 explodes in the end. So we are left with (2, 3).
Example 2:
Input: @list = (3, 2, -4)
Output: (-4)
The numbers 2 and -4 collide and 2 explodes in the end. That gives us (3, -4).
Now the numbers 3 and -4 collide and 3 explodes. Finally we are left with -4.
Example 3:
Input: @list = (1, -1)
Output: ()
The numbers 1 and -1 both collide and explode. Nothing left in the end.
Number Collision in Raku
sub number-collision (@in-array) {
my @in = @in-array;
loop {
return () if @in.elems == 0;
my @temp;
for 0..^@in.end -> $i {
if @in[$i] > 0 {
if @in[$i+1] > 0 {
push @temp, @in[$i];
} else {
next if abs(@in[$i]) == abs(@in[$i+1]);
push @temp,
abs(@in[$i]) > abs(@in[$i+1]) ??
@in[$i] !! @in[$i+1];
}
} elsif @in[$i] < 0 {
push @temp, @in[$i] and next
unless @in[$i-1]:exists;
if @in[$i-1] < 0 {
push @temp, @in[$i];
} else {
shift @temp and next
if abs(@in[$i]) == abs(@in[$i+1]);
@temp[*-1] =
abs(@in[$i]) > abs(@in[$i-1]) ??
@in[$i] !! @in[$i-1];
}
} else { # @in[$i] == 0
push @temp, @in[$i];
}
}
return @temp if @temp.all > 0 or @temp.all < 0;
@in = @temp;
}
}
for <2 3 -1>, <3 2 -4>, <1 -1> -> @test {
say "@test[]".fmt("%-10s => "), number-collision @test;
}
This program displays the following output:
$ raku ./number-collision.raku
2 3 -1 => [2 3]
3 2 -4 => [-4]
1 -1 => []
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 April 9, 2023. And, please, also spread the word about the Perl Weekly Challenge if you can.
Leave a comment