Peter’s blog ✴ Week 239 ✴ 16 October 2023

THE WEEKLY CHALLENGE
Pulling the strings

The Perl Camel

Task 2

Consistent strings

You are given an array of strings and an allowed string of distinct characters. A string is consistent if all characters in the string appear in the allowed string. Write a script to return the number of consistent strings in the given array.

Examples


Example 1
Input: @str = ("ad", "bd", "aaab", "baa", "badab")
       $allowed = "ab"
Output: 2

Strings "aaab" and "baa" are consistent since they only contain characters 'a' and 'b'.

Example 2
Input: @str = ("a", "b", "c", "ab", "ac", "bc", "abc")
       $allowed = "abc"
Output: 7

Example 3
Input: @str = ("cc", "acd", "b", "ba", "bac", "bad", "ac", "d")
       $allowed = "cad"
Output: 4

Strings "cc", "acd", "ac", and "d" are consistent.

Analysis

This is another task that Perl does easily. The key line in my solution is:

$count ++ if $strings[$j] =~ m|^[$allowed]+$|;

which is executed in a loop over all the strings. Note that $count has to be initialised to 0 to avoid a 'strict' warning if there are no consistent strings.

Perl Weekly’s review

from Perl Weekly issue 639

Perl core strength is in display for all to see. Cool attempt, well done.

Try it 

Try running the script with any input, for example:
@str = ad, bd, aaab, baa, badab
$allowed = ab



Script


#!/usr/bin/perl

use v5.16;    # The Weekly Challenge - 2023-10-16
use utf8;     # Week 239 task 2 - Consistent strings
use strict;   # Peter Campbell Smith
use warnings; # Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge

consistent_strings(['ad', 'bd', 'aaab', 'baa', 'badab'], 'ab');
consistent_strings(['a', 'b', 'c', 'ab', 'ac', 'bc', 'abc'], 'abc');
consistent_strings(['cc', 'acd', 'b', 'ba', 'bac', 'bad', 'ac', 'd'], 'cad');
consistent_strings(['perl', 'is', 'an', 'easy', 'language', 'to', 'use'], 'aegilnoprstuy');
consistent_strings(['perl', 'is', 'an', 'easy', 'language', 'to', 'use'], 'bcdfhjkmqvwxz');
    
sub consistent_strings {
    
    my (@strings, $allowed, $j, $count);
    
    $count = 0;
    @strings = @{$_[0]};
    $allowed = $_[1];
    
    # increment $count if $strings[$j] is conprised only from the letters in $_[1] (= allowed)
    for $j (0 .. @strings - 1) {
        $count ++ if $strings[$j] =~ m|^[$allowed]+$|;
    }

    say qq[\nInput:  \@str = ('] . join(q[', '], @strings) . q[')];
    say qq[        \$allowed = '$_[1]'];
    say qq[Output: $count]; 
}

10 lines of code

Output from script


Input:  @str = ('ad', 'bd', 'aaab', 'baa', 'badab')
        $allowed = 'ab'
Output: 2

Input:  @str = ('a', 'b', 'c', 'ab', 'ac', 'bc', 'abc')
        $allowed = 'abc'
Output: 7

Input:  @str = ('cc', 'acd', 'b', 'ba', 'bac', 'bad', 'ac', 'd')
        $allowed = 'cad'
Output: 4

Input:  @str = ('perl', 'is', 'an', 'easy', 'language', 'to', 'use')
        $allowed = 'aegilnoprstuy'
Output: 7

Input:  @str = ('perl', 'is', 'an', 'easy', 'language', 'to', 'use')
        $allowed = 'bcdfhjkmqvwxz'
Output: 0

 

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