Assuming the function is called concat
and takes an array of strings pool
as a first parameter, and an accumulator* string s
as a second parameter:
Each time you enter the concat
function, you can check the following rules:
- If
pool
is empty, then return s
as it is a correct answer.
- If
s
does not have an acceptable match in pool
, then backtrack by returning null or some indicator that there is no suitable answer for the inputs.
- Recurse on every acceptable match until either: there are no matches left, or, a correct answer is found.
This will ultimately lead to either a correct answer, or, to null or some other indicator value that the inputs had no answer.
*An accumulator string is one that accumulates a value between recursive function calls. In this case, it would start as an empty string in the initial call, and then at each invocation of concat
deeper into the call stack, it would be concatenated by its match from pool
.
Here is a small javascript implementation, if you run it it will produce a somewhat verbose log:
function concat(pool, s) {
s = s === undefined ? '' : s;
if (pool.length === 0) {
log("empty pool, s: " + s);
return s;
}
for (let itr = 0; itr < pool.length; ++itr) {
let v = pool[itr];
if (s.length === 0 || v.charAt(0) === s.charAt(s.length - 1)) {
log(s + v + " is a candidate path, searching...");
let ret = concat(nSlice(pool, itr), s + v);
if (ret !== null) {
log("returning non-null ret: " + ret);
return ret;
}
log(s + v + " hit a dead end, continuing...");
} else {
log(s + v + " was not a candidate path, continuing...");
}
}
log("Returning null for given s: " + s);
return null;
}
function nSlice(arr, index) {
let a = arr.slice(0);
a.splice(index, 1);
return a;
}
function log(m) {
console.log(m);
let e = document.createElement('div');
e.innerHTML = m;
document.body.appendChild(e);
}
[
['ab2c', 'h23f2', 'c4dsh'],
['ab2c', 'h23fc', 'c555ab', 'c4dsh'],
['h23fc', 'c555ab', 'c4dsh', 'ab2c']
].forEach(v => {
concat(v);
log("------------------");
});