Perl Weekly Challenge 273.
My solutions (task 1 and task 2 ) to the The Weekly Challenge - 273.
Task 1: Percentage of Character
Submitted by: Mohammad Sajid Anwar
You are given a string, $str and a character $char.
Write a script to return the percentage, nearest whole,
of given character in the given string.
Example 1
Input: $str = "perl", $char = "e"
Output: 25
Example 2
Input: $str = "java", $char = "a"
Output: 50
Example 3
Input: $str = "python", $char = "m"
Output: 0
Example 4
Input: $str = "ada", $char = "a"
Output: 67
Example 5
Input: $str = "ballerina", $char = "l"
Output: 22
Example 6
Input: $str = "analitik", $char = "k"
Output: 13
The problem seems straightforward. I can split the string, choose the
characters that match count them, calculate the percentage and round
it. The code can be compacted using the tr
operator, which counts
matches. As it doesn’t interpolate, it must be evaled
. The results fit a oneliner:
Example 1:
perl -E '
($w,$c)=@ARGV; $l=length $w; say "str=$w, char=$c -> ", int(.5+100*(eval"\$w=~tr/$c//")/$l);
' perl e
Results:
str=perl, char=e -> 25
Example 2:
perl -E '
($w,$c)=@ARGV; $l=length $w; say "str=$w, char=$c -> ", int(.5+100*(eval"\$w=~tr/$c//")/$l);
' java a
Results:
str=java, char=a -> 50
Example 3:
perl -E '
($w,$c)=@ARGV; $l=length $w; say "str=$w, char=$c -> ", int(.5+100*(eval"\$w=~tr/$c//")/$l);
' python a
Results:
str=python, char=a -> 0
Example 4:
perl -E '
($w,$c)=@ARGV; $l=length $w; say "str=$w, char=$c -> ", int(.5+100*(eval"\$w=~tr/$c//")/$l);
' ada a
Results:
str=ada, char=a -> 67
Example 5:
perl -E '
($w,$c)=@ARGV; $l=length $w; say "str=$w, char=$c -> ", int(.5+100*(eval"\$w=~tr/$c//")/$l);
' ballerina l
Results:
str=ballerina, char=l -> 22
Example 6:
perl -E '
($w,$c)=@ARGV; $l=length $w; say "str=$w, char=$c -> ", int(.5+100*(eval"\$w=~tr/$c//")/$l);
' analitik k
Results:
str=analitik, char=k -> 13
Notice that the nearest integer to 12.5 is ambiguous, as it is equidistant from 12 and 13. The code above rounds up in this case.
For the full code, I simply split the string, grep
the matches and count them, to
avoid evali
-ing the tr
operator. I convert to lowercase to disregard case.
1 # Perl weekly challenge 273
2 # Task 1: Percentage of Character
3 #
4 # See https://wlmb.github.io/2024/06/10/PWC273/#task-1-percentage-of-character
5 use v5.36;
6 use experimental "for_list";
7 die <<~"FIN" unless @ARGV && @ARGV%2==0;
8 Usage: $0 S1 C1 S2 W2...
9 to find the percentage of character Ci in string Si.
10 FIN
11 for my ($str, $chr)(@ARGV){
12 my $length=length $str;
13 my $matches=0+grep{ lc($_) eq lc($chr)} split "", $str;
14 my $percentage = int(.5+100*$matches/$length);
15 say "str=$str, chr=$chr -> $percentage";
16 }
Example:
./ch-1.pl perl e java a python a ada a ballerina l analitik k
Results:
str=perl, chr=e -> 25
str=java, chr=a -> 50
str=python, chr=a -> 0
str=ada, chr=a -> 67
str=ballerina, chr=l -> 22
str=analitik, chr=k -> 13
Task 2: B After A
Submitted by: Mohammad Sajid Anwar
You are given a string, $str.
Write a script to return true if there is at least one b,
and no a appears after the first b.
Example 1
Input: $str = "aabb"
Output: true
Example 2
Input: $str = "abab"
Output: false
Example 3
Input: $str = "aaa"
Output: false
Example 4
Input: $str = "bbb"
Output: true
“A b, first followed by no a” can be captured by a simple regular expression, yielding a half liner.
Examples:
perl -E 'for(@ARGV){say "$_ -> ", /^[^b]*b[^a]*$/i?"true":"false"}' aabb abab aaa bbb
Results:
aabb -> true
abab -> false
aaa -> false
bbb -> true
The full code is similar:
1 # Perl weekly challenge 273
2 # Task 2: B After A
3 #
4 # See https://wlmb.github.io/2024/06/10/PWC273/#task-2-b-after-a
5 use v5.36;
6 die <<~"FIN" unless @ARGV;
7 Usage: $0 S1 S2...
8 to test the strings S1 S2... for B after A
9 FIN
10 for(@ARGV){
11 say "$_ -> ", /^[^b]*b[^a]*$/i?"true":"false"
12 }
Example:
./ch-2.pl aabb abab aaa bbb
Results:
aabb -> true
abab -> false
aaa -> false
bbb -> true
/;