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 ()