Судоку проверка
Здравствуйте, есть задача про судоку, поле 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!"; |
Цитата:
Пройдись по тем 9 боксам (циклом)... Пусть некая функция проверит текущий бокс, удовлетворяет он условиям или нет. В ней два цикла: - по строкам - по столбцам Для проверки можно использовать "пустой" объект... Вроде все просто. А ты там циклов наворотил - капец! :blink: |
Цитата:
По строкам/строкам прохожусь, как для проверки использовать пустой объект ? И как лучше проверить циклами сами боксы 3 на 3 ? |
Можно попробовать каждую строку бить на три части. Если остаток от деления на 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('Найдено совпадение'); } } Чуть криво сделал, это просто идея, мож пригодится или натолкнет на мысль) |
shoopik,
Поскольку при игре ставится при каждом ходе одна цифра, то и проверять нужно только те строки/столбцы и блок, в которых находится эта цифра. |
Цитата:
|
Цитата:
var o={}; А когда берешь очередного "подопечного" можно быстро проверить, был такой или нет if (o[a[i][j]]) { return false; } else { o[a[i][j]]=true; }; |
Цитата:
|
Цитата:
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; }; |
судоку проверка
шифровка из центра ... :)
<!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> |
ksa,
твой вариант только для Цитата:
а строки и столбцы? |
рони, я не особо знаком с Судоку... :cray: Т.ч. "как надо" я не знаю...
ТС сказал про "боксы" - я сделал тестовый примерчик. Вот собственно и все. :) |
ksa,
да вроде просто каждая строка arr[i] - не должна содержать повторений и каждый столбец [arr[0] [0], arr[1] [0],..., arr[8] [0]] |
рони, а боксы 3х3 тогда тут при чем? :blink:
|
Цитата:
9 строк, 9 столбцов, 9 блоков 3 х 3 - каждый из этих 27 массивов должен содержать только уникальные элементы - вот и все правила Судоку. |
судоку проверка
:write: вопрос как проще сформровать массив k в 12 строке, последовательность строк не имеет значения, вариант формирования смотреть пост №10 (строки 12-15)
<!DOCTYPE html> <html> <head> <title>Untitled</title> <meta charset="utf-8"> <style type="text/css"> </style> <script> var chec = function() { var k = [ /* строки */ [0, 1, 2, 3, 4, 5, 6, 7, 8], [9, 10, 11, 12, 13, 14, 15, 16, 17], [18, 19, 20, 21, 22, 23, 24, 25, 26], [27, 28, 29, 30, 31, 32, 33, 34, 35], [36, 37, 38, 39, 40, 41, 42, 43, 44], [45, 46, 47, 48, 49, 50, 51, 52, 53], [54, 55, 56, 57, 58, 59, 60, 61, 62], [63, 64, 65, 66, 67, 68, 69, 70, 71], [72, 73, 74, 75, 76, 77, 78, 79, 80], /* блоки 3 х 3 */ [0, 1, 2, 9, 10, 11, 18, 19, 20], [3, 4, 5, 12, 13, 14, 21, 22, 23], [6, 7, 8, 15, 16, 17, 24, 25, 26], [27, 28, 29, 36, 37, 38, 45, 46, 47], [30, 31, 32, 39, 40, 41, 48, 49, 50], [33, 34, 35, 42, 43, 44, 51, 52, 53], [54, 55, 56, 63, 64, 65, 72, 73, 74], [57, 58, 59, 66, 67, 68, 75, 76, 77], [60, 61, 62, 69, 70, 71, 78, 79, 80], /* столбцы */ [0, 9, 18, 27, 36, 45, 54, 63, 72], [1, 10, 19, 28, 37, 46, 55, 64, 73], [2, 11, 20, 29, 38, 47, 56, 65, 74], [3, 12, 21, 30, 39, 48, 57, 66, 75], [4, 13, 22, 31, 40, 49, 58, 67, 76], [5, 14, 23, 32, 41, 50, 59, 68, 77], [6, 15, 24, 33, 42, 51, 60, 69, 78], [7, 16, 25, 34, 43, 52, 61, 70, 79], [8, 17, 26, 35, 44, 53, 62, 71, 80] ]; 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> |
Часовой пояс GMT +3, время: 10:02. |