Skip to content

Instantly share code, notes, and snippets.

@fernandocamargo
Last active April 3, 2024 18:51
Show Gist options
  • Save fernandocamargo/2df3201b0aa1f4b6794bd6af5d9dc4e5 to your computer and use it in GitHub Desktop.
Save fernandocamargo/2df3201b0aa1f4b6794bd6af5d9dc4e5 to your computer and use it in GitHub Desktop.
const cases = [
"GROC",
"FERNANDO",
"GC",
"AMIAT",
"AML",
"GABE",
"GRMLAWE",
"SLMIBE",
"RMLAIB",
"CORGAMLSTAIBEWZN",
"GAGA",
"CORGAMLSTAIBEWZS",
"GMIAWZN",
"ZALORG",
"WIMLAZE",
"WIMLAZ",
"AAAABBBB",
"WZNTSCORGABEWZN",
];
const sample = [
["G", "A", "B", "E"],
["R", "M", "I", "W"],
["O", "L", "A", "Z"],
["C", "S", "T", "N"],
];
const increase = (value) => value + 1;
const decrease = (value) => value - 1;
const get = (object) => (attribute) => object[attribute];
const normalize = (object) => String(object).toLowerCase().trim();
const indexColumnBy = (row) => (indexes, letter, column) => {
const index = normalize(letter);
const current = indexes[index];
const coordinates = [[row, column]];
const value = current ? current.concat(coordinates) : coordinates;
return Object.assign(indexes, { [index]: value });
};
const indexRow = (indexes, letters, row) =>
letters.reduce(indexColumnBy(row), indexes);
const getSiblings = ([row, column]) => [
[decrease(row), column], // ⭡
[decrease(row), increase(column)], // ↗
[row, increase(column)], // ⭢
[increase(row), increase(column)], // ↘
[increase(row), column], // ⭣
[increase(row), decrease(column)], // ↙
[row, decrease(column)], // ⭠
[decrease(row), decrease(column)], // ↖
];
const contains = (element) => ({
at: (collection) => !!~collection.map(normalize).indexOf(normalize(element)),
});
const isSibiling =
(reference = []) =>
(coordinates) =>
contains(coordinates).at(getSiblings(reference));
const walk = (stack, possibilities = []) => {
const previous = possibilities.reverse().find(isSibiling(stack.previous));
const invalid = !!previous && !contains(previous).at(stack.path);
const valid = !stack.valid ? stack.valid : invalid;
const path = !stack.valid ? stack.path : stack.path.concat([previous]);
return { previous, valid, path };
};
const check = (tail) => (valid, head) => {
const stack = { previous: head, valid: true, path: [head] };
return valid || tail.reduce(walk, stack).valid;
};
const find = (matrix) => (word) => {
const letters = normalize(word).split("");
const indexes = matrix.reduce(indexRow, {});
const getCoordinates = get(indexes);
const head = letters.shift();
const tail = letters.map(getCoordinates);
const directions = getCoordinates(head);
return !!directions && directions.reduce(check(tail), false);
};
const finder = find(sample);
const test = (word) => console.log(word, finder(word));
cases.forEach(test);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment