aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorboblied <boblied@gmail.com>2023-01-27 11:23:19 -0600
committerboblied <boblied@gmail.com>2023-01-27 11:23:19 -0600
commitf8a32b4ca7a9d3974a900224af1bdb0309cf8142 (patch)
tree731ec2e08ded0007377bf58eff01d67ef4ab0b56
parent0ccfbd5cfaa81d02a6743acf5667424f02089620 (diff)
downloadperlweeklychallenge-club-f8a32b4ca7a9d3974a900224af1bdb0309cf8142.tar.gz
perlweeklychallenge-club-f8a32b4ca7a9d3974a900224af1bdb0309cf8142.tar.bz2
perlweeklychallenge-club-f8a32b4ca7a9d3974a900224af1bdb0309cf8142.zip
Week 184 Task 2
-rw-r--r--challenge-184/bob-lied/perl/ch-2.pl106
1 files changed, 106 insertions, 0 deletions
diff --git a/challenge-184/bob-lied/perl/ch-2.pl b/challenge-184/bob-lied/perl/ch-2.pl
new file mode 100644
index 0000000000..bccc237400
--- /dev/null
+++ b/challenge-184/bob-lied/perl/ch-2.pl
@@ -0,0 +1,106 @@
+#!/usr/bin/env perl
+# vim:set ts=4 sw=4 sts=4 et ai wm=0 nu:
+#=============================================================================
+# ch-2.pl Perl Weekly Challenge Week 184 Task 2 Split Array
+#=============================================================================
+# Copyright (c) 2023, Bob Lied
+#=============================================================================
+# You are given list of strings containing 0-9 and a-z separated by space only.
+# Write a script to split the data into two arrays, one for integers and one
+# for alphabets only.
+# Example 1 Input: @list = ( 'a 1 2 b 0', '3 c 4 d')
+# Output: [[1,2,0], [3,4]] and [['a','b'], ['c','d']]
+# Example 2 Input: @list = ( '1 2', 'p q r', 's 3', '4 5 t')
+# Output: [[1,2], [3], [4,5]] and [['p','q','r'], ['s'], ['t']]
+#=============================================================================
+
+use v5.36;
+
+use constant NUMBER => 0;
+use constant LETTER => 1;
+
+use Getopt::Long;
+my $Verbose = 0;
+my $DoTest = 0;
+
+GetOptions("test" => \$DoTest, "verbose" => \$Verbose);
+exit(!runTest()) if $DoTest;
+
+# Use this module to show output of nested array references.
+# Doesn't exactly match the spec because it quotes numbers
+# and has no white space.
+use Data::Dumper;
+$Data::Dumper::Indent = 0;
+$Data::Dumper::Terse = 1;
+
+my $numLet = splitArray(@ARGV);
+say Dumper($numLet->[NUMBER]), ' and ', Dumper($numLet->[LETTER]);
+
+# Input is an array of strings.
+sub splitArray(@array)
+{
+ # Split each string into an array of digits and letters.
+ # Use _splitList to turn each string in the array into a pair of lists.
+ # The result is an array of pairs, where each pair contains two
+ # array references, [NUMBER] for numbers and [LETTER] for letters.
+ my @nlListPair = map { _splitList( split(' ', $_) ) } @array;
+
+ # This array will be our result.
+ my @numberLetter = ( [], [] );
+
+ for my $p ( @nlListPair )
+ {
+ # Notice that Example 2 implies that an empty list should be removed
+ # from the output. [1,2] has no letters and [p q r] has no numbers,
+ # but there are no corresponding empty lists in the output.
+ for my $type ( NUMBER, LETTER )
+ {
+ my $list = $p->[$type];
+ push @{$numberLetter[$type]}, $list if scalar(@$list);
+ }
+ }
+ return \@numberLetter;
+}
+
+# Given a list of digits and letters, partition the list into
+# an array of numbers and an array of letters. Returns a reference
+# to a pair of arrays where the first element is a list of numbers
+# and the second element is a list of letters.
+# Example: ('a', 1, 'x', 3) ==> [ [1,3], ['a','x'] ]
+sub _splitList(@list)
+{
+ my @numberLetter = ( [], [] );
+
+ for ( @list )
+ {
+ my $which = (m/\d/ ? NUMBER : LETTER);
+ push @{$numberLetter[$which]}, $_;
+ }
+
+ return \@numberLetter;
+}
+
+sub runTest
+{
+ use Test2::V0;
+
+ is( _splitList( qw(a 1 2 b 0) ), [[1,2,0], ['a','b' ]], 'Split a 1 2 b 0');
+ is( _splitList( qw(3 c 4 d ) ), [[3,4 ], ['c','d' ]], 'Split 3 c 4 d');
+ is( _splitList( qw(1 2 ) ), [[1,2 ], [ ]], 'Split 1 2');
+ is( _splitList( qw(p q r ) ), [[ ], ['p','q','r']], 'Split p q r');
+ is( _splitList( qw(s 3 ) ), [[3 ], ['s' ]], 'Split s 3');
+ is( _splitList( qw(4 5 t ) ), [[4,5 ], ['t' ]], 'Split 3 c 4 d');
+
+ is( splitArray( 'a 1 2 b 0', '3 c 4 d' ),
+ [ [[1,2,0], [3,4]], [['a','b'], ['c','d']] ], 'Example 1');
+ is( splitArray( '1 2', 'p q r', 's 3', '4 5 t' ),
+ [ [[1,2], [3], [4,5]], [['p','q','r'], ['s'], ['t']] ], 'Example 2');
+
+ is( splitArray( '1 2', '3 4', '5 6' ),
+ [ [[1,2], [3,4], [5,6]], [] ], 'No letters');
+ is( splitArray( 'a b', 'c d' ),
+ [ [] , [['a','b'], ['c','d']] ], 'No numbers');
+
+ done_testing;
+}
+