Perl Weekly Challenge 219: Sorted Squares

These are some answers to the Week 219, task 1, 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 June 4, 2023 at 23:59). This blog post offers some solutions to this challenge. Please don’t read on if you intend to complete the challenge on your own.

Sorted Squares

You are given a list of numbers.

Write a script to square each number in the list and return the sorted list, increasing order.

Example 1

Input: @list = (-2, -1, 0, 3, 4)
Output: (0, 1, 4, 9, 16)

Example 2

Input: @list = (5, -4, -1, 3, 6)
Output: (1, 9, 16, 25, 36)

Sorted Squares in Raku

This is quite simple. The program uses a pipeline to chain a code block to replace the input values by their squares (map {$_²}) and the sort routine. Note that, in Raku, the sort built-in function is clever enough to sort numbers numerically and strings lexicographically, so that we don't need to specify the type of sort we want to use. Please also note that the ² postfix operator returns the square of the operand.

sub sorted-squares (@in) {
    return sort map {$_²}, @in;
}

for (-2, -1, 0, 3, 4), (5, -4, -1, 3, 6) -> @test {
    say "@test[]".fmt("%-15s => "), sorted-squares @test;
}

This program displays the following output:

$ raku ./sorted-squares.raku
-2 -1 0 3 4     => (0 1 4 9 16)
5 -4 -1 3 6     => (1 9 16 25 36)

This script is so simple that we can transform it into a Raku one-liner:

$ raku -e 'say sort map {$_²}, @*ARGS' -2 -1 0 3 4
(0 1 4 9 16)

Sorted Squares in Perl

This is a port to Perl of the same data pipeline. Please refer to the above section for explanations if needed. Note that, in Perl, we need to specify that we want a numeric sort (with the {$a <=> $b} block).

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

sub sorted_squares {
    return sort {$a <=> $b} map $_ * $_, @_;
}

for my $test ([-2, -1, 0, 3, 4], [5, -4, -1, 3, 6]) {
    printf "%-15s => ", "@$test";
    say join " ", sorted_squares @$test;
}

This program displays the following output:

$ perl ./sorted-squares.pl
-2 -1 0 3 4     => 0 1 4 9 16
5 -4 -1 3 6     => 1 9 16 25 36

Note that we can also turn this program into a simple Perl one-liner:

$ perl -E 'say join " ", sort {$a <=> $b} map $_ * $_, 
    @ARGV'  2 -1 0 -3 4
0 1 4 9 16

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 June 11, 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.