Skip to content

Instantly share code, notes, and snippets.

@jkobus
Last active February 9, 2022 03:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jkobus/06eb16d2b9ae960ef68fd96817ef10b9 to your computer and use it in GitHub Desktop.
Save jkobus/06eb16d2b9ae960ef68fd96817ef10b9 to your computer and use it in GitHub Desktop.
<?php
/**
* Make sure to enable zend.assertions=1 in your php.ini for assert to work.
*/
assert_options(ASSERT_ACTIVE, 1);
function OneEditApart(string $a, string $b): bool
{
// the longer one will be on the left
if(strlen($b) > strlen($a)) {
$x = $a;
$a = $b;
$b = $x;
}
// if the length diff is more than 1 character, it's not one edit anymore
if((strlen($a) - strlen($b)) > 1) {
return false;
}
$ax = str_split($a);
$bx = str_split($b);
$i = 0;
$j = 0;
$hasChange = false;
while($i < strlen($a)) {
// string on the left is longer, so nothing more to compare to
if(!isset($bx[$j])) {
break;
}
// both letters are equal, lets try the next one
if($ax[$i] === $bx[$j]) {
++$i;
++$j;
continue;
}
// letters were not equal, if we had a change earlier, it's not one edit anymore
if($hasChange) {
return false;
}
// letters were not equal, therefore we note that here
$hasChange = true;
// if the $a is longer than $b, let's try to skip that letter and see if the next one will match
if(strlen($a) > strlen($b)) {
++$i;
} else {
// nope, these are equal strings, lets try another one then
++$i;
++$j;
}
}
return true;
}
// Tests
assert(OneEditApart('dog', 'cat') === false);
assert(OneEditApart('cat', 'cats') === true);
assert(OneEditApart('cat', 'cut') === true);
assert(OneEditApart('cat', 'cast') === true);
assert(OneEditApart('cat', 'at') === true);
assert(OneEditApart('cat', 'act') === false);
assert(OneEditApart('cat', 'acts') === false);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment