Peter
Peter Campbell Smith

Solo words and a cross matrix

Weekly challenge 266 — 22 April 2024

Week 266 - 22 Apr 2024

Task 1

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

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['']) . ')';
}   

Output


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