✓ Accepted answer
Well I can try to help somewhat.
First, we know that any string with less characters than #a - 1 or more characters than #a + 1 will always be more than one letter off. So we should start with something like this:
if #b > (#a + 1) or #b < (#a - 1) then return false end
If b has more characters than a, that means that a must be somewhere within b for it to still be true. In your examples, "sanan" is true while "sanka" is false. So this means that "sana", letter for letter, must be within b, if b is greater than a.
Since bis larger in this situation, string.match much be applied to it instead of a.
if #b > #a then return b:match(a) end
If b has less characters than a, we just need to do the opposite. b must be inside a, letter for letter.
if #b < #a then return a:match(b) end
The most difficult situation is when both a and b are equal. In this case, we're not looking for an exact match, all we need is a - 1 of the corresponding letters to be the same. Therefore for this we'll have to use a for loop.
if #a == #b then
local matches = 0
for i = 1, #a do
if a:sub(i, i) == b:sub(i, i) then
matches = matches + 1
end
end
if matches >= #a - 1 then
return true
end
end