perl logo Perl logo (Thanks to Olaf Alders)

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 }