Created
November 23, 2018 14:06
-
-
Save MrMeison/66d6d9eb48b89a5a1414057be7914154 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Суть решения: Сначала пробигаемся с начала матрица до конца заполняя левое и верхнее направлевление | |
* для выйграша. Для этого сравниваем текущее и предыдущее значения по этому направлению и проверяем было ли | |
* предыдущее значение выиграшным по этому направлению. Если да, то проверять дальше бессмысленно, то что они | |
* в любом случае будут меньше текущего значения, иначе предверяем следующее число в том же направлении. | |
* | |
* После того как закончим прверять все верхнии и левые значения переходим к нижних правым. Для этого делаем тоже самое | |
* но в обратном направлении. Заодно и складываем сумму. | |
*/ | |
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