Perl Weekly Challenge 180.

My solutions (task 1 and task 2 ) to the The Weekly Challenge - 180.

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

I can count each character in the and use ~List::MoreUtils::firstidx to find the index of the first character whose count equals 1. This yields a oneliner:

perl -MList::MoreUtils=firstidx -E '
for(@ARGV){@a=split ""; my %c; $c{$_}++ foreach(@a); $f=firstidx {$c{$_}==1} @a;
say "$f->$a[$f]" if $f>=0};
' "Perl Weekly Challenge" "Long Live Perl" "a lost cat act sola"

Results:

0->P
1->o

I could have used lc to avoid distinguishing upper from lower case characters, and I could filter out spaces and/or punctuation.

The full code is

 1  # Perl weekly challenge 180
 2  # Task 1: First unique character
 3  #
 4  # See https://wlmb.github.io/2022/08/29/PWC180/#task-1-first-unique-character
 5  use v5.36;
 6  use List::MoreUtils qw(firstidx);
 7  say "Usage: $0 S1 [S2...]\n to find the first unique character of strings S1, S2...\n"
 8      unless @ARGV;
 9  foreach(@ARGV){
10      my @chars=split ""; # or split "", lc or grep {/\S/} split...
11      my %count;
12      $count{$_}++ foreach(@chars);
13      my $first= firstidx {$count{$_}==1} @chars;
14      say "The first unique character of '$_' is $first->$chars[$first]" if $first>=0;
15      say "'$_' has no unique characters" if $first==-1;
16  }

Example:

./ch-1.pl  "Perl Weekly Challenge" "Long Live Perl" "a lost cat act sola"

Results:

The first unique character of 'Perl Weekly Challenge' is 0->P
The first unique character of 'Long Live Perl' is 1->o
'a lost cat act sola' has no unique characters

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)

The examples seem to filter the list leaving those elements that are larger or equal (not smaller or equal) to the given integer. I’ll assume the @ARGV contains $i followed by the elements of @n. Then, I can simply grep the list, yielding the following one-liner:

perl -E '($i,@n)=@ARGV; say join ", ", grep {$_>=$i} @n' 3 1 4 2 3 5
perl -E '($i,@n)=@ARGV; say join ", ", grep {$_>=$i} @n' 4 9 0 6 2 3 8 5
perl -E '($i,@n)=@ARGV; say join ", ", grep {$_>=$i} @n' 4 1 2 3

Results:

4, 3, 5
9, 6, 8, 5

The inequality may be reversed to leave the elements that are smaller or equal.

The full code is

 1  # Perl weekly challenge 180
 2  # Task 2: Trim List
 3  #
 4  # See https://wlmb.github.io/2022/08/29/PWC180/#task-2-trim-list
 5  use v5.36;
 6  die "Usage: $0 N E0 E1...\nto trim the list keeping elements En>=N."
 7      unless @ARGV>=2;
 8  my ($N, @list)=@ARGV;
 9  say "The elements of (", join(", ", @list),
10      ") larger than or equal to $N are (",
11      join(", ", grep {$_ >= $N} @list), ")";

./ch-2.pl 3 1 4 2 3 5
./ch-2.pl 4 9 0 6 2 3 8 5
./ch-2.pl 4 1 2 3

Results:

The elements of (1, 4, 2, 3, 5) larger than or equal to 3 are (4, 3, 5)
The elements of (9, 0, 6, 2, 3, 8, 5) larger than or equal to 4 are (9, 6, 8, 5)
The elements of (1, 2, 3) larger than or equal to 4 are ()
Written on August 29, 2022