Skip to content

Instantly share code, notes, and snippets.

@inomdzhon
Last active May 10, 2020 16:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save inomdzhon/34257b28ee2c7c1a111be158edf24cb8 to your computer and use it in GitHub Desktop.
Save inomdzhon/34257b28ee2c7c1a111be158edf24cb8 to your computer and use it in GitHub Desktop.

Задание

Описание

Матрицу можно представить в виде двумерного списка. Например, список [[1, 2, 3], [4, 5, 6], [7, 8, 9]] — это отображение матрицы:

1 2 3
4 5 6
7 8 9

Задача

Реализуйте и экспортируйте по умолчанию функцию buildSnailPath, которая принимает на вход матрицу и возвращает список элементов матрицы по порядку следования от левого верхнего элемента по часовой стрелке к внутреннему. Движение по матрице напоминает улитку.

Примеры

buildSnailPath([
  [1, 2],
  [3, 4],
]); // [1, 2, 4, 3]
buildSnailPath([
  [1, 2, 3, 4],
  [5, 6, 7, 8],
  [9, 10, 11, 12],
]) // [1, 2, 3, 4, 8, 12, 11, 10, 9, 5, 6, 7] 
// 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 computeXByDirection(value, direction) {
return value + ({
up: -1,
right: 0,
down: 1,
left: 0,
})[direction];
}
function computeYByDirection(value, direction) {
return value + ({
up: 0,
right: 1,
down: 0,
left: -1,
})[direction];
}
function changeDirectionСlockwise(direction) {
return ({
up: 'right',
right: 'down',
down: 'left',
left: 'up',
})[direction];
}
function goTo(rawSteps, x, y, direction) {
const steps = canGoTo(rawSteps, x, y) ? addRoadToStep(rawSteps, roads[x][y], x, y) : cloneDeep(rawSteps);
if (canGoTo(steps, computeXByDirection(x, direction), computeYByDirection(y, direction))) {
return goTo(steps, computeXByDirection(x, direction), computeYByDirection(y, direction), direction);
} else if (canGoTo(steps, computeXByDirection(x, changeDirectionСlockwise(direction)), computeYByDirection(y, changeDirectionСlockwise(direction)))) {
return goTo(steps, computeXByDirection(x, changeDirectionСlockwise(direction)), computeYByDirection(y, changeDirectionСlockwise(direction)), changeDirectionСlockwise(direction));
} else {
return steps;
}
}
return goTo([], 0, 0, 'right').map(i=>i.road);
}
// END
// 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment