perl logo Perl logo (Thanks to Olaf Alders)

The weekly challenge 314 - Task 1: Equal Strings

 1 #!/usr/bin/env perl
 2 # https://theweeklychallenge.org/blog/perl-weekly-challenge-314/#TASK1
 3 #
 4 # Task 1: Equal Strings
 5 # =====================
 6 #
 7 # You are given three strings.
 8 #
 9 # You are allowed to remove the rightmost character of a string to make all equals.
10 #
11 # Write a script to return the number of operations to make it equal otherwise -1.
12 #
13 ## Example 1
14 ##
15 ## Input: $s1 = "abc", $s2 = "abb", $s3 = "ab"
16 ## Output: 2
17 ##
18 ## Operation 1: Delete "c" from the string "abc"
19 ## Operation 2: Delete "b" from the string "abb"
20 #
21 ## Example 2
22 ##
23 ## Input: $s1 = "ayz", $s2 = "cyz", $s3 = "xyz"
24 ## Output: -1
25 #
26 ## Example 3
27 ##
28 ## Input: $s1 = "yza", $s2 = "yzb", $s3 = "yzc"
29 ## Output: 3
30 #
31 ############################################################
32 ##
33 ## discussion
34 ##
35 ############################################################
36 #
37 # At first, we check what's the minimum and maximum length of all
38 # given strings. If these lengths differ by more than one, then
39 # we can return -1 right away. Otherwise, if min and max are equal,
40 # then all strings are of the same length. If they are all equal,
41 # then we can return 0. Otherwise, we need to fall through to removing
42 # the last character of each string. We do this by reducing min by 1
43 # and then falling through to the handling of cases were the min and
44 # max lengths differ by exactly one.
45 # In this case, we remove the last character if the length is not
46 # equal to min and count this as an operation to make strings equal.
47 # if in the end, all elements are the same, we return the number of
48 # operations. Otherwise, we couldn't make all strings equal and return -1.
49 
50 use v5.36;
51 use List::Util qw(min max);
52 
53 equal_strings("abc", "abb", "ab");
54 equal_strings("ayz", "cyz", "xyz");
55 equal_strings("yza", "yzb", "yzc");
56 
57 sub equal_strings(@strings) {
58     say "Input: " . join(", ", @strings);
59     my $tmp = {};
60     my $min = min map {length($_)} @strings;
61     my $max = max map {length($_)} @strings;
62     if($max - $min > 1) {
63         return say "Output: -1";
64     }
65     if($max == $min) {
66         map { $tmp->{$_}++ } @strings;
67         if(scalar(keys(%$tmp)) > 1) {
68             $min--;
69         } else {
70             return say "Output: 0";
71         }
72     }
73     $tmp = {};
74     my $count = 0;
75     foreach my $elem (@strings) {
76         if(length($elem) > $min) {
77             $elem =~ s/.$//;
78             $count++
79         }
80         $tmp->{$elem}++;
81     }
82     if(scalar(keys(%$tmp)) == 1) {
83         say "Output: $count";
84     } else {
85         say "Output: -1";
86     }
87 }