##Recursive Solution Improvement
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
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.
##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.
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.
##Recursive Solution Improvement
I noticed your comment that you wantedFirst, here's a recursive solutionrewrite of the answer you submitted yourself, so here is one that I think reads more clearly thanwhich fixes a small bug and removes the original.
Note that there's no need to introduce an inner function for the recursion, which isn't needed. Instead, you can usewe make the original function and allow its third parameter to befinal 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
That said, aA 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.
##Recursive Solution Improvement
I noticed your comment that you wanted a recursive solution, so here is one that I think reads more clearly than the original.
Note that there's no need to introduce an inner function for the recursion. Instead, you can use the original function and allow its third parameter to be optional:
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
That said, 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.
##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.
##Recursive Solution Improvement
I noticed your comment that you wanted a recursive solution, so here is one that I think reads more clearly than the original.
Note that there's no need to introduce an inner function for the recursion. Instead, you can use the original function and allow its third parameter to be optional:
function longestSuffix (A, B, answer) {
var answer = answer || '',
aLast = A.slice(-1),
bLast = B.slice(-1),
aMinusLastA = A.slice(0,-1),
bMinusLastB = B.slice(0,-1),
done = !aLast || !bLast || aLast != bLast;
return done ? answer : longestSuffix(aMinusLastA, bMinusLastB, 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
That said, 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.
##Recursive Solution Improvement
I noticed your comment that you wanted a recursive solution, so here is one that I think reads more clearly than the original.
Note that there's no need to introduce an inner function for the recursion. Instead, you can use the original function and allow its third parameter to be optional:
function longestSuffix (A, B, answer) {
var answer = answer || '',
aLast = A.slice(-1),
bLast = B.slice(-1),
aMinusLast = A.slice(0,-1),
bMinusLast = B.slice(0,-1),
done = !aLast || !bLast || aLast != bLast;
return done ? answer : longestSuffix(aMinusLast, bMinusLast, 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
That said, 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.
##Recursive Solution Improvement
I noticed your comment that you wanted a recursive solution, so here is one that I think reads more clearly than the original.
Note that there's no need to introduce an inner function for the recursion. Instead, you can use the original function and allow its third parameter to be optional:
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
That said, 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.