Peter’s blog ✴ Week 266 ✴ 22 April 2024

THE WEEKLY CHALLENGE
Solo words and a cross matrix

The Perl Camel

Task 1

Uncommon words

You are given two sentences, $line1 and $line2. Write a script to find all uncommmon words in any order in the given two sentences. Return ('') if none found. A word is uncommon if it appears exactly once in one of the sentences and doesn’t appear in the other sentence.

Examples


Example 1
Input: $line1 = 'Mango is sweet'
       $line2 = 'Mango is sour'
Output: ('sweet', 'sour')

Example 2
Input: $line1 = 'Mango Mango'
       $line2 = 'Orange'
Output: ('Orange')

Example 3
Input: $line1 = 'Mango is Mango'
       $line2 = 'Orange is Orange'
Output: ('')

Analysis

The task as stated boils down to finding any words that occur once anywhere in $line1 and $line2. So let's concatenate the 2 lines with a space between them, lower case the combination, and split it into an array of words.

Now let's make a hash %counts so that $counts{$word} is the frequency of $word ocurring in the array.

And lastly let's report all the words with a count of 1.

That's task accomplished in 3 lines of reasonably understandable code.

Perl Weekly’s review

from Perl Weekly issue 666

Love the simplicity in the solution. No gimmicks, pure solution. Get to try as well, really cool. Thanks for sharing.

Try it 

Try running the script with any input:



example: Some roses are red



example: Some roses are white

Script


#!/usr/bin/perl

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

use v5.26;    # The Weekly Challenge - 2024-04-22
use utf8;     # Week 266 - task 1 - Uncommon words
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';

uncommon_words('Mango is sweet', 'Mango is sour');
uncommon_words('Roses are red', 'Violets are blue');
uncommon_words('Red red roses are sweet', 'Roses are sweet');
uncommon_words('London is the capital of the UK', 'The capital of the UK is London');
uncommon_words('Alpha Bravo Charlie Delta Echo', 'Foxtrot Golf Hotel India Juliett');

sub uncommon_words {
    
    my (@words, %counts, $uncommon);
    
    # concatenate the lines, lower-cased, and count word frequency
    @words = split(/ +/, lc(qq[$_[0] $_[1]]));
    $counts{$_} ++ for @words;
    
    # find the words where frequency is 1
    $uncommon .= $counts{$_} == 1 ? qq['$_', ] : '' for sort keys %counts;
    
    # show the answer
    say qq[\nInput:  \$line1 = '$_[0]'\n        \$line2 = '$_[1]'];
    say qq[Output: (] . ($uncommon ? substr($uncommon, 0, -2) : q['']) . ')';
}   

7 lines of code

Output from script


Input:  $line1 = 'Mango is sweet'
        $line2 = 'Mango is sour'
Output: ('sour', 'sweet')

Input:  $line1 = 'Roses are red'
        $line2 = 'Violets are blue'
Output: ('blue', 'red', 'roses', 'violets')

Input:  $line1 = 'Red red roses are sweet'
        $line2 = 'Roses are sweet'
Output: ('')

Input:  $line1 = 'London is the capital of the UK'
        $line2 = 'The capital of the UK is London'
Output: ('')

Input:  $line1 = 'Alpha Bravo Charlie Delta Echo'
        $line2 = 'Foxtrot Golf Hotel India Juliett'
Output: ('alpha', 'bravo', 'charlie', 'delta', 'echo', 
         'foxtrot', 'golf', 'hotel', 'india', 'juliett')

 

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