Recursive Solution Improvement
First, here's a rewrite of the answer you submitted yourself, which fixes a small bug and removes the inner function, which isn't needed. Instead, we make the final two parameters optional:
function longestSuffix(X,Y,m,n) {
var m = m === undefined ? X.length : m,
n = n === undefined ? Y.length : n,
keepGoing = X[m-1] && Y[n-1] && X[m-1] === Y[n-1];
return keepGoing ? longestSuffix(X, Y, m-1, n-1) + X[m-1] : '';
};
Here's a different approach, slightly longer because I spelled everything out with variable names, but perhaps simpler in concept:
function longestSuffix (A, B, answer) {
var answer = answer || '',
aLast = A.slice(-1),
bLast = B.slice(-1),
A = A.slice(0,-1),
B = B.slice(0,-1),
done = !aLast || !bLast || aLast != bLast;
return done ? answer : longestSuffix(A, B, aLast + answer);
};
You can make it shorter by, eg, removing aMinusLast
and bMinusLast
and replacing them inline with their definitions, but I like this expanded version because everything is clearly named, and the entire logic of the function can be seen at a glance in a single line.
Loop solution
A loop may be more appropriate here. Here's a very brief implementation which takes advantage of slice
, which exists on strings as well as arrays.
The only ugly part of this is that we have to treat the case when both A fully matches B as a special case in the return statement. Otherwise note that the final slice(1)
just adjusts back for the final decrement.
function longestSuffix (A, B) {
var i = -1;
while (A.slice(i) == B.slice(i) && i >= -A.length) i--;
return i < -A.length ? A : A.slice(i).slice(1)
};
This could be expanded for further clarity, but I figured I'd leave this one in compressed form, because it's so short.