PWC180 - Trim List

TL;DR

On with TASK #2 from The Weekly Challenge #180. Enjoy!

The challenge

You are given list of numbers, @n and an integer $i.

Write a script to trim the given list where element is less than or equal to the given integer.

Example 1

Input: @n = (1,4,2,3,5) and $i = 3
Output: (4,5)

Example 2

Input: @n = (9,0,6,2,3,8,5) and $i = 4
Output: (9,6,8,5)

The questions

There seems to have been a bit of back and forth with this challenge, so I will not pile stuff on. I’d stick to asking for any need of basic validation etc. etc.

Oh, and maybe if it’s OK to swap the two inputs, i.e. get $i first.

The solution

This trim function seems like an inverted grep, so why not implement it in these terms?

sub trim (&@) { my $cond = shift; grep { ! $cond->($_) } @_ }

This time we’re using old-fashioned prototypes, letting us write idiomatic cool and even readable stuff like this:

my @trimmed = trim { $_ <= $i } @n;

But hey, let’s wrap this too into its own function trim_le, and we obtain the following whole program:

#!/usr/bin/env perl
use v5.24;
use warnings;

sub trim (&@) { my $cond = shift; grep { ! $cond->($_) } @_ }
sub trim_le ($@) { my $i = shift; trim { $_ <= $i } @_      }

my $i = shift // 3;
my @start = @ARGV ? @ARGV : (1, 4, 2, 3, 5);
my @trimmed = trim_le $i, @start;
{local $" = ','; say "(@trimmed)" }

Raku goes pretty much along the same lines. I still have to get the hang of the alternative form for grep and other functions to put the operation after a colon and using the whatever. Whatever!

#!/usr/bin/env raku
use v6;

sub trim (&cond, *@items) { grep {! &cond($_) }, @items }
sub trim_le ($i, *@items) { trim {$_ <= $i}, @items }

sub MAIN ($i is copy = Nil, *@args) {
   ($i, @args) = 3, 1, 4, 2, 3, 5 unless defined $i;
   my @trimmed = trim_le($i, @args);
   put '(' ~ @trimmed.join(',') ~ ')';
}

Stay safe folks!


Comments? Octodon, , GitHub, Reddit, or drop me a line!