Peter
Peter Campbell Smith

Pulling the strings

Weekly challenge 239 — 16 October 2023

Week 239 - 16 Oct 2023

Task 2

Task — 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.

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]; 
}

Output


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