Skip to content

Instantly share code, notes, and snippets.

@MrMeison
Created November 23, 2018 14:06
Show Gist options
  • Save MrMeison/66d6d9eb48b89a5a1414057be7914154 to your computer and use it in GitHub Desktop.
Save MrMeison/66d6d9eb48b89a5a1414057be7914154 to your computer and use it in GitHub Desktop.
/**
* Суть решения: Сначала пробигаемся с начала матрица до конца заполняя левое и верхнее направлевление
* для выйграша. Для этого сравниваем текущее и предыдущее значения по этому направлению и проверяем было ли
* предыдущее значение выиграшным по этому направлению. Если да, то проверять дальше бессмысленно, то что они
* в любом случае будут меньше текущего значения, иначе предверяем следующее число в том же направлении.
*
* После того как закончим прверять все верхнии и левые значения переходим к нижних правым. Для этого делаем тоже самое
* но в обратном направлении. Заодно и складываем сумму.
*/
const WALKERS = {
left: (y,x) => [y, x - 1],
right: (y,x) => [y, x + 1],
up: (y,x) => [y - 1, x],
down: (y,x) => [y + 1, x]
};
// сумма выигрышных направлений для ячейки
const sumWinDirection = (cellResult) => {
let sum = 0;
for (let key in cellResult) {
sum += Number(cellResult[key]);
}
return sum;
};
// рисуем какие выиграшнуе направления ( визуализация )
const printWinDirection = (arr, results) => {
let res = [];
results.forEach((_, y) => {
results[y].forEach((value, x) => {
res = res.concat(value.up && '↑', value.down && '↓', value.right && '→', value.left && '←', arr[y][x], '\t')
});
res.push('\n');
});
console.log(res.filter(Boolean).join(''));
};
const solve = (arr) => {
let result = 0;
const resultMatrix = [];
for (let i = 0; i < arr.length; i++) {
resultMatrix[i] = [];
}
// проверка текущего и предыдущего значения в заданном направлении
// если false то направление заведомо проиграшное,
// если true то выиграшное
// undefined - если надо проверять значения до прелылущего чтобы дать ответ
const checkPrevValue = (direction) => (current, prev) => {
if (
prev.x === -1 || prev.y === -1 ||
prev.x === arr[0].length || prev.y === arr.length
) return true;
if (current.value > prev.value) {
if (resultMatrix[prev.y][prev.x][direction]) {
return true;
}
} else {
return false;
}
};
// проверка текущего значения в заданном направлении
const checkDirection = (direction, current) => {
let result;
let prev = current;
const check = checkPrevValue(direction);
do {
const [y, x] = WALKERS[direction](prev.y, prev.x);
prev = {
value: arr[y] && arr[y][x],
x,
y
};
result = check(current, prev);
} while(result === undefined);
return result;
};
// проверяем левые и верхние значения
for (let y = 0; y < arr.length; y++) {
for (let x = 0; x < arr[y].length; x++) {
resultMatrix[y][x] = resultMatrix[y][x] || Object.create(null);
const current = {
value: arr[y][x],
x,
y
};
resultMatrix[y][x].up = checkDirection('up', current);
resultMatrix[y][x].left = checkDirection('left', current);
console.log(resultMatrix[0][0], x, y);
}
}
// проверяем правые и нижние значения в обратном направлении
for (let y = arr.length - 1; y >= 0; y--) {
for (let x = arr[y].length - 1; x >= 0; x--) {
const current = {
value: arr[y][x],
x,
y
};
resultMatrix[y][x].down = checkDirection('down', current);
resultMatrix[y][x].right = checkDirection('right', current);
result += sumWinDirection(resultMatrix[y][x]);
}
}
return result;
}
console.log(
solve([
[ 6, 4, 10, 11 ],
[ 2, 9, 9, 3 ],
[ 5, 4, 5, 4 ]
])
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment