20.12.2017, 07:09
|
Аспирант
|
|
Регистрация: 02.07.2017
Сообщений: 83
|
|
Судоку проверка
Здравствуйте, есть задача про судоку, поле 9на9, нужно проверить, чтобы цифры в строках, столбцах и в боксах 3на3 не было повторений цифр.
Нагородил вот тут, сам запутался там: https://jsfiddle.net/bb3o2ohr/
Нужно в итоге вернуть "try again" или "finished".
Допустим есть поле:
[ [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ],
[ 2, 3, 4, 5, 6, 7, 8, 9, 1 ],
[ 3, 4, 5, 6, 7, 8, 9, 1, 2 ],
[ 4, 5, 6, 7, 8, 9, 1, 2, 3 ],
[ 5, 6, 7, 8, 9, 1, 2, 3, 4 ],
[ 6, 7, 8, 9, 1, 2, 3, 4, 5 ],
[ 7, 8, 9, 1, 2, 3, 4, 5, 6 ],
[ 8, 9, 1, 2, 3, 4, 5, 6, 7 ],
[ 9, 1, 2, 3, 4, 5, 6, 7, 8 ] ]
//Создаю переменные:
var i; //Для первого цикла
var j; // Для второго
var z; // Для цикла в массиве цифр
var uniq1Arr = []; //Здесь массивы, для строк
var uniq2Arr = []; // Для колонок
var uniq3Arr =[]; // Для полей 3 на 3
//Иду циклами, например:
// Здесь проверяю строчки, и пушу каждую цифру строки в массив, если длина массива больше 9, очищаю его.
for(i=0; i<9; i++) {
for(j=0; j<9; j++) {
for(z=0; z<uniq1Arr.length; z++) {
if(uniq1Arr.length >9) uniq1Arr = [];
if(board[i][j] == uniq1Arr[z]) {
return "Try again!";
}
uniq1Arr.push(board[i][j]);
}
// Здесь проверяю колонки, и пушу каждую цифру колонки в массив, если длина массива больше 9, очищаю его.
for(i=0; i<9; i++) {
for(j=0; j<9; j++) {
for(z=0; z<uniq2Arr.length; z++) {
if(uniq1Arr.length >9) uniq2Arr = [];
if(board[j][i] == uniq2Arr[z]) {
return "Try again!";
}
uniq1Arr.push(board[j][i]);
}
//Поля 3на3 проверяю так...
for(i=0; i<3; i++){
for(j=0; j<3; j++) {
for(z=0; z<uniq3Arr.length; z++) {
if(board[i][j] == uniq1Arr[z]) return "Try again!";
}
if(board[i][j] == uniq3) return "Try again!" ;
uniq3 = board[i][j];
}
}
uniq3 = 0;
uniq3Arr = [];
for(i=3; i<6; i++){
for(j=0; j<3; j++) {
for(z=0; z<uniq3Arr.length; z++) {
if(board[i][j] == uniq3Arr[z]) return "Try again!";
}
if(board[i][j] == uniq3) return "Try again!"
uniq3 = board[i][j]
}
}
uniq3 = 0;
uniq3Arr = [];
for(i=6; i<9; i++){
for(j=0; j<3; j++) {
for(z=0; z<uniq3Arr.length; z++) {
if(board[i][j] == uniq3Arr[z]) return "Try again!";
}
if(board[i][j] == uniq3) return "Try again!"
uniq3 = board[i][j]
}
}
//Если всё прошло, победа
return "Finished!";
|
|
20.12.2017, 08:29
|
|
CacheVar
|
|
Регистрация: 19.08.2010
Сообщений: 14,228
|
|
Сообщение от shoopik
|
нужно проверить, чтобы цифры в строках, столбцах и в боксах 3на3 не было повторений цифр.
|
Чтобы в каждой строке/столбце не было повторений? Или вообще одна цифра могла встретиться только раз в строках или столбцах "бокса"?
Пройдись по тем 9 боксам (циклом)... Пусть некая функция проверит текущий бокс, удовлетворяет он условиям или нет. В ней два цикла:
- по строкам
- по столбцам
Для проверки можно использовать "пустой" объект...
Вроде все просто. А ты там циклов наворотил - капец!
|
|
20.12.2017, 09:43
|
Аспирант
|
|
Регистрация: 02.07.2017
Сообщений: 83
|
|
Сообщение от ksa
|
Чтобы в каждой строке/столбце не было повторений? Или вообще одна цифра могла встретиться только раз в строках или столбцах "бокса"?
Пройдись по тем 9 боксам (циклом)... Пусть некая функция проверит текущий бокс, удовлетворяет он условиям или нет. В ней два цикла:
- по строкам
- по столбцам
Для проверки можно использовать "пустой" объект...
Вроде все просто. А ты там циклов наворотил - капец!
|
Чтобы в каждой строке/столбце не было повторений, и внутри боксов 3на3.
По строкам/строкам прохожусь, как для проверки использовать пустой объект ?
И как лучше проверить циклами сами боксы 3 на 3 ?
|
|
20.12.2017, 10:19
|
|
Профессор
|
|
Регистрация: 11.08.2017
Сообщений: 208
|
|
Можно попробовать каждую строку бить на три части. Если остаток от деления на 3 == 0, то передать в функцию индекс строки и текущий индекс элемента.
for(var j = 0; j <= 9; j++){
arr[j].forEach(function(item, i) {
if(i % 3 == 0 && i != 0){
myFunc([arr[j], i]);
}
});
}
И в функции на основе принятых параметров сформировать массив, в котором проверить на совпадения. Тем самым уже проверены строки, осталось дело за столбцами.
function myFunc(arr){
var arr2 = [arr[0][arr[1]], arr[0][arr[1]-1], arr[0][arr[1]-2]];
var uni = arr2.filter(function(elem, pos) {
return arr2.indexOf(elem) == pos;
});
if(uni.length < 3){
alert('Найдено совпадение');
}
}
Чуть криво сделал, это просто идея, мож пригодится или натолкнет на мысль)
|
|
20.12.2017, 10:47
|
Профессор
|
|
Регистрация: 27.11.2015
Сообщений: 2,899
|
|
shoopik,
Поскольку при игре ставится при каждом ходе одна цифра, то и проверять нужно только те строки/столбцы и блок, в которых находится эта цифра.
|
|
20.12.2017, 11:03
|
Аспирант
|
|
Регистрация: 02.07.2017
Сообщений: 83
|
|
Сообщение от Dilettante_Pro
|
shoopik,
Поскольку при игре ставится при каждом ходе одна цифра, то и проверять нужно только те строки/столбцы и блок, в которых находится эта цифра.
|
Там сразу всё поле даётся, заполненное
|
|
20.12.2017, 11:32
|
|
CacheVar
|
|
Регистрация: 19.08.2010
Сообщений: 14,228
|
|
Сообщение от shoopik
|
как для проверки использовать пустой объект ?
|
Перед проверкой создаешь пустой объект...
var o={};
А когда берешь очередного "подопечного" можно быстро проверить, был такой или нет
if (o[a[i][j]]) {
return false;
} else {
o[a[i][j]]=true;
};
|
|
20.12.2017, 11:35
|
|
CacheVar
|
|
Регистрация: 19.08.2010
Сообщений: 14,228
|
|
Сообщение от shoopik
|
как лучше проверить циклами сами боксы 3 на 3 ?
|
Передавай в проверяющую функцию "верхнюю точку" бокса, а там обычные циклы от 0 до 2... По строкам и столбцам.
|
|
20.12.2017, 11:57
|
|
CacheVar
|
|
Регистрация: 19.08.2010
Сообщений: 14,228
|
|
Сообщение от shoopik
|
Чтобы в каждой строке/столбце не было повторений, и внутри боксов 3на3.
|
Оно?
var arr=[
[ 1, 2, 3, 4, 5, 6, 7, 8, 9 ],
[ 2, 2, 4, 5, 6, 7, 8, 9, 1 ],
[ 3, 4, 5, 6, 7, 8, 9, 1, 2 ],
[ 4, 5, 6, 7, 8, 9, 1, 2, 3 ],
[ 5, 6, 7, 8, 9, 1, 2, 3, 4 ],
[ 6, 7, 8, 9, 1, 2, 3, 4, 5 ],
[ 7, 8, 9, 1, 2, 3, 4, 5, 6 ],
[ 8, 9, 1, 2, 3, 4, 5, 6, 7 ],
[ 9, 1, 2, 3, 4, 5, 6, 7, 8 ]
];
for (var i=0; i<arr.length; i++) {
var y=Math.floor(i/3)*3;
var x=(i%3)*3;
var ok=box(y,x);
if (!ok) {
alert('Ошибка!');
break;
};
};
if (ok) {
alert('Все отлично.');
};
function box(Y,X) {
for (var i=0; i<3; i++) {
var o={};
for (var j=0; j<3; j++) {
var val=arr[Y+i][X+j];
if (o[val]) {
alert(Y+' - '+X);
return false;
} else {
o[val]=true;
};
};
};
for (var i=0; i<3; i++) {
var o={};
for (var j=0; j<3; j++) {
var val=arr[Y+j][X+i];
if (o[val]) {
alert(Y+' - '+X);
return false;
} else {
o[val]=true;
};
};
};
return true;
};
|
|
20.12.2017, 12:14
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,126
|
|
судоку проверка
шифровка из центра ...
<!DOCTYPE html>
<html>
<head>
<title>Untitled</title>
<meta charset="utf-8">
<style type="text/css">
</style>
<script>
var chec = function() {
for (var g = [], b = [], c = [], d = [], e = [], h = [], f = [], a = 0; 81 > a; a++) {
a % 9 || (b = [], h.push(b)), b.push(a), 9 > a ? f.push([a]) : f[a % 9].push(a), a % 3 || a % 27 || (c = [], d = [], e = [], g.push(c, d, e)), [c, d, e][a % 9 / 3 | 0].push(a);
}
var k = [].concat(g, h, f);
return function(a) {
a = [].concat.apply([], a);
return k.every(function(b) {
var c = {};
return b.every(function(b) {
b = a[b];
c[b] = (c[b] || 0) + 1;
return 2 > c[b];
});
});
};
}();
var board = [ [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ],
[ 2, 3, 4, 5, 6, 7, 8, 9, 1 ],
[ 3, 4, 5, 6, 7, 8, 9, 1, 2 ],
[ 4, 5, 6, 7, 8, 9, 1, 2, 3 ],
[ 5, 6, 7, 8, 9, 1, 2, 3, 4 ],
[ 6, 7, 8, 9, 1, 2, 3, 4, 5 ],
[ 7, 8, 9, 1, 2, 3, 4, 5, 6 ],
[ 8, 9, 1, 2, 3, 4, 5, 6, 7 ],
[ 9, 1, 2, 3, 4, 5, 6, 7, 8 ] ];
alert(chec(board)); //false
board = [
[8, 4, 5, 6, 1, 9, 3, 2, 7],
[1, 3, 2, 4, 5, 7, 6, 9, 8],
[7, 6, 9, 8, 3, 2, 5, 4, 1],
[5, 9, 6, 2, 8, 1, 7, 3, 4],
[4, 8, 3, 5, 7, 6, 2, 1, 9],
[2, 7, 1, 3, 9, 4, 8, 5, 6],
[3, 5, 7, 9, 4, 8, 1, 6, 2],
[6, 1, 4, 7, 2, 5, 9, 8, 3],
[9, 2, 8, 1, 6, 3, 4, 7, 5]
]
alert(chec(board));//true
</script>
</head>
<body>
<div id="slider"></div>
</body>
</html>
|
|
|
|