Skip to content

Instantly share code, notes, and snippets.

@tripolskypetr
Last active January 2, 2020 21:41
Show Gist options
  • Save tripolskypetr/08a93675c99c6ea83c2bec211e92b08c to your computer and use it in GitHub Desktop.
Save tripolskypetr/08a93675c99c6ea83c2bec211e92b08c to your computer and use it in GitHub Desktop.
Functional style oriented graph traversal https://jsfiddle.net/tripolskypetr/132am0bL/
// o <- end
// / \ n
// f g \ /
// \ / m n
// e \ /
// | p |
// h d \ /
// \ | l
// i c /
// \ | k
// b /
// \ /
// a <- start
// This is a directed graph. Accordingly, we represent it in the form of pairs of points
const roads = {
a: ['b', 'k'],
b: ['c'],
c: ['i', 'd'],
d: ['h', 'e'],
e: ['f', 'g', 'o'],
f: [],
g: [],
h: [],
i: [],
k: ['l'],
l: ['m', 'p'],
m: ['o', 'n'],
n: [],
o: [],
p: [],
};
// We write a function that will iterate over all possible roads, adjusted for the fact that two different points can lead to the same endpoint (applyWay). We also write a function that recursively collects graph connections into segments (buildWays) the start and end points.
const buildWays = (dt) => [...roads[dt].map((d) => [dt, d]), ...roads[dt].map((d) => buildWays(d)).reduce((a, v) => a.concat(v), [])];
const first = (arr) => arr[0];
const last = (arr) => arr[arr.length - 1];
const applyWay = (dot) => {
const apply = [];
ways.forEach((way) => {
if (last(way) === dot) {
roads[dot].forEach((road) => apply.push([...way, ...road]));
} else {
return;
}
});
ways.push(...apply);
}
// Count all kinds of segments. Using the start and end points we connect the segments in various routes
const ways = buildWays('a'); // [ ['a','b'], ['b','c'] ]
Object.keys(roads).forEach((dot) => applyWay(dot)/* [ ['a','b', 'c', 'i'], ... ] */);
// From the start and end points we find the shortest route
const calculateRoute = (to, from = 'a') => ways
.filter((way) => first(way) === from && last(way) === to)
.sort((a, b) => a.length > b.length ? 1 : a.length < b.length ? -1 : 0);
console.log(first(calculateRoute('o'))); // [ 'a', 'k', 'l', 'm', 'o' ]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment