diff options
| author | boblied <boblied@gmail.com> | 2023-01-27 11:23:19 -0600 |
|---|---|---|
| committer | boblied <boblied@gmail.com> | 2023-01-27 11:23:19 -0600 |
| commit | f8a32b4ca7a9d3974a900224af1bdb0309cf8142 (patch) | |
| tree | 731ec2e08ded0007377bf58eff01d67ef4ab0b56 | |
| parent | 0ccfbd5cfaa81d02a6743acf5667424f02089620 (diff) | |
| download | perlweeklychallenge-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.pl | 106 |
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; +} + |
