Kontrola jednoho bloku sudoku – Java – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Kontrola jednoho bloku sudoku – Java – Fórum – Programujte.comKontrola jednoho bloku sudoku – Java – Fórum – Programujte.com

 

Petr
~ Anonymní uživatel
746 příspěvků
18. 11. 2012   #1
-
0
-

Ahoj,

chci kontrolovat jeden blok (3x3) v sudoku. Tvorim si metodu prozatim pro ten prvni blok. Kdyz by nastala situace, ze aktualne generovany cislo na souradnicich [n][m] je stejny jako uz nejaky existujici, vrati se "true", jinak false. Pripada vam ta metoda spravne? Me pripada ze by mela fungovat, ale kdyz to testuju, tak nefunguje :(.

  public static boolean ChybaBlok(int[][] pole, int n, int m){
    
        if (m<3 && n<3) {
       
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    
                    if (pole[n][m] == pole[i][j]) {
                       
                        return true;
                    }
                }
            }

        }
        
        
        
        return false;
    }
Nahlásit jako SPAM
IP: 81.201.55.–
KIIV
~ Moderátor
+43
God of flame
18. 11. 2012   #2
-
0
-

Neni treba mozne, ze ti to sabotuje ten prvek ktery testujes? Krom toho kdyz budes testovat prvek  0,0 tak se moc daleko nedostanes s ostatnima v bloku

Nahlásit jako SPAM
IP: 94.112.32.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Petr
~ Anonymní uživatel
746 příspěvků
18. 11. 2012   #3
-
0
-

KIIV: Prvek 0,0 mam osetreny kdyz tu metodu volam... To pole mi to normalne vypise, akorat tam vzdycky je nejake cislo 2x. :-(

Jak to myslis s tim prvkem ktery testuju? Resp. jak by to mohl sabotovat?

Nahlásit jako SPAM
IP: 81.201.55.–
KIIV
~ Moderátor
+43
God of flame
18. 11. 2012   #4
-
0
-

no dejme tomu ukazkovy priklad:

1 2 .
3 . 5
. 9 8

ukazka 1)
udas pozici: 1,0 (tam je dvojka..)
for s i jede od 0 do 0
for s j neudela nic... 0 neni mensi nez nula

ukazka 2)
nahodou mas treba m=2, n=1 na ty pozici bude dejme tomu 5 ...
for s i projede cislo 0... 
for s j projede cisla 0 a 1 ... zkontroloval si jen dve pozice... a v nejlepsim pripade dokazes zkontrolovat az 4 pozice...

takze sem se mirne unahlil s tim kontrolovanim sama sebe.. k tomu se to nedostane.. ale urcite nekontrolujes vse nikdy

Nahlásit jako SPAM
IP: 94.112.32.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Petr
~ Anonymní uživatel
746 příspěvků
18. 11. 2012   #5
-
0
-

Ajo, mas pravdu... to sem nejak celkove nedomyslel. Zkusil sem to prekopat, aby to jelo po radcich. Kdyz budu na vyssim radku nez 0, tak to zkontroluje cely radek 0 a kdyz na vyssim radku nez 1, tak to zkontroluje i cely radek 1, ale nefunguje. (To ze mi to nekontroluje zbytek radky nevadi - uz mam vyresenou kontrolovacku pro sloupce a radky.)

Nahlásit jako SPAM
IP: 81.201.55.–
Petr
~ Anonymní uživatel
746 příspěvků
18. 11. 2012   #6
-
0
-

   

public static boolean ChybaBlok(int[][] pole, int n, int m){
        
       
        if (n>0) {
            
            for (int i = 0; i < 3; i++) {
                if (pole[n][m]==pole[0][i]) {
                    return true;
                }
            }
            
        }
        if (n>1) {
            
            for (int i = 0; i < 3; i++) {
                if (pole[n][m]==pole[1][i]) {
                    return true;
                }
            }
            
        }
        
        
        
        return false;
        }
Nahlásit jako SPAM
IP: 81.201.55.–
sleepy0
Stálý člen
19. 11. 2012   #7
-
0
-

#6 Petr
Ahoj ja by som to riesil asi takto: Urobil by som priradenie, ze ak je k cislo zo sudoku tak by som mu priradil cislo 2^(k-1), cize napr. 1 by som dal (000...001) 2->(000...010), 3->(000...0100) a tak dalej az po cislo k_max co je u teba 9. Taketo priradenie sa da urobit bitshiftom: zoberem cislo zo sudoku, nejake k, a dam mu cislo 1<<(k-1). To ti len posunie tu jednotku do lava. V podstate robim nieco podobne ako keby som celemu cislu priradil cislo 10 umocnene na to cele cislo. A teraz zacne sranda spravim si premennu kolizii, napr. c, a skumam cisla. Zoberem 1. ulozim ho do premennej pre vsetky cisla, idem na druhe a skumam col = x2 & p, kde p je premenna do ktorej budes davat postupne vsetky cisla cize potom by si mal dostat, ak su dobre, nieco taketo (000...0111111111). Ak je cislo dobre tak ho vlozis do p = p | x_k, k-te nacitane cislo. Ak ti bude nieco kolidovat tak to zistis na premennej col, ze je nenulova a navise hodnota cisla ktora koliduje prave poradie tej jednotky v col + 1. Ale mozno viac napovie kod: 

public static int ChybaBlok(int[][] blok/*je velkosti 3x3*/){
	short p=0, col=0;
	for(int i=0; i<3; i++){
		for(int j=0; j<3; j++){
			short v = 1<<(blok[i][j]-1); // bude treba asi osterit este ak je tam 0 a cislo vacsie ako 9
			col = col | (p & v); // ak najdes prvok ktory sa v bloku 
						//uz nachadza pridas ho medzi 
						//kolidujuce prvky  
			p = p | v; // ak uz sa v p nachadza tak to p nezmeni, ak nie 
					// tak ho prida
		}
	}
	return col; // nebude to odosielat true alebo false, ale cisla v ktorych 
			//koliduje alebo 0, co je nieco podobne, ale mas tu skritej viac informacie.
			// Mozes reverzne kolidujuce prvky vyhladat
}
Nahlásit jako SPAM
IP: 158.195.195.–
Petr
~ Anonymní uživatel
746 příspěvků
20. 11. 2012   #8
-
0
-

To je nejaky divny... kdyz mi to vrati "col" jako nejaky cislo, co s tim pak zmuzu? Jak z toho poznam ze to koliduje v 5ty bunce a nebo ve 2 a ve 3ti ?

Druha vec: moc nechapu zapis s "|" a "&" aktualne sem ej pouzival akorat logickych operatorech jako "||" nebo "&&"...

Nahlásit jako SPAM
IP: 81.201.55.–
sleepy0
Stálý člen
20. 11. 2012   #9
-
0
-

#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
}
Nahlásit jako SPAM
IP: 158.195.195.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 29 hostů

Podobná vlákna

Zvíraznenie bloku — založil Jojo

XHTML a zformátování bloku — založil beachboy

Odřádkování bloku MSVS — založil Kenvelo

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý