Perl Weekly Challenge 353.
My solutions (task 1 and task 2 ) to the The Weekly Challenge - 353.
Task 1: Max Words
Submitted by: Mohammad Sajid Anwar
You are given an array of sentences.
Write a script to return the maximum number of words that appear in a single sentence.
Example 1
Input: @sentences = ("Hello world", "This is a test", "Perl is great")
Output: 4
Example 2
Input: @sentences = ("Single")
Output: 1
Example 3
Input: @sentences = ("Short", "This sentence has seven words in total", "A B C",
"Just four words here")
Output: 7
Example 4
Input: @sentences = ("One", "Two parts", "Three part phrase", "")
Output: 3
Example 5
Input: @sentences = ("The quick brown fox jumps over the lazy dog", "A",
"She sells seashells by the seashore",
"To be or not to be that is the question")
Output: 10
I’ll assume the input is in the form of period (“. “) separated sentences, and
each sentence is made of space separated words. Then I just have to
split the input to get all the sentences, split the sentences to get
their words, convert to scalar to get their number and choose the
maximum. I can use the max function from List::Util. This takes a
one-liner.
Examples:
perl -MList::Util=max -E '
for(@ARGV){say "$_ -> ", max map {0+split " "}split /\.\s*/}
' "Hello world. This is a test. Perl is great." "Single." \
"Short. This sentence has seven words in total. A B C. Just four words here." \
"One. Two parts. Three part phrase. ." \
"The quick brown fox jumps over the lazy dog. A.
She sells seashells by the seashore. To be or not to be that is the question."
Results:
Hello world. This is a test. Perl is great. -> 4
Single. -> 1
Short. This sentence has seven words in total. A B C. Just four words here. -> 7
One. Two parts. Three part phrase. . -> 3
The quick brown fox jumps over the lazy dog. A.
She sells seashells by the seashore. To be or not to be that is the question. -> 10
The full code is:
1 # Perl weekly challenge 353
2 # Task 1: Max Words
3 #
4 # See https://wlmb.github.io/2025/12/22/PWC353/#task-1-max-words
5 use v5.36;
6 use List::Util qw(max);
7 die <<~"FIN" unless @ARGV;
8 Usage: $0 S0 S1...
9 to find the maximum number of space-separated words in the period
10 separated phrases contained in the strings Sn.
11 FIN
12 for(@ARGV){
13 say "$_ -> ",
14 max # choose maximum
15 map {0+ # count words
16 split " " # separate into words
17 }
18 split /\.\s*/ # separate into sentences
19 }
20
Examples:
./ch-1.pl "Hello world. This is a test. Perl is great." "Single." \
"Short. This sentence has seven words in total. A B C. Just four words here." \
"One. Two parts. Three part phrase. ." \
"The quick brown fox jumps over the lazy dog. A.
She sells seashells by the seashore. To be or not to be that is the question."
Results:
Hello world. This is a test. Perl is great. -> 4
Single. -> 1
Short. This sentence has seven words in total. A B C. Just four words here. -> 7
One. Two parts. Three part phrase. . -> 3
The quick brown fox jumps over the lazy dog. A.
She sells seashells by the seashore. To be or not to be that is the question. -> 10
Task 2: Validate Coupon
Submitted by: Mohammad Sajid Anwar
You are given three arrays, @codes, @names and @status.
Write a script to validate codes in the given array.
A code is valid when the following conditions are true:
- codes[i] is non-empty and consists only of alphanumeric
characters (a-z, A-Z, 0-9) and underscores (_).
- names[i] is one of the following four categories:
"electronics", "grocery", "pharmacy", "restaurant".
- status[i] is true.
Return an array of booleans indicating validity: output[i]
is true if and only if codes[i], names[i] and status[i] are all valid.
Example 1
Input: @codes = ("A123", "B_456", "C789", "D@1", "E123")
@names = ("electronics", "restaurant", "electronics", "pharmacy", "grocery")
@status = ("true", "false", "true", "true", "true")
Output: (true, false, true, false, true)
Example 2
Input: @codes = ("Z_9", "AB_12", "G01", "X99", "test")
@names = ("pharmacy", "electronics", "grocery", "electronics", "unknown")
@status = ("true", "true", "false", "true", "true")
Output: (true, true, false, true, false)
Example 3
Input: @codes = ("_123", "123", "", "Coupon_A", "Alpha")
@names = ("restaurant", "electronics", "electronics", "pharmacy", "grocery")
@status = ("true", "true", "false", "true", "true")
Output: (true, true, false, true, true)
Example 4
Input: @codes = ("ITEM_1", "ITEM_2", "ITEM_3", "ITEM_4")
@names = ("electronics", "electronics", "grocery", "grocery")
@status = ("true", "true", "true", "true")
Output: (true, true, true, true)
Example 5
Input: @codes = ("CAFE_X", "ELEC_100", "FOOD_1", "DRUG_A", "ELEC_99")
@names = ("restaurant", "electronics", "grocery", "pharmacy", "electronics")
@status = ("true", "true", "true", "true", "false")
Output: (true, true, true, true, false)
I assume the input are comma separated strings with the codes, names
and statuses. I split them and zip them to make an array of references
of the form “[code, name, status]”. I test each against a
corresponding regular expression and if all are successful the result
is true, otherwise false. Finally, I output all results. This
takes a 2.5-liner.
Examples:
perl -MList::Util=zip -E '
for my($c,$n,$s)(@ARGV){say "\n$c\n$n\n$s\n -> ",join ", ",map{($x,$y,$z)=$_->@*;$x=~/^(\w|_)*$/
&&$y=~/^(electronics|grocery|pharmacy|restaurant)$/&&$z=~/^true$/?"T":"F"}(zip map {[split
/,\s*/]} $c, $n, $s)}
' "A123, B_456, C789, D@1, E123" "electronics, restaurant, electronics, pharmacy, grocery" \
"true, false, true, true, true" \
\
"Z_9, AB_12, G01, X99, test" "pharmacy, electronics, grocery, electronics, unknown" \
"true, true, false, true, true" \
\
"_123, 123,, Coupon_A, Alpha" "restaurant, electronics, electronics, pharmacy, grocery" \
"true, true, false, true, true" \
\
"ITEM_1, ITEM_2, ITEM_3, ITEM_4" "electronics, electronics, grocery, grocery" \
"true, true, true, true" \
\
"CAFE_X, ELEC_100, FOOD_1, DRUG_A, ELEC_99" \
"restaurant, electronics, grocery, pharmacy, electronics" \
"true, true, true, true, false"
Results:
A123, B_456, C789, D@1, E123
electronics, restaurant, electronics, pharmacy, grocery
true, false, true, true, true
-> T, F, T, F, T
Z_9, AB_12, G01, X99, test
pharmacy, electronics, grocery, electronics, unknown
true, true, false, true, true
-> T, T, F, T, F
_123, 123,, Coupon_A, Alpha
restaurant, electronics, electronics, pharmacy, grocery
true, true, false, true, true
-> T, T, F, T, T
ITEM_1, ITEM_2, ITEM_3, ITEM_4
electronics, electronics, grocery, grocery
true, true, true, true
-> T, T, T, T
CAFE_X, ELEC_100, FOOD_1, DRUG_A, ELEC_99
restaurant, electronics, grocery, pharmacy, electronics
true, true, true, true, false
-> T, T, T, T, F
The full code is:
1 # Perl weekly challenge 353
2 # Task 2: Validate Coupon
3 #
4 # See https://wlmb.github.io/2025/12/22/PWC353/#task-2-validate-coupon
5 use v5.36;
6 use feature qw(try);
7 use List::Util qw(zip);
8 die <<~"FIN" unless @ARGV and @ARGV%3==0;
9 Usage: $0 C0 N0 S0 C1 N1 S1...
10 to validate coupons. Cn, Nn and Sn ares a comma separated strings
11 containing codes, names and status, for the n-th list of coupons.
12 FIN
13 for my($codes, $names, $statuses)(@ARGV){
14 try {
15 my @together=zip map {[split /,\s*/]} $codes, $names, $statuses;
16 my @pass = map {
17 my ($code, $name, $status) = $_->@*;
18 die "Missing code: $codes" unless defined $code;
19 die "Missing name: $names" unless defined $name;
20 die "Missing status: $statuses" unless defined $status;
21 $code =~ /^(\w|_)*$/ # valid code?
22 && $name =~ /^(electronics|grocery|pharmacy|restaurant)$/i # valid name?
23 && $status =~ /^true$/i # valid status?
24 ? "True" : "False"
25 } @together;
26 my $pass = join ", ", @pass;
27 say "\n$codes\n$names\n$statuses\n -> $pass\n";
28 }
29 catch($e){ warn $e; }
30 }
31
Example:
./ch-2.pl \
"A123, B_456, C789, D@1, E123" "electronics, restaurant, electronics, pharmacy, grocery" \
"true, false, true, true, true" \
\
"Z_9, AB_12, G01, X99, test" "pharmacy, electronics, grocery, electronics, unknown" \
"true, true, false, true, true" \
\
"_123, 123,, Coupon_A, Alpha" "restaurant, electronics, electronics, pharmacy, grocery" \
"true, true, false, true, true" \
\
"ITEM_1, ITEM_2, ITEM_3, ITEM_4" "electronics, electronics, grocery, grocery" \
"true, true, true, true" \
\
"CAFE_X, ELEC_100, FOOD_1, DRUG_A, ELEC_99" \
"restaurant, electronics, grocery, pharmacy, electronics" \
"true, true, true, true, false"
/;