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

About laurent_r

user-pic I am the author of the "Think Perl 6" book (O'Reilly, 2017) and I blog about the Perl 5 and Raku programming languages.