#8 Petr
To bol len navrh mojho riesenia. Ty nepoznas ze ti to koliduje v 1. 2. alebo n-tej bunke. Ty vies iba to ze sa ti tam opakuju nejake cisla, pre sudoku {1,2,3,...,9} ak ti to vrati col ==0 tak tam nic nekoliduje. Na to aby si zistil v ktorej buke sa to opakuje musis to preist este raz, ale s tym ze teraz uz vies cisla, ktore sa opakuju.
Toto je bunka:
1 2 3
4 5 4
2 6 7
Tebe vrati ChybaBlok(bunka) cislo v bin kode 00...000001010 (jeho hodnota je 10) -> z toho vidis ze sa opakuje 2 a 4. Dolezite je ze vies ze tie cisla urcite koliduju, ak je col nenulovy. Ak by si chcel napriklad ziskat kolidujuce bunky, tak len prepises kod:
public static int ChybaBlok(int[][] blok/*je velkosti 3x3*/, int[] kolBunky){
short p=0, col=0;
int k=0;
for(int i=0; i<3; i++){
for(int j=0; j<3; j++){
short v = 1<<(blok[i][j]-1);
col = col | (p & v);
if(p&v!=0){ // ak je nenulove vies ze v tekto bunke je kolizia
// Nechcelo sa mi kvoli tomu vytvarat nejaku HashMap, tak to vrazim len do jednorozmernaho pola ;)
kolBunky[k] = i*3+j // Ale to nemusi byt len 3 moze byt aj vacsie zalezi ake chces riesit sudoku napr 1024x1024 :D
}
p = p | v;
}
}
return col;
}
Musis si iba mimo tuto metodu zadefinovat dostatocne velke pole kolBunky, to je v tvojom pripade 9, lebo moze nastat ze koliduje vo vsetkych, ak to niekto vyplni napriklad samimi jednotkami. Alebo namiesto toho cisla budes odosielat prave tento int[] a velkost si nastavis priamo v metode podla potreby. Ako som pisal nechcelo sa mi vytvarat Nieco ako HashMap<Integ.., Inte...> preto som siahol po jednorozmernom poli, ale to nevadi lebo kazda bunka ma svoju hodnotu danu vztahom bunka[i][j] -> i*sirkaBunky + j cize bunke [1][2], ak koliduje priradi hodnotu 5.
K druhej otazke | je bitewise OR a & je bitewise AND, cize ti robi OR(AND) po bitoch napr. 01011 AND 01101 to da 01001 a OR tychto cisel ti da 01111 to je vsetko v bin pre ilustraciu. To || a && je v podstate nieco podobne ale pouziva sa to skorej pre boolean ze ak napriklad prva hodnota pre or je true druha sa uz neskuma lebo to nezmeni. a && je zase ze ak prva je false druha sa neskuma. Sa to celkom hodi, ked zistujes ci ti uzivatel zadal pole a jeho dlzka je nejaka tebou definovana if(pole!=null && pole.length == 3) lebo ak je null iste vies ze by ti to zhavarovalo.
A tak ma este napadlo, ze ak chces overovat len ci prave zadany prvok ti koliduje, tak ak si pamats na tu premennu p tam boli zapisane vsetky cisla ktore su v danom bloku, staci nieco taketo:
public static boolean koliduje(int m, int n, int p, int[][] blok){
short v = 1<<(blok[i][j]-1);
return (p & v)!=0 // koliduje ak sa tam ten prvok nachadza
}