Peter
Peter Campbell Smith

Greatest letter and
mashed arrays

Weekly challenge 264 — 8 April 2024

Week 264 - 8 Apr 2024

Task 1

Task — Greatest English letter

You are given a string, $str, made up of only alphabetic characters [a..zA..Z]. Write a script to return the greatest English letter in the given string. A letter is greatest if it occurs as lower and upper case. Also letter ‘b’ is greater than ‘a’ as ‘b’ appears after ‘a’ in the English alphabet.

Examples


Example 1
Input: $str = 'PeRlwEeKLy'
Output: L

There are two letters E and L that appears as lower 
and upper. The letter L appears after E, so the L is the 
greatest English letter.

Example 2
Input: $str = 'ChaLlenge'
Output: L

Example 3
Input: $str = 'The'
Output: ''

Analysis

I can think of several ways of meeting this challenge, but I think this one is probably the most efficient.

  • Sort the characters of $str in reverse (eg cbaCBA)
  • Loop over the lower case letters ($c) in the sorted string
  • Look for a match of $c.*$C where $C == uc($c)

Because of the reverse sort the first match will be the match which is the last alphabetically, and thus the greatest English letter in the string.

Try it 

Try running the script with any input:



example: An example which should give the result E

Script


#!/usr/bin/perl

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

use v5.26;    # The Weekly Challenge - 2024-04-08
use utf8;     # Week 264 - task 1 - Greatest English letter
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';

greatest_english_letter('PeRlwEeKLy');
greatest_english_letter('zebras live in London Zoo');
greatest_english_letter('Antelopes like chocolate');
greatest_english_letter('all lower case gives a null result');
greatest_english_letter('the lower case can come fiRst');
greatest_english_letter('maybe harder - yAaBbcCdDY');

sub greatest_english_letter {
    
    my ($str, $C, $c, $m);
    
    $str = shift;
    say qq[\nInput:  \$str = '$str'];
    
    # reverse sort characters of $str
    $str = join('', sort { $b cmp $a } split('', $str));
    
    # loop over lc chars in $str
    while ($str =~ m|([a-z])|g) {
        $C = uc($1);
        
        # test for uc same char
        next unless $str =~ m|$1.*$C|;
        say qq[Output: '$C'];
        return;
    }
    say qq[Output: ''];
}

Output

	
Input:  $str = 'PeRlwEeKLy'
Output: 'L'

Input:  $str = 'zebras live in London Zoo'
Output: 'Z'

Input:  $str = 'Antelopes like chocolate'
Output: 'A'

Input:  $str = 'all lower case gives a null result'
Output: ''

Input:  $str = 'the lower case can come fiRst'
Output: 'R'

Input:  $str = 'maybe harder - yAaBbcCdDY'
Output: 'Y'