Acronyms and FS
Weekly challenge 317 — 14 April 2025
Week 317: 14 Apr 2025
You are given two strings.
Write a script to return true
if swapping any two letters in one string match the other string,
or return false
otherwise.
Example 1 Input: $str1 = 'desc', $str2 = 'dsec' Output: true Example 2 Input: $str1 = 'tuck', $str2 = 'tcuk' Output: true Example 3 Input: $str1 = 'poo', $str2 = 'eop' Output: false Example 4 Input: $str1 = 'stripe', $str2 = 'sprite' Output: true
This is slightly harder than it looks because there are some edge cases.
The first step is to return false
if the strings are different lengths
because they can never match the conditions.
For the next step I originally considered:
a, b
and b, a
...
true
, and if not, it is false
But consider a case such as identical
and identical
. The algorithm
above will return false
because there are no places where the corresponding
characters in the two strings differ. However, we can swap the first i
in
the first string with the second i
in that string, and while that leaves
the string unchanged, it does now match the second string and thus meets the
stated conditions of the challenge, so the result is true
.
I could have retained my original algorithm, and then done an additional
chack for a case like identical
, but I concluded that the easiest
and most foolproof solution
was the simple one of swapping all the possible pairs in the first string and
seeing if it matches the second one. Even for a very long word that will
take negligible time.
#!/usr/bin/perl # Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge use v5.26; # The Weekly Challenge - 2025-04-14 use utf8; # Week 317 - task 2 - Friendly strings use warnings; # Peter Campbell Smith binmode STDOUT, ':utf8'; use Encode; # these are true friendly_strings('stripe', 'sprite'); friendly_strings('xxAxxBxx', 'xxBxxAxx'); friendly_strings('AxxxxxxB', 'AxxxxxxB'); friendly_strings('mmmmm', 'mmmmm'); friendly_strings('hippopotamus', 'hippopotamsu'); friendly_strings('identical', 'identical'); # these are false friendly_strings('shorter', 'shorterx'); friendly_strings('longer', 'longe'); friendly_strings('completely', 'differents'); friendly_strings('friendly', 'friendly'); sub friendly_strings { my ($string1, $string2, $result, @chars1, $j, $k, @chars3, $string3, $x); # initialise ($string1, $string2) = @_; $result = 'false'; @chars1 = split('', $string1); # strings must be same length if (length($string1) == length($string2)) { # loop over all pairs F: for $j (0 .. length($string1) - 2) { for $k ($j + 1 .. length($string1) - 1) { # swap 2 characters in string1 @chars3 = @chars1; $x = $chars3[$j]; $chars3[$j] = $chars3[$k]; $chars3[$k] = $x; $string3 = join('', @chars3); # and compare with string2 if ($string3 eq $string2) { $result = qq[true - '$x' and '$chars3[$j]']; last F; } } } } # report results say qq[\nInput: \$string1 = '$string1', \$string2 = '$string2']; say qq[Output: $result]; }
Input: $string1 = 'stripe', $string2 = 'sprite' Output: true - 't' and 'p' Input: $string1 = 'xxAxxBxx', $string2 = 'xxBxxAxx' Output: true - 'A' and 'B' Input: $string1 = 'AxxxxxxB', $string2 = 'AxxxxxxB' Output: true - 'x' and 'x' Input: $string1 = 'mmmmm', $string2 = 'mmmmm' Output: true - 'm' and 'm' Input: $string1 = 'hippopotamus', $string2 = 'hippopotamsu' Output: true - 'u' and 's' Input: $string1 = 'identical', $string2 = 'identical' Output: true - 'i' and 'i' Input: $string1 = 'shorter', $string2 = 'shorterx' Output: false Input: $string1 = 'longer', $string2 = 'longe' Output: false Input: $string1 = 'completely', $string2 = 'differents' Output: false Input: $string1 = 'friendly', $string2 = 'friendly' Output: false
Any content of this website which has been created by Peter Campbell Smith is in the public domain