The weekly challenge 264 - Task 1: Greatest English Letter

 1 #!/usr/bin/env perl
 2 # https://theweeklychallenge.org/blog/perl-weekly-challenge-264/#TASK1
 3 #
 4 # Task 1: Greatest English Letter
 5 # ===============================
 6 #
 7 # You are given a string, $str, made up of only alphabetic characters [a..zA..Z].
 8 #
 9 # Write a script to return the greatest english letter in the given string.
10 #
11 ### A letter is greatest if it occurs as lower and upper case. Also letter
12 ### ‘b’ is greater than ‘a’ if ‘b’ appears after ‘a’ in the English alphabet.
13 #
14 ## Example 1
15 ##
16 ## Input: $str = 'PeRlwEeKLy'
17 ## Output: L
18 ##
19 ## There are two letters E and L that appears as lower and upper.
20 ## The letter L appears after E, so the L is the greatest english letter.
21 #
22 ## Example 2
23 ##
24 ## Input: $str = 'ChaLlenge'
25 ## Output: L
26 #
27 ## Example 3
28 ##
29 ## Input: $str = 'The'
30 ## Output: ''
31 #
32 ############################################################
33 ##
34 ## discussion
35 ##
36 ############################################################
37 #
38 # First, we split the input string into its characters. We then
39 # calculate the lowercase version of the character. We fill some
40 # data into a hash of hashes:
41 # - The key of the outermost hash is the lowercase version of the
42 #   character
43 # - The key of the inner hash is the character in its original form
44 # - The value of the inner hash is just a true value
45 # This way, if both the upper- and lowercase form of a character are
46 # in the input string, the corresponding inner hash for the character
47 # will have two keys (the upper- and lowercase version).
48 # Now we simply walk through the reverse sorted keys of the outer hash.
49 # As soon as we find a character that has both upper- and lowercase
50 # versions in its inner hash, we have found the Greatest English Letter
51 # and can finish the loop.
52 
53 use strict;
54 use warnings;
55 
56 greatest_english_letter('PeRlwEeKLy');
57 greatest_english_letter('ChaLlenge');
58 greatest_english_letter('The');
59 
60 sub greatest_english_letter {
61    my $str = shift;
62    print "Input: '$str'\n";
63    my $all = {};
64    my $output = "''";
65    foreach my $c (split(//, $str)) {
66       $all->{lc($c)}->{$c} = 1;
67    }
68    foreach my $c (reverse sort keys %$all) {
69       next unless scalar(keys %{ $all->{$c} }) == 2;
70       $output = uc($c);
71       last;
72    }
73    print "Output: $output\n";
74 }