The weekly challenge 313 - Task 1: Broken Keys
1 #!/usr/bin/env perl 2 # https://theweeklychallenge.org/blog/perl-weekly-challenge-313/#TASK1 3 # 4 # Task 1: Broken Keys 5 # =================== 6 # 7 # You have a broken keyboard which sometimes type a character more than once. 8 # 9 # You are given a string and actual typed string. 10 # 11 # Write a script to find out if the actual typed string is meant for the given 12 # string. 13 # 14 ## Example 1 15 ## 16 ## Input: $name = "perl", $typed = "perrrl" 17 ## Output: true 18 ## 19 ## Here "r" is pressed 3 times instead of 1 time. 20 # 21 ## Example 2 22 ## 23 ## Input: $name = "raku", $typed = "rrakuuuu" 24 ## Output: true 25 # 26 ## Example 3 27 ## 28 ## Input: $name = "python", $typed = "perl" 29 ## Output: false 30 # 31 ## Example 4 32 ## 33 ## Input: $name = "coffeescript", $typed = "cofffeescccript" 34 ## Output: true 35 # 36 ############################################################ 37 ## 38 ## discussion 39 ## 40 ############################################################ 41 # 42 # We walk $name from left to right and do the same with $typed, 43 # keeping track of the position in both strings. If at the current 44 # position, the characters don't match, we compare the character 45 # in $typed against the previous character from $name because we're 46 # still fine if we have a match this way. If we're through with $typed, 47 # but not with $name, we can return "false". Otherwise, once we're 48 # through with $name we only need to check if all remaining characters 49 # from $typed are the same as the last character in $name. If we have 50 # any remainder in $typed, then we can return false as well. 51 # If we've used up all characters from both strings successfully, we 52 # can return "true". 53 54 use v5.36; 55 56 broken_keys("perl", "perrrl"); 57 broken_keys("raku", "rrakuuuu"); 58 broken_keys("python", "perl"); 59 broken_keys("coffeescript", "cofffeescccript"); 60 61 sub broken_keys($name, $typed) { 62 say "Input: \"$name\", \"$typed\""; 63 my @name = split //, $name; 64 my @typed = split //, $typed; 65 my $prev = ""; 66 my $j = 0; 67 foreach my $i (0..$#name) { 68 if($name[$i] eq $typed[$j]) { 69 $j++; 70 $prev = $name[$i]; 71 next; 72 } 73 while($prev eq $typed[$j]) { 74 $j++; 75 } 76 $prev = $name[$i]; 77 if($j > $#typed and $i < $#name) { 78 return say "Output: false"; 79 } 80 } 81 while($j < $#typed and $prev eq $typed[$j]) { 82 $j++; 83 } 84 if($j < $#typed) { 85 return say "Output: false"; 86 } 87 say "Output: true"; 88 }