( …continues from previous week. )
Welcome to the Perl review pages for Week 180 of The Weekly Challenge! Here we will take the time to discuss the submissions offered up by the team, factor out some common methodologies that came up in those solutions, and highlight some of the unique approaches and unusual code created.
●︎ Why do we do these challenges?
I suppose any reasonable answer to that question would come from a field as wide ranging and varied as the people who choose to join the team. One thing, though, is clear: it’s not a competition, and there are no judges, even if there is a “prize” of sorts. About that – I think of it more as an honorarium periodically awarded to acknowledge the efforts we make towards this strange goal. So there’s no determination to find the fastest, or the shortest, or even, in some abstract way, the best way to go about things, although I’m certain the participants have their own aspirations and personal drives. As Perl is such a wonderfully expressive language, this provides quite a bit of fodder to the core idea of TMTOWTDI, producing a gamut of varied techniques and solutions.
Even the tasks themselves are often open to a certain amount of discretionary interpretation. What we end up with is a situation where each participant is producing something in the manner they personally find the most interesting and satisfying. Some team members will focus on carefully crafted complete applications, thoroughly vetting input data and handling every use case they can think up. Others choose to apply themselves to the logic of the underlying puzzle and making it work in the most elegant way they can. Some eschew modules they would ordinarily reach for, others embrace them, bringing to light wheels perhaps invented years ago that happen to exactly solve the problem in front of them today.
I’ve been considering this question for some time and have found one binding commonality between all of us out solving these challenges each week, in that however we normally live our lives, the task in front of us more than likely has nothing to do with any of that. And I think this has great value. We all do what we do, in the real world, and hopefully we do it well. The Weekly Challenge provides us with an opportunity to do something germane to that life yet distinctly different; if we only do the things we already know how to do then we will only do the same things over and over. This is where the “challenge” aspect comes into play.
So we can consider The Weekly Challenge as providing a problem space outside of our comfort zone, as far out from that comfort as we wish to take things. From those reaches we can gather and learn things, pick and choose and bring what we want back into our lives. Personally, I think that’s what this whole thing is about. YMMV.
And that, my friends, is why I’m here: to try and figure out ways to do just that.
So that’s that… I’m ready now — let’s go in and see what we can find.
For Added Context
Before we begin, you may wish to revisit either the pages for the original tasks or the summary recap of the challenge. But don’t worry about it, the challenge text will be repeated and presented as we progress from task to task.
Oh, and one more thing before we finally get started:
Getting in Touch with Us
Email › Please feel free to email me (Colin) with any feedback, notes, clarifications or whatnot about this review.
GitHub › Submit a pull request to us for any issues you may find with this page.
Twitter › Join the discussion on Twitter!
I’m always curious as to what the people think of these efforts. Everyone here at the PWC would like to hear any feedback you’d like to give.
Enough? Fine. So without even further ado…
• Task 1 • Task 2 • BLOGS •
TASK 1
First Unique Character
Submitted by: Mohammad S Anwar
You are given a string, $s
.
Write a script to find out the first unique character in the given string and print its index (0-based).
Example 1
Input: $s = "Perl Weekly Challenge"
Output: 0 as 'P' is the first unique character
Example 2
Input: $s = "Long Live Perl"
Output: 1 as 'o' is the first unique character
about the solutions
Adam Russell, Ali Moradi, Arne Sommer, Athanasius, Aut0exec, Bejoy Mathews, Cheok-Yin Fung, Colin Crain, Dario Mazzeo, Dave Jacoby, Duncan C. White, E. Choroba, Flavio Poletti, Jaldhar H. Vyas, James Smith, Jorg Sommrey, Julien Fiegehenn, Kueppo Wesley, Laurent Rosenfeld, Lubos Kolouch, Matthew Neleigh, Mohammad S Anwar, Niels van Dijke, Robert DiCicco, Roger Bell_West, Simon Green, Solathian, Stephen G Lynn, Steven Wilson, Ulrich Rieke, and W. Luis Mochan
Arrays and strings are two rather closely-related data structures, although one might not immediately realize this. In Perl they are held in very different containers: either an indexed Array or, in the case of a string, a simple Scalar. Internally, though, the string component of a scalar holds, in an invisibly complicated way hidden from the user, a pointer to a C-array of characters.
Consequently string characters can be referred to by index, just like an array. In the C language strings and arrays are essentially the same, but in Perl an Array data type has a bunch of clever additional metadata attached to it, such as its length, and first position.
Wait, first position? Don’t you mean last position? No, we get that from the length if we know the first, and Perl arrays always allocate a bit more memory than they strictly need to make adding (and removing) elements easier. So on a canvas of apportioned memory we overlay a sequence of scalar values, and hence we will need to know where to start. Clever, no?
Trust me, it’s intensely clever. There’s cleverness all over the “simple” Perl data types.
Strings, in fact, also use a similar device of allocating extra space in front of the first character but you really don’t need to know that right now.
Suffice to say strings and arrays at the deepest levels boil down to sequential slots in memory that can be managed arithmetically. Which is also the essence of a list in Perl, which can be thought of as an array without the data structure backing it up: a list is a sequence of scalars often contained in a stack.
Sure, there’s lots of hand-waving in that explanation but also I feel that’s a pretty good gist of the situation. This is all just provided as a public service, giving background as to why you can go the same sort of things one might think to do with an array, with strings, and why converting between the two forms has its own set of specialized functions to go about this. They’re kind of welded at the hip, when it comes down to it.
There were 31 submissions for the first task this past week.
FINDING a NEEDLE in a PILE of STRING
Stephen G Lynn, Bejoy Mathews, Dave Jacoby, Roger Bell_West, Dario Mazzeo, Mohammad S Anwar, Athanasius, Aut0exec, Solathian, Simon Green, E. Choroba, and Niels van Dijke
In the first of two list-based tasks this week we are asked to locate the position of the first unique value within the list. In order to do this will by necessity need to look at every position within the list at least once, to know for sure our final selection is unique,
Using two passes over the data makes the task fairly straightforward: in the first we count the incidence of each component element, and in the second find the first character that shows up only once. The first counting does not even need to be complete, as all we really care about is “once” or “more than once”.
The task can also be accomplished in a single pass, if we collect and update the necessary information as we go along. By the time we get to the end of the line we will, with a little care, know everything we need to make the call.
additional languages: Raku
blog writeup: PWC 180
We’ll start the ball rolling with Stephen, who appears to be quite fond of the letter ‘s’.
Alternately, having forcibly secured a foothold in the symbol table, he has chosen to fully develop his position there under that name before venturing further. Exploring code can be fraught with peril, and hence solidifying a strong base camp can be a very prudent course to pursue. And bonus if you also just happen to really like the letter ‘s’.
In any case here we are with a scalar, an array and a hash all named ‘s’ with differing sigils. The string ‘s’ is chopped into an array of characters ‘s’ that are processed into a frequency hash ‘s’. We can then iterate over the index values of the array, and, examining each character as a hash key, check its count. The first key whose count is 1 is unique, and hence our winner.
Further processing can now stop after the result is reported.
sub print_1st_unique_char_indx {
#-- parsimonious use of a single stash entry *s
local ($s) = shift;
local (@s, %s);
@s = split //, $s;
for $s (@s) {$s{$s}++;}
for $s (0 .. scalar(@s)-1) {
if ($s{$s[$s]}==1) {
print $s,"\n";
last;
}
}
}
An interesting approach is given by Bejoy, who makes a single top-level pass across the data. He examines for each letter position and then, using grep
, tests the prevalence of one-or-more second appearances in the array slice following it..
Or in other words, look at the first letter, and see if it occurs again. If it does then try the second, and see if the string following that contains a repeat. Continue until we find one that doesn’t, and note its position.
my @pwc = split('', $s);
my $pos=-1;
foreach(@pwc)
{
$pos++;
if (grep(/$pwc[$pos]/, @pwc[$pos..@pwc-1]) == 1) { print "The first unique character in '$s' is '$pwc[$pos]'\n"; exit }
}
In Dave’s first_uniq_char
we perform much the same action, yet use a second loop to replace the grep
. One tradeoff here is that once we find a single second instance we can short-circuit out of the inner loop and move on the next string index immediately.
sub first_uniq_char( $string ) {
my @string = split //, $string;
OUTER: for my $i ( 0 .. -1 + scalar @string ) {
my $c = $string[$i];
for my $j ( 0 .. -1 + scalar @string ) {
next if $i == $j;
my $d = $string[$j];
next OUTER if $c eq $d;
}
return $i;
}
return -1;
}
additional languages: Javascript, Kotlin, Lua, Postscript, Python, Raku, Ruby, Rust
blog writeup: RogerBW’s Blog: The Weekly Challenge 180: Unique Trim
Now Roger returns us to performing two discrete passes over the elements of a listified string, the first to bag the frequencies and the second to find the lowest index with a hashed count of 1.
A map
is used to make our bag, and a foreach
loop iterates over the index values.
sub firstunique($s) {
my @s = split '',$s;
my %cc;
map {$cc{$_}++} @s;
foreach my $i (0..$#s) {
if ($cc{$s[$i]} == 1) {
return $i;
}
}
return -1;
}
Here is another example of making a frequency hash, then using a C-style for
loop to traverse the string letter-by-letter using substr
, landing on the first character with a hash value of 1.
The difference here being that Dario does it in Italian.
my $s="Long Live Perl";
my %freq=();
for (my $i=0; $i<length($s); $i++){
$freq{substr($s,$i,1)}++;
}
for (my $i=0; $i<length($s); $i++){
my $c=substr($s,$i,1);
if ($freq{$c}==1){
print "$i '$c' e' il primo carattere univoco\n";
last;
}
}
additional languages: Python, Raku, Swift
Mohammad introduces an interpretative twist we haven’t seen before, in standardizing the case before counting their frequencies. This brings to light an ontological ambiguity on the nature of a “character”. If a character is an encoded numeric entity on a computer system, then “A” and “a” are different, as their bits are not the same. Any semantic similarities in the meaning of the glyphs is irrelevant. However looking at it another way strings are presumed to be textual, and texts are composed of letters, giving credence to the idea that “A” and “a” are minor grammatical variations on a single vowel that does not change, and hence in essence the same thing.
By lowercasing before counting, Mohammad places himself in the latter camp.
Interesting.
A quick search through the submissions reveals he is not alone.
sub first_unique_character($str) {
my @c = ();
my %c = ();
foreach my $c (split //, $str) {
next if $c eq ' ';
$c = lc $c;
if (exists $c{$c}) {
$c{$c}++;
}
else {
push @c, $c;
$c{$c} = 1;
}
}
my $i = 0;
foreach my $c (@c) {
if ($c{$c} == 1) {
return $i;
}
$i++;
}
}
additional languages: Raku
For example, the monk Athanasius makes the same assumption, quite explicitly in their notes, along with caveats on ignoring whitespace. Frankly this whole line of reasoning never occurred to me.
sub find_index
{
my ($s) = @_;
my %chars;
for my $char (split //, $s)
{
++$chars{ lc $char } if $char =~ / ^ [[:alpha:]] $ /x;
}
my $index;
for my $i (0 .. length( $s ) - 1)
{
my $key = lc substr( $s, $i, 1 );
if (exists $chars{ $key } && $chars{ $key } == 1)
{
$index = $i;
last;
}
}
return $index;
}
Member Aut0exec delivers a compact and direct solution that uses a regular expression to match out occurrences of each letter. The string is broken into an array of characters, then each is matched globally within the unaltered string.
foreach my $letter (split(//, $String)) {
my @matches = $String =~ /$letter/g;
if ( scalar(@matches) eq 1 )
{
print ("The first unique letter is: $letter at index: $i\n");
last;
}
$i++;
}
This approach makes me think that by using the /e
switch, a counter, and a toggle the whole thing could be done within a single expression.
Hmmm…
Member Solathian also employs a global match to find all occurrences of each letter, combining the whole operation into the conditional clause.
foreach my $char (@characters)
{
# skip spaces
if($char ne ' ')
{
#count the characters in the string
if( 1 == ($string =~ s/$char//g ) )
{
# if it is one then it is unique
say( "Output: $i as '$char' is the first unique character");
$returnVal = $i;
last;
}
}
$i++;
}
additional languages: Python
blog writeup: Weekly Challenge 180
The Perl regular expression engine is an awesome machine of sometimes incomprehensible power. Or perhaps just dangerously incomprehensible.
Ok, sure, that might be a little hyperbolic but frankly, not a lot. It is its own DSL and interpreter combo that may not be Turing complete, but certainly feels as through it is. The actual status, to my knowledge, remains unproven.
But with great power comes great complexity, and with complexity comes overhead. And overhead, in a general sense, is to be avoided.
Enter index
, which searches for a subpattern within a string. Because no backtracking is involved it doesn’t need the whole RE engine, and hence is very fast. Combined with substr
instead of making a new array to iterate over and we have a recipe for speed.
sub main($phrase) {
# Go through each character
foreach my $i (0 .. length($phrase)-2) {
# If the letter in that position does not occur later, print the index
if (index($phrase, substr($phrase, $i, 1), $i + 1) == -1) {
say $i;
return;
}
}
# Oh dear. Nothing unique!
say 'No unique characters!';
}
Although Choroba gives us a very nice comparative solution, with a tasting plate of subroutines served four ways, it was his regular expression version that really caught my eye:
sub first_unique_character_regex ($s) {
local $_ = $s;
s/\Q$1//g while /(.).*\1/g;
return length ? index $s, substr $_, 0, 1 : -1;
}
What’s happening here? It’s important to realize the conditional match in the while
will be executed first, which will match the first character in the string, capturing it into $1, just as long as a second occurrence is found later in the string. Should a match be found, the earlier substitution will remove all traces of that character from the string and we will go around again.
The conditional fails at the first non-repeating character, at which point we move to the return
statement. If the target string still has characters then we use index
to find the offset, which would be the number of characters we have stripped off the head before we finally found our unique value.
This is our index, or -1 is returned if we can’t find a non-repeating character.
Choroba provides several other solutions that are also very much worth a look, as always. Using two hashes, one recording uniqueness and the other positions of the first occurrences, proved the quickest in a shoot-out. I personally find this very interesting because I used two hashes myself in a very similar fashion.
use List::Util qw{ min };
sub first_unique_character_hash ($s) {
my %pos;
my $i = 0;
my %is_unique;
for my $ch (split //, $s) {
$is_unique{$ch} = ! exists $pos{$ch};
$pos{$ch} = $i++;
}
return min(@pos{ grep $is_unique{$_}, keys %pos }) // -1
}
Finally, what about a module function?
The List::Util
function uniq
did not prove useful to this particular task, as this only removes duplicates without preserving any original properties of uniqueness among array elements. There was, however, another function over in List::MoreUtils
that proved more promising.
This function is singleton
, and Niels is here to demonstrate it to us.
What singleton
does is filter a list, and only allow unique, solitary values through. The result is a list of unique elements with non-unique values completely removed. By splitting a string, applying the function and rejoining the filtered result he constructs a string of only the unique characters from the original.
This sting is then used to construct a character class, which when inserted into a regular expression minimally matching everything from the front of the original string up to the first single member of the character class. The magic then is that the length of this match, returned, will be the offset of the first unique character.
Yes it is kind of convoluted but also great.
use List::MoreUtils qw(singleton);
sub firstUniqueChar($) {
my $re = sprintf '(?i)(.*?)([%s])', join '',singleton split //,lc $_[0];
my (@r) = $_[0] =~ m#$re#;
return [length $r[0], $r[1]];
}
Blogs and Additional Submissions in Guest Languages for Task 1:
NOTES
additional languages: Prolog
blog writeup: First Uniquely Trimmed Index – Perl – RabbitFarm ( Perl )
blog writeup: First Uniquely Trimmed Index – Prolog – RabbitFarm ( Prolog )
additional languages: C++, D, Lua, Modula-3, Nim, Pascal, Python, Raku
additional languages: Raku
blog writeup: Unique Trim with Raku and Perl - Arne Sommer
additional languages: Raku
blog writeup: Second to None - Programming Excursions in Perl and Raku
additional languages: C
additional languages: Raku
blog writeup: PWC180 - First Unique Character - ETOOBUSY
additional languages: Raku
blog writeup: Perl Weekly Challenge: Week 180
blog writeup: Perl Weekly Challenge #180
additional languages: D, Javascript, Julia, Kotlin, Lua, Python, Raku, Ring, Ruby, Scala
blog writeup: Perl Weekly Challenge 180: First Unique Character and Trim List
additional languages: Python
additional languages: Julia, Raku, Ruby
additional languages: C++, Haskell, Raku, Rust
blog writeup: Perl Weekly Challenge 180 – W. Luis Mochán
TASK 2
Trim List
Submitted by: Mohammad S Anwar
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,3,5)
Example 2
Input: @n = (9,0,6,2,3,8,5) and $i = 4
Output: (9,6,8,5)
about the solutions
Adam Russell, Ali Moradi, Arne Sommer, Athanasius, Aut0exec, Bejoy Mathews, Cheok-Yin Fung, Colin Crain, Dario Mazzeo, Dave Jacoby, Duncan C. White, E. Choroba, Flavio Poletti, Jaldhar H. Vyas, James Smith, Jorg Sommrey, Kueppo Wesley, Laurent Rosenfeld, Lubos Kolouch, Matthew Neleigh, Mohammad S Anwar, Niels van Dijke, Robert DiCicco, Roger Bell_West, Simon Green, Solathian, Stephen G Lynn, Steven Wilson, Ulrich Rieke, and W. Luis Mochan
The UNIX utility grep
is an acronym from the three terms “Global”, “Regular Expression”, and “Print”. It’s a handy search tool created by Ken Thompson that selects terms from all items in an input list — originally filenames — that match a given expression, printing the positive results.
This idea, of taking a large pool of data and extracting only those parts that match certain criteria, is known as a filter. In Perl, the regular expression component is generalized to a block of code that returns either true of false for a given input. This generalized idea, in turn, of applying a code block, or function, to a list or stream of data to determine a result, is a basic component of the functional programming paradigm.
There were 30 submissions for the second task this past week.
A SELECTION of SUBMISSIONS
Ali Moradi, Matthew Neleigh, Niels van Dijke, Duncan C. White, W. Luis Mochan, Dario Mazzeo, Aut0exec, Flavio Poletti, Cheok-Yin Fung, James Smith, and Stephen G Lynn
Basically what we are being asked to do here is implement grep
, either calling it directly or by reproducing the functionality in a filter. As it is already a built-in function integral to the language just using grep
was by far the most common approach. However some submissions chose more elemental reconstructive solutions, sequentially processing and comparing the input list items.
additional languages: C++, D, Lua, Modula-3, Nim, Pascal, Python, Raku
Ali will start us off with a demonstration on the use of grep
.
sub trim_list{
my ($arr, $i) = @_;
grep {$_ > $i} @$arr;
}
The block we are applying is {$_ > $i}
, which sets the special variable $_
, known as the topic, to each element in the input subroutine stack in turn.
grep
returns a list of all elements that resolve to true within the block. This, because it is the last operation in a subroutine that does not otherwise explicitly return, is passed through and returned by the subroutine.
Matthew takes a lower-level approach, and a more strict interpretation of the directive to “trim the given list”. In this he operates on a reference for his input, and alters the original array in-place rather than returning a copy.
A while loop is used with an external index variable. At each cycle the list element at the index is examined, and if it satisfies the condition it is left alone, the index incremented and the next element selected. If the condition fails, however, splice
is used to remove the element from the list. As the list is now one element shorter, the index now points to the next element already.
sub trim_list_by_value{
my $list = shift();
my $n = int(shift());
my $i = 0;
# Loop while $i is within the array
while($i <= $#$list){
if($list->[$i] > $n){
# This value doesn't meet search criteria;
# move on (increment $i)
$i++;
} else{
# This value meets search criteria; remove
# it (and shrink the list)
splice(@{$list}, $i, 1);
}
}
}
additional languages: C
It’s not clear whether recopying or in-place alteration of the actual input list is the purest expression of the operation. Each has its own virtue, either to preserve memory or to be able to return to the unaltered list later. Ultimately the best choice will depend on the final application.
@list = grep { $_ >= $i } @list;
say '('.join(',', @list ).')';
In an unexpected twist Niels covers all bases, and depending on what is being assigned from the function returns either a newly-minted array of values or simply overwrites the input reference with new data from the filtered list.
sub trimList (\@$) {
my ($ar,$v) = @_;
if (wantarray) {
grep { $_ > $v } @$ar;
} else {
@$ar = grep { $_ > $v } @$ar;
}
}
blog writeup: Perl Weekly Challenge 180 – W. Luis Mochán
Using grep
the combined actions can be placed into one compact line. Even if we include some verbose commentary, as Luis has done here.
say "The elements of (", join(", ", @list),
") larger than or equal to $N are (",
join(", ", grep {$_ >= $N} @list), ")";
To avoid just repeating the grep
form of example over and over, I’ll try and seek out any variations where they lie.
Here Dario constructs his own loop, examining each element in turn and either pushing it onto a new output list or passing it by. This is, after all, the essential action behind grep
, albeit that producing an anonymous array to be assigned.
Dario pretty-prints the output array and a comma-separated list within parentheses, which is both clear and has a nice look.
my @out=();
foreach my $j (@n){
if ($j>$i){
push(@out, $j);
}
}
my $output="(@out)";
$output=~s/ /,/g;
print "$output\n";
A regular expression is used to swap the spaces placed by the double-quote operator for commas, which works fine, but something many people do not seem to know is that the behavior of the double quotes when given an array is configurable! Buried within the noisy glyph-scape that holds the many Perl special variables we find $"
, which is easy to remember because it’s the variable for double quotes. Its formal, long name is $LIST_SEPARATOR
, and it specifies the character placed between elements of a list when interpolated. Remember all arrays are lists but not all lists are arrays.
Because the configuration is by default global, it’s commonly redefined using the local
declaration, limiting its scope to the current block.
And furthermore the more modern say
is just like print
but adds a linefeed. So the output section could be compactly rewritten using Perl idioms as:
local $" = ', ';
say "($output)";
Nice, right?
The use of local
is not necessary, nor is any declarative statement in fact, as the special variable $"
comes pre-defined. The main purpose of using local
is that in more complex environments a global change may break some other interpolation placed far away, potentially bringing in a had-to-trace bug.
Here Aut0exec provides a more stripped down example, with most of the processing encapsulated in a single line of code.
my @List = split(/,/, $ARGV[0]);
my $Int = $ARGV[1];
my @Filtered;
foreach (@List) { push(@Filtered, $_) unless $_ <= $Int; }
$"=',';
print ("Filtered list is: @Filtered \n");
But since I seem to be discussing conventions, I will mention those capitalized variable names, although perfectly legal, throw me off. $Int
scans to me like a type declaration, making me question where I am and many of the dubious life choices I have made over the years. And I don’t particularly like that train of thought. There’s a time and a place for that, like for instance my therapist’s office. Lowercase and underscores, “snake_case” is the convention, and I’m honestly not a fan of single letters except in the most obvious throw-away cases.
Obviously in a language that prides itself on TIMTOWTDI these particulars will be in some dispute, and YMMV.
additional languages: Raku
blog writeup: PWC180 - Trim List - ETOOBUSY
Here Flavio demonstrates proper safe-coding procedures by explicitly placing his output within its own containing block.
We also have a really interesting replacement for some of the generalized functionality of grep
, with the function trim_le
, for “less-than or equal to”. Or maybe “learner’s edition”, but I doubt it.
This function in turn calls the function trim
handing it a coderef containing a conditional block, which can happen by benefit of the function prototype &@
. This says to take a reference to, passing a coderef and an array reference. Done this way we can pass the wrapper function a low shelf value and the array to be trimmed, all without parentheses.
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)" }
With the inherent structural brevity of the grep
solution, some people took in on themselves to make that an end in itself.
CY has crafted her grep
code to fit on a single line, to be used from the shell under perl -nE
.
@a = split /\D/, $_; say join " ", grep { $_ > $a[0]} @a #perl -nE
# perl -nE '@a = split /\D/, $_; say join " ", grep { $_ > $a[0]} @a'
# [input] 3 1 4 2 3 5
# [output] 4 5
# [input] 4 9 0 6 2 3 8 5
# [output] 9 6 8 5
blog writeup: Perl Weekly Challenge #180
When inscribing monuments in stone, the Romans eschewed punctuation and interstitial spacing between letters, only grudgingly acquiescing to divid sentence-level concepts into separate lines. The argument was that when literally chiseling granite plinths you really wanted to be terse and direct, and did not want to run out of space and have to start over. Punctuation in that context is a frivolous luxury.
As goeth the Romans, so goes James. He does helpfully provide us with a pre-compacted version first, which is nice.
sub filter {
grep { $_ > $_[0] } @{ $_[1] }
}
sub f{grep{$_>$_[0]}@{$_[1]}}
additional languages: Julia, Raku
blog writeup: PWC 180
And finally, we have a different method to review! But talk about bringing a bomb to a knife-fight: Stephen hauls in the PDL, the Perl Data Language extensions, to do his work.
And short work that is. As it turns out the PDL has a list comprehension function where
that works much the same as grep
or a WHERE
clause in SQL. Or set theory, for that matter, with its vertical bar. Or any of a gamut of other languages that offer a formal list comprehension scheme.
Anyhoo, where
it is, and what it is is all elements of the piddle $n
that are greater than $i
.
use PDL;
use PDL::NiceSlice;
use PDL::AutoLoader;
sub trim {
my ($i,@n)=@_;
my $n = pdl @n;
return $n->where($n >= $i);
}
Blogs and Additional Submissions in Guest Languages for Task 2:
additional languages: Prolog
blog writeup: First Uniquely Trimmed Index – Perl – RabbitFarm ( Perl )
blog writeup: First Uniquely Trimmed Index – Prolog – RabbitFarm ( Prolog )
additional languages: Raku
blog writeup: Unique Trim with Raku and Perl - Arne Sommer
additional languages: Raku
blog writeup: Second to None - Programming Excursions in Perl and Raku
additional languages: Raku
blog writeup: Perl Weekly Challenge: Week 180
additional languages: Awk, C, D, Go, Javascript, Julia, Kotlin, Lua, Pascal, Python, Raku, Ring, Ruby, Scala
blog writeup: Perl Weekly Challenge 180: First Unique Character and Trim List
additional languages: Python
additional languages: Python, Raku, Swift
additional languages: Julia, Lua, Raku, Ruby
additional languages: Javascript, Kotlin, Lua, Postscript, Python, Raku, Ruby, Rust
blog writeup: RogerBW’s Blog: The Weekly Challenge 180: Unique Trim
additional languages: Python
blog writeup: Weekly Challenge 180
additional languages: C++, Haskell, Raku, Rust
_________ THE BLOG PAGES _________
That’s it for me this week, people! Warped by the rain, driven by the snow, resolute and unbroken by the torrential influx, by some miracle I somehow continue to maintain my bearings.
Looking forward to next wave, the perfect wave, I am: your humble servant.
But if Your Unquenchable THIRST for KNOWLEDGE is not SLAKED,
then RUN (dont walk!) to the WATERING HOLE
and FOLLOW these BLOG LINKS:
( …don’t think, trust your training, you’re in the zone, just do it … )
Adam Russell
- First Uniquely Trimmed Index – Perl – RabbitFarm ( Perl )
- First Uniquely Trimmed Index – Prolog – RabbitFarm ( Prolog )
Arne Sommer
- Unique Trim with Raku and Perl - Arne Sommer ( Perl & Raku )
Colin Crain
Flavio Poletti
- PWC180 - First Unique Character - ETOOBUSY ( Perl & Raku )
- PWC180 - Trim List - ETOOBUSY ( Perl & Raku )
Jaldhar H. Vyas
- Perl Weekly Challenge: Week 180 ( Perl & Raku )
James Smith
- Perl Weekly Challenge #180 ( Perl )
Laurent Rosenfeld
- Perl Weekly Challenge 180: First Unique Character and Trim List ( Perl & Raku )
Roger Bell_West
- RogerBW’s Blog: The Weekly Challenge 180: Unique Trim ( Perl & Raku )
Simon Green
- Weekly Challenge 180 ( Perl )
Stephen G Lynn
- PWC 180 ( Perl & Raku )
W. Luis Mochan