Perl Weekly Challenge 252: Unique Sum Zero

These are some answers to the Week 252, Task 2, of the Perl Weekly Challenge organized by Mohammad S. Anwar.

Spoiler Alert: This weekly challenge deadline is due in a few days from now (on January 21, 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: Unique Sum Zero

You are given an integer, $n.

Write a script to find an array containing $n unique integers such that they add up to zero.

Example 1

Input: $n = 5
Output: (-7, -1, 1, 3, 4)

Two other possible solutions could be as below:
(-5, -1, 1, 2, 3) and (-3, -1, 2, -2, 4).

Example 2

Input: $n = 3
Output: (-1, 0, 1)

Example 3

Input: $n = 1
Output: (0)

Unique Sum Zero in Raku

We just take a number of distinct strictly positive integers equal to the rounded half of the input number and take these numbers and their negative counterpart, so that the sum is always 0. And we add 0 if the input number was odd. For fun, I decided to use the built-in pick method (which generates in our case distinct random integers in the specified range). As you can see in the tests below, this makes it possible to get different solutions in successive runs of the program.

sub zero-sum ($n) {
    my @result;
    for (1..$n*2).pick(($n/2).Int) -> $i {
        append @result, ($i, -$i);
    }
    append @result, 0 unless $n %% 2;
    return @result;
}
for 3, 4, 5, 1 -> $test {
    say "$test => ", zero-sum $test;
}

This program displays the following output (two successive runs):

$ raku ./zero-sum.raku
3 => [3 -3 0]
4 => [8 -8 6 -6]
5 => [7 -7 2 -2 0]
1 => [0]

~
$ raku ./zero-sum.raku
3 => [2 -2 0]
4 => [1 -1 5 -5]
5 => [6 -6 1 -1 0]
1 => [0]

Unique Sum Zero in Perl

This is essentially a port to Perl of the Raku program above, except that we don't pick random numbers, but simply consecutive integers. Please refer to the previous section if you need further explanations.

use strict;
use warnings;
use feature 'say';

sub zero_sum {
    my $n = shift;
    my @result;
    for my $i (1.. int $n/2) {
        push @result, ($i, -$i);
    }
    push @result, 0 if $n % 2;
    return @result;
}
for my $test (3, 4, 5,  1) {
    say "$test => ", join " ", zero_sum $test;
}

This program displays the following output:

$ perl ./zero-sum.pl
3 => 1 -1 0
4 => 1 -1 2 -2
5 => 1 -1 2 -2 0
1 => 0

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 January 28, 2024. 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.