Peter’s blog ✴ Week 184 ✴ 26 September 2022

THE WEEKLY CHALLENGE
Sequence numbers and split arrays

The Perl Camel

Task 2

Split array

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 letters.

Examples


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']]

Analysis

Interestingly the formatting of the output is rather different from the input.

After a couple of false starts I decided that the best strategy was to treat the input simply as a string of characters. The only characters that matter are the digits, letters and commas. I append digits to $first and (single-quoted) letters to $second, in both cases appending ', '. When a comma is encountered in the input I append '], [' to both $first and $second.

It's then just a case of combining $first and $second and eliminating trailing commas and empty occurrences of [].

Perl Weekly’s review

from PW issue 584

Short and compact task analysis of the weekly challenge. Thanks for sharing.

This review may cover either or both challenges for this week.

I am sorry that the 'Try it' feature is currently working very slowly or not at all owing to some issue with my web hosting provider.

Try it 

Try running the script with any input:



example: 'a 1 2 b 0', '3 c 4 d'

Script


#!/usr/bin/perl

# Peter Campbell Smith - 2022-09-28
# PWC 184 task 2

use v5.28;
use utf8;
use warnings;

my (@lists, $list, $char, $first, $second, $output, $j);

# inputs
@lists = (qq['a 1 2 b 0', '3 c 4 d'], qq['1 2', 'p q r', 's 3', '4 5 t']);

for $list (@lists) {
    say qq[\nInput:  $list];
    $first = $second = '[';
    
    # loop over characters in list
    while ($list =~ m|(.)|g) {
        $char = $1;
        
        # a digit, append it and a comma to $first
        if ($char =~ m|[0-9]|) {
            $first .= qq[$char,];
            
        # a letter, append it and a comma to $second 
        } elsif ($char =~ m|[a-z]|i) {
            $second .= qq['$char',];
        
        # a comma, append '], [' to both $first and $second
        } elsif ($char eq ',') {
            $first .= '], [';
            $second .= '], [';
        }
    }
    
    # tweaks to eliminate empty [] pairs and convert ,] to ]
    $output = qq([$first]] and [$second]]);
    $output =~ s|,]|]|g;
    $output =~ s|\[],\s*||g;
    say qq[Output: $output];        
}

21 lines of code

Output from script


Input:  'a 1 2 b 0', '3 c 4 d'
Output: [[1,2,0], [3,4]] and [['a','b'], ['c','d']]

Input:  '1 2', 'p q r', 's 3', '4 5 t'
Output: [[1,2], [3], [4,5]] and [['p','q','r'], ['s'], ['t']]

 

Any content of this website which has been created by Peter Campbell Smith is in the public domain