1 #!/usr/bin/perl 2 # https://theweeklychallenge.org/blog/perl-weekly-challenge-208/#TASK1 3 # 4 # Task 1: Minimum Index Sum 5 # ========================= 6 # 7 # You are given two arrays of strings. 8 # 9 # Write a script to find out all common strings in the given two arrays with minimum index sum. If no common strings found returns an empty list. 10 # 11 ## Example 1 12 ## 13 ## Input: @list1 = ("Perl", "Raku", "Love") 14 ## @list2 = ("Raku", "Perl", "Hate") 15 ## 16 ## Output: ("Perl", "Raku") 17 ## 18 ## There are two common strings "Perl" and "Raku". 19 ## Index sum of "Perl": 0 + 1 = 1 20 ## Index sum of "Raku": 1 + 0 = 1 21 # 22 ## Example 2 23 ## 24 ## Input: @list1 = ("A", "B", "C") 25 ## @list2 = ("D", "E", "F") 26 ## 27 ## Output: () 28 ## 29 ## No common string found, so no result. 30 # 31 ## Example 3 32 ## 33 ## Input: @list1 = ("A", "B", "C") 34 ## @list2 = ("C", "A", "B") 35 ## 36 ## Output: ("A") 37 ## 38 ## There are three common strings "A", "B" and "C". 39 ## Index sum of "A": 0 + 1 = 1 40 ## Index sum of "B": 1 + 2 = 3 41 ## Index sum of "C": 2 + 0 = 2 42 # 43 ############################################################ 44 ## 45 ## discussion 46 ## 47 ############################################################ 48 # 49 # We have to find the index for every string in both arrays. 50 # Then we find the index sum for each string. 51 # Then we find the minimum value for the sums. 52 # Then we output every string that has this minimum value as its sum. 53 54 use strict; 55 use warnings; 56 use List::Util qw(min); 57 58 index_sum( ["Perl", "Raku", "Love"], ["Raku", "Perl", "Hate"] ); 59 index_sum( ["A", "B", "C"], ["D", "E", "F"] ); 60 index_sum( ["A", "B", "C"], ["C", "A", "B"] ); 61 62 sub index_sum { 63 my ($l1, $l2) = @_; 64 my @list1 = @$l1; 65 my @list2 = @$l2; 66 my @result = (); 67 my $index_data = {}; 68 print "Input: (" . join(", ", @list1) . "); (" . join(", ", @list2) . ")\n"; 69 # find the index for every string in list1 70 foreach my $i (0..$#list1) { 71 my $value = $list1[$i]; 72 $index_data->{$value}->{"list1_index"} = $i; 73 } 74 # find the index for every string in list2 75 foreach my $j (0..$#list2) { 76 my $value = $list2[$j]; 77 $index_data->{$value}->{"list2_index"} = $j; 78 } 79 # for each found string, if it exists in both lists, calculate the sum 80 my @sums = (); 81 foreach my $v (keys %$index_data) { 82 if(defined($index_data->{$v}->{"list1_index"}) 83 && defined($index_data->{$v}->{"list2_index"})) { 84 $index_data->{$v}->{"sum"} = 85 $index_data->{$v}->{"list1_index"} 86 + $index_data->{$v}->{"list2_index"}; 87 push @sums, $index_data->{$v}->{"sum"}; 88 } 89 } 90 # calculate the minimum sum 91 my $minimum = min(@sums); 92 # find all values that share the minimum index sum 93 foreach my $v (keys %$index_data) { 94 if(defined($index_data->{$v}->{"sum"})) { 95 if($index_data->{$v}->{"sum"} == $minimum) { 96 push @result, $v; 97 } 98 } 99 } 100 # in order to avoid a random sort order of the results we sort by 101 # their index in list1 102 print "Output: (" . join(", ", 103 sort { 104 $index_data->{ $a }->{"list1_index"} <=> 105 $index_data->{ $b }->{"list1_index"} } 106 @result) . ")\n"; 107 }