Peter
Peter Campbell Smith

Broken digits

Weekly challenge 275 — 24 June 2024

Week 275 - 24 Jun 2024

Task 1

Task — Broken keys

You are given a $sentence and a list of broken @keys. Write a script to find out how many words can be typed fully.

Examples


Example 1
Input: $sentence = "Perl Weekly Challenge", 
     @keys = ('l', 'a')
Output: 0

Example 2
Input: $sentence = "Perl and Raku", 
     @keys = ('a')
Output: 1
Only Perl since the other word two words contain 'a' 
and can't be typed fully.

Example 3
Input: $sentence = "Well done Team PWC", 
     @keys = ('l', 'o')
Output: 2

Example 4
Input: $sentence = "The joys of polyglottism", 
     @keys = ('T')
Output: 2

Analysis

My solution consists essentially of two lines. The first is:

$sentence =~ s|$_|#|g for @keys;

which changes all the @keys characters into '#'.

The second is

$count += ($_ !~ m|#| ? 1 : 0) 
        for split(/ /, $sentence);

which splits $sentence into words and counts the ones that don't contain a '#'.

Note that example 4 above demonstrates that the matching of keys is case-independent, and I therefore lower-case both $sentence and @keys on input.

Try it 

Try running the script with any input:



example: this is not difficult



example: f, s

Script


#!/usr/bin/perl

# Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge

use v5.26;    # The Weekly Challenge - 2024-06-24
use utf8;     # Week 275 - task 1 - Broken keys
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';

my ($sentence, @keys);

broken_keys('Perl Weekly Challenge', 'l', 'a');
broken_keys('The joys of polyglottism', 'T');
broken_keys('Write a script to find out how many words can be typed fully', 'i', 'o');
broken_keys('All cows eat grass', 'b', 'd', 'f', 'h', 'i');
broken_keys('Vitamins keep you healthy', 'v', 'k', 'u', 'y');

sub broken_keys {
    
    my ($sentence, @keys, $count);
    
    printf(qq[\nInput:  \$sentence = ('%s'), \@keys = ('%s')\n], $_[0], join(q[', '], @_[1 .. @_ - 1]));
    $sentence = lc(shift @_);
    push @keys, lc($_) for @_;
    
    # change any occurrences of keys to '#'
    $sentence =~ s|$_|#|g for @keys;
    
    # count the words which don't contain '#'
    $count += ($_ !~ m|#| ? 1 : 0) for split(/ /, $sentence);
    
    printf(qq[Output: %s\n], defined $count ? $count : 0);
}

Output


Input:  $sentence = ('Perl Weekly Challenge'), @keys = ('l', 'a')
Output: 0

Input:  $sentence = ('The joys of polyglottism'), @keys = ('T')
Output: 2

Input:  $sentence = ('Write a script to find out how many words can be typed fully'), @keys = ('i', 'o')
Output: 6

Input:  $sentence = ('All cows eat grass'), @keys = ('b', 'd', 'f', 'h', 'i')
Output: 4

Input:  $sentence = ('Vitamins keep you healthy'), @keys = ('v', 'k', 'u', 'y')
Output: 0