From 00eacff816e458cadb4442e7b2ec596e6bce1a88 Mon Sep 17 00:00:00 2001 From: Yitzchak Scott-Thoennes Date: Sun, 27 Jul 2025 21:03:54 -0400 Subject: challenge 331: fix task2 solutions --- challenge-331/ysth/go/ch-2.go | 27 +++++++++++++++++++++------ challenge-331/ysth/perl/ch-2.pl | 35 ++++++++++++++++++++++++++++++++--- challenge-331/ysth/python/ch-2.py | 25 ++++++++++++++++++++++++- 3 files changed, 77 insertions(+), 10 deletions(-) diff --git a/challenge-331/ysth/go/ch-2.go b/challenge-331/ysth/go/ch-2.go index 421c5a8892..dc35146668 100644 --- a/challenge-331/ysth/go/ch-2.go +++ b/challenge-331/ysth/go/ch-2.go @@ -6,18 +6,33 @@ import ( ) func buddy_strings(string1 string, string2 string) bool { - if (string1 == string2) { return false } var runes1 = []rune(string1) var runes2 = []rune(string2) if len(runes1) != len(runes2) { return false } - var differences int = 0 + var swaps int = 0 + var pair_exists bool = false + var previous_character1 rune + var previous_character2 rune for i := range runes1 { - if runes1[i] != runes2[i] { - differences++ - if differences > 1 { return false } + var character1 rune = runes1[i] + var character2 rune = runes2[i] + if swaps == 1 { + // second character of swap + if previous_character2 != character1 || character2 != previous_character1 { + return false + } + swaps = 2 + } else if character1 != character2 { + // starting the first swap + if swaps > 0 { return false } + previous_character1 = character1 + previous_character2 = character2 + swaps = 1 } + pair_exists = pair_exists || i > 0 && runes1[i-1] == runes1[i] } - return true + + return swaps == 0 && pair_exists || swaps == 2 } func main() { diff --git a/challenge-331/ysth/perl/ch-2.pl b/challenge-331/ysth/perl/ch-2.pl index 2aebf3e46f..f183cd768c 100644 --- a/challenge-331/ysth/perl/ch-2.pl +++ b/challenge-331/ysth/perl/ch-2.pl @@ -1,11 +1,40 @@ use 5.040; use utf8::all; # utf8 @ARGV -use Text::Fuzzy (); + +# replacement for the pre-perl5.28 stringwise xor that worked on any codepoints (up to uvsize) +sub bitwise_xor { + # copy/stringize arguments so overload/magic only happens once per arg + my $a = "$_[0]"; + my $b = "$_[1]"; + if (!utf8::is_utf8($a) && !utf8::is_utf8($b)) { + no if $] > 5.022, 'feature' => 'bitwise'; + return $a ^ $b; + } + if (length $a < length $b) { + $a =~ s/./chr(ord $& ^ ord($b =~ m!.!gs && $&))/gse; + return $a . substr $b, length $a; + } + else { + $b =~ s/./chr(ord $& ^ ord($a =~ m!.!gs && $&))/gse; + return $b . substr $a, length $b; + } +} sub buddy_strings($string1, $string2) { - length $string1 == length $string2 - and Text::Fuzzy->new($string1, max => 1, no_exact => 1) == 1 + if ($string1 eq $string2) { + # a doubled character to "swap" + return $string1 =~ /(.)\1/s; + } + else { + return + # lengths must match + length $string1 == length $string2 + # exactly 2 differing characters, adjacent + && bitwise_xor($string1, $string2) =~ /^\0*([^\0])\1\0*\z/ + # in opposite order in the two strings + && substr($string1, $-[1], 2) eq reverse substr($string2, $-[1], 2) + } } sub main() { diff --git a/challenge-331/ysth/python/ch-2.py b/challenge-331/ysth/python/ch-2.py index 6d0f7c80e4..a87815fd24 100644 --- a/challenge-331/ysth/python/ch-2.py +++ b/challenge-331/ysth/python/ch-2.py @@ -3,7 +3,30 @@ import regex from itertools import batched def buddy_strings(string1: str, string2: str) -> bool: - return True if regex.fullmatch(regex.escape(string1)+'{1<=s<=1}', string2) else False + if len(string1) != len(string2): + return False + swaps = 0 + pair_exists: bool = False + previous_character1: str + previous_character2: str + for i in range(len(string1)): + character1: str = string1[i] + character2: str = string2[i] + if swaps == 1: + # second character of swap + if previous_character2 != character1 or character2 != previous_character1: + return False + swaps = 2 + elif string1[i] != string2[i]: + # starting the first swap + if swaps > 0: + return False + previous_character1 = character1 + previous_character2 = character2 + swaps = 1 + pair_exists = pair_exists or i > 0 and string1[i-1] == string1[i] + + return pair_exists and swaps == 0 or swaps == 2 def main() -> None: inputs: list[str] = sys.argv[1:] -- cgit