The weekly challenge 335 - Task 1: Common Characters
1 #!/usr/bin/env perl 2 # https://theweeklychallenge.org/blog/perl-weekly-challenge-335/#TASK1 3 # 4 # Task 1: Common Characters 5 # ========================= 6 # 7 # You are given an array of words. 8 # 9 # Write a script to return all characters that is in every word in the given array including duplicates. 10 # 11 ## Example 1 12 ## 13 ## Input: @words = ("bella", "label", "roller") 14 ## Output: ("e", "l", "l") 15 # 16 # 17 ## Example 2 18 ## 19 ## Input: @words = ("cool", "lock", "cook") 20 ## Output: ("c", "o") 21 # 22 # 23 ## Example 3 24 ## 25 ## Input: @words = ("hello", "world", "pole") 26 ## Output: ("l", "o") 27 # 28 # 29 ## Example 4 30 ## 31 ## Input: @words = ("abc", "def", "ghi") 32 ## Output: () 33 # 34 # 35 ## Example 5 36 ## 37 ## Input: @words = ("aab", "aac", "aaa") 38 ## Output: ("a", "a") 39 # 40 ############################################################ 41 ## 42 ## discussion 43 ## 44 ############################################################ 45 # 46 # We do this one in multiple passes: 47 # 1. split each word into its characters and count how often each character 48 # appears in it 49 # 2. initialize an output data hash with the first hash from the resulting 50 # array 51 # 3. for each each character in the keys of that hash and for each hash in the 52 # array, check whether the character appears in the hash. If it doesn't, 53 # remove it from the output data hash. If it does, set the corresponding 54 # value in the data output hash to the minimum of the two current values 55 # 4. collect the remaining characters and the number of their occurrences to 56 # create the output array 57 58 use v5.36; 59 60 common_characters("bella", "label", "roller"); 61 common_characters("cool", "lock", "cook"); 62 common_characters("hello", "world", "pole"); 63 common_characters("abc", "def", "ghi"); 64 common_characters("aab", "aac", "aaa"); 65 66 sub common_characters( @words ) { 67 say "Input: (\"" . join("\", \"", @words) . "\")"; 68 my @data = (); 69 foreach my $word (@words) { 70 my $tmp = {}; 71 foreach my $char (split //, $word) { 72 $tmp->{$char}++; 73 } 74 push @data, $tmp; 75 } 76 my $output = { %{$data[0]} }; 77 foreach my $hash (@data) { 78 foreach my $char (keys %$output) { 79 if($hash->{$char}) { 80 $output->{$char} = $hash->{$char} if $hash->{$char} < $output->{$char}; 81 } else { 82 delete $output->{$char}; 83 } 84 } 85 } 86 my @out = (); 87 foreach my $char (keys %$output) { 88 foreach my $count (1..$output->{$char}) { 89 push @out, $char; 90 } 91 } 92 say "Output: (" . join(", ", map {"\"$_\""} @out) . ")"; 93 }