|
// eslint-disable-next-line no-unused-vars |
|
import { cloneDeep } from 'lodash'; |
|
|
|
// BEGIN (write your solution here) |
|
export default function buildSnailPath(rawRoads) { |
|
const roads = cloneDeep(rawRoads); |
|
|
|
function isStepPassed(steps, x, y) { |
|
for (let i = 0; i < steps.length; i += 1) { |
|
if (steps[i].x === x && steps[i].y === y) { |
|
return true; |
|
} |
|
} |
|
|
|
return false; |
|
} |
|
|
|
function addRoadToStep(rawSteps, road, x, y) { |
|
const steps = cloneDeep(rawSteps); |
|
steps.push({ |
|
x, |
|
y, |
|
road, |
|
}); |
|
return steps; |
|
} |
|
|
|
function canGoTo(steps, x, y) { |
|
if (roads[x] && y >= 0 && y < roads[x].length) { |
|
return isStepPassed(steps, x, y) ? false : true; |
|
} else { |
|
return false; |
|
} |
|
} |
|
|
|
function goTo(rawSteps, x, y, direction) { |
|
const steps = canGoTo(rawSteps, x, y) ? addRoadToStep(rawSteps, roads[x][y], x, y) : cloneDeep(rawSteps); |
|
|
|
if (direction === 'up') { |
|
if (canGoTo(steps, x - 1, y)) { |
|
return goTo(steps, x - 1, y, 'up'); |
|
} else if (canGoTo(steps, x, y + 1)) { |
|
return goTo(steps, x, y + 1, 'right'); |
|
} else { |
|
return steps; |
|
} |
|
} |
|
|
|
if (direction === 'right') { |
|
if (canGoTo(steps, x, y + 1)) { |
|
return goTo(steps, x, y + 1, 'right'); |
|
} else if (canGoTo(steps, x + 1, y)) { |
|
return goTo(steps, x + 1, y, 'down'); |
|
} else { |
|
return steps; |
|
} |
|
} |
|
|
|
if (direction === 'down') { |
|
if (canGoTo(steps, x + 1, y)) { |
|
return goTo(steps, x + 1, y, 'down'); |
|
} else if (canGoTo(steps, x, y - 1)) { |
|
return goTo(steps, x, y - 1, 'left'); |
|
} else { |
|
return steps; |
|
} |
|
} |
|
|
|
if (direction === 'left') { |
|
if (canGoTo(steps, x, y - 1)) { |
|
return goTo(steps, x, y - 1, 'left'); |
|
} else if (canGoTo(steps, x - 1, y)) { |
|
return goTo(steps, x - 1, y, 'up'); |
|
} else { |
|
return steps; |
|
} |
|
} |
|
} |
|
|
|
return goTo([], 0, 0, 'right').map(i => i.road); |
|
} |
|
// END |