Perl Weekly Challenge 110.

My solutions (task 1, task 2 and task 2a) to the The Weekly Challenge - 110.

Task 1: Valid Phone Numbers

Submitted by: Mohammad S Anwar

You are given a text file.

Write a script to display all valid phone numbers in the given text file.

Acceptable Phone Number Formats

+nn  nnnnnnnnnn
(nn) nnnnnnnnnn
nnnn nnnnnnnnnn

Input File
0044 1148820341
 +44 1148820341
  44-11-4882-0341
(44) 1148820341
  00 1148820341
Output
0044 1148820341
 +44 1148820341
(44) 1148820341

I guess it is enough to build one regular expression for each format and if any of them matchs, then the number is valid (Am I missing some subtlety somewhere?) I anchor the patterns to the beginning and end of the strings allowing for leading and trailing spaces, and I don’t chomp the input, so I don’t add newlines on output.

# Perl weekly challenge 110
# Task 2: Valid phone numbers
#
# See https://wlmb.github.io/2021/04/27/PWC110/#task-1-valid-phone-numbers
use strict;
use warnings;
use v5.12;
my $pattern= join '|', map {qr(^\s*$_\s*$)} qw(\+\d{2}\s\d{10} \\(\d{2}\\)\s\d{10} \d{4}\s\d{10});
print "Output:\n", grep {$_=~$pattern} <>;

Example:

./ch-1.pl <<EOF
0044 1148820341
+44 1148820341
44-11-4882-0341
(44) 1148820341
00 1148820341
EOF

Results:

Output:
0044 1148820341
+44 1148820341
(44) 1148820341

Task 2: Transpose File

Submitted by: Mohammad S Anwar

You are given a text file.

Write a script to transpose the contents of the given file.

#+beginexample Input File name,age,sex Mohammad,45,m Joe,20,m Julie,35,f Cristina,10,f Output: name,Mohammad,Joe,Julie,Cristina age,45,20,35,10 sex,m,m,f,f

#+endexample

This task is simple if we assume that all rows have the same number of fields and that there are no fields that are quoted strings containing commas. In that case I just build split the input strings into a 2D rectangular array and print its transpose by iterating the leftmost index befor the rightmost.

# Perl weekly challenge 110
# Task 2: Transpose file
#
# Simple version
# See https://wlmb.github.io/2021/04/27/PWC110/#task-2-transpose-file
use strict;
use warnings;
use v5.12;
my @input=map {chomp; [split /,/]} <>;
say join "\n", map { my $c=$_; join ",", map {$input[$_][$c]} 0..@input-1} 0..scalar @{$input[0]}-1;

Exampls:

./ch-2.pl <<EOF
name,age,sex
Mohammad,45,m
Joe,20,m
Julie,35,f
Cristina,10,f
EOF

Results:

name,Mohammad,Joe,Julie,Cristina
age,45,20,35,10
sex,m,m,f,f

If there is a risk of a more complicated input file I could employ one of the CSV modules and use the maximum number of columns. This allows quoted input strings with embedded commas, embedded spaces, missing fields, etc.

# Perl weekly challenge 110
# Task 2: Transpose file
#
# CSV version
# See https://wlmb.github.io/2021/04/27/PWC110/#task-2-transpose-file
use strict;
use warnings;
use v5.12;
use List::Util qw(max);
use Text::CSV qw(csv);
my $input=csv(in=>*ARGV);
my $Ncols=max map {scalar @{$input->[$_]}} @$input-1;
my $transposed=[map {my $c=$_; [map {$input->[$_][$c]} 0..@$input-1]} 0..$Ncols-1];
csv(in=>$transposed, out=>*STDOUT, eol=>$/);

Example:

./ch-2a.pl <<EOF
name,age,sex
Mohammad,45,m
Joe,20,m
Julie,35,f
Cristina,10,f
EOF

Results:

name,Mohammad,Joe,Julie,Cristina
age,45,20,35,10
sex,m,m,f,f

Slightly more complex example:

./ch-2a.pl <<EOF
name,age,sex
Mohammad,45,m
"Joe, Jr.",,m
Julie L.,35
Cristina,,f
EOF

Results:

name,Mohammad,"Joe, Jr.","Julie L.",Cristina
age,45,,35,
sex,m,m,,f
Written on April 27, 2021