Vídite tam chybu? – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Vídite tam chybu? – C / C++ – Fórum – Programujte.comVídite tam chybu? – C / C++ – Fórum – Programujte.com

 

Epoxi0
Newbie
28. 10. 2013   #1
-
0
-

   

#include <stdio.h>
#include <string.h>
#include "zapoctovy-program.c"
#include "funkcni_prototypy.h"


int main(void)
{


	printf("\n******* SUDOKU *******\n\n");
	printf("Sudoku zobrazuje reseni krok po kroku.\n\n");
	printf("Zadej %d radku o %d cislech.\n", 9, 9);
	printf("Cisla mohou byt oddelena libovolnym znakem\n");
	printf("Zadej nulu pro prazdne pole.\n");
	printf("Pro ukonceni zadej pismeno Q.\n\n");
	while (zadej_zadani()) {
		citac = 0;
		vyres_sudoku();
		zobraz_sudoku();
		if (! hotove_sudoku()) printf("Neco je spatne\n");
		printf("Pocet testu: %ld\n\n", citac);
	}/*konec while*/
	printf("\n");
	return 0;
}
#ifndef funkci_prototypy_H
#define funkci_prototypy_H

static long int citac;
static char sudoku[9][9];

/*------Funkce ktere kontroluji zadani atd.------*/
int zadej_zadani(void);
int zadej_radek(int radek);
int zkontroluj_vstupni_zadani(void);
int zkontroluj_vstupni_radky(void);
int zkontroluj_vstupni_radek(int radek);
int zkontroluj_vstupni_sloupce(void);
int zkontroluj_vstupni_sloupec(int sloupec);
int zkontroluj_vstupni_ctverecky(void);
int zkontroluj_vstupni_ctverecek(int ctverecek);
void transformuj_ctverecek(char buffer[], int ctverecek);
int zkontroluj_diagonalu(void);
int zkontroluj_vstupni_diagonalu(int i);
int zkontroluj_druhou_diagonalu(void);
int zkontroluj_druhou_vstupni_diagonalu(int i);

/*------Funkce pro reseni------*/
void vyres_sudoku(void);
int volne_pole_cislo(int cislo, int radek, int sloupec);
void transformuj_ctverecek_poli(char buffer[], int radek, int sloupec);
/*-------Ostatni-------*/
void zobraz_sudoku_cekani(void);
void zobraz_sudoku(void);
void obrazek(int cislo);
int hotove_sudoku(void);
void cekani(void);

#endif
#include "funkcni_prototypy.h"

int zadej_zadani(void) /* Funkce pozada o zadani na kazdem radku 9 cisel */
{
	int radek; char sudoku;

	printf("Zadejte prosim zadani: \n");

	while (1){
		for (radek = 0; radek < 9; radek++){
			if (! zadej_radek(radek)) return (0);
		}/*konec for*/
		printf("\n Problem sudoku: \n");
		zobraz_sudoku();
		if (zkontroluj_vstupni_zadani()) return(1);
		else printf("\n");
	}/*konec while*/
}/*konec zadej_zadani*/

int zadej_radek(int radek) /*Do pole se zadavaji cisla od 0 do 9, nezalezi jestli jsou oddelena od sebe nebo ne. /
                           /*Pouze prvnich 9 cisel bude nacteno*/
                           /*Pouzil jsem fgets() s gets() to nemusi fungovat*/
 {

	int c, i;
	int sloupec = 0;
	int vysledek = 1;

	/*Nulovani pole*/
	for (i = 0; i < 9; i++) {
		sudoku[radek][i] = 0;
	}/*konec for*/
	printf("radek %d : ", radek + 1);
	while(1){
		c = getc(stdin);
		if (c == feof(stdin) || c == 0x0A) return vysledek;
		else if ((c == 'Q') || (c == 'q')) vysledek = 0;
		/*Prevede zadani do radku sudoku*/
		else if ((vysledek) && (sloupec < 9) && (c >= '0') && (c <= '9')) {
            sudoku[radek][sloupec++] = c - 48;
		}/*konec if*/
	}/* konec while*/
}/*konec zadej_radek*/

int zkontroluj_vstupni_zadani(void) /*Jednotlive funkce zkontroluji, jestli nebylo zadano zadani*/
{                                    /*Tim se vyhneme dalsim problemum*/
	int vysledek = 1;

	if (! zkontroluj_vstupni_radky())         vysledek = 0;
	if (! zkontroluj_vstupni_sloupce())       vysledek = 0;
	if (! zkontroluj_vstupni_ctverecky())     vysledek = 0;
    if (! zkontroluj_diagonalu())             vysledek = 0;
    if (! zkontroluj_druhou_diagonalu())      vysledek = 0;

	return vysledek;
}/*konec zkontroluj_vstupni_zadani*/

int zkontroluj_diagonalu(void) /*Zkontroluje, jestli nejsou dve stejna cisla na digonale*/
{                              /*pomoci nasledujici funkce*/
	int i;
	int vysledek = 1;

		if (! zkontroluj_vstupni_diagonalu(i)) vysledek = 0;

	return vysledek;
}

int zkontroluj_vstupni_diagonalu(int i)
{
	int j, k , l;

	for (i = 0; i < 8; i++) {
		if ( sudoku[i][i] == 0 ) continue;
		for (j = i + 1; j < 9; j++) {
			if (sudoku[j][j] == sudoku[i][i]) {
				printf("chyba v digonale na radku %d a %d: stejna cisla\n", i + 1, j + 1);
             return 0;
			}/*konec if*/
		}/*konec for j*/
	}/*konec for i*/
	return 1;
}/*konec zkontroluj_vstupni_diagonalu*/

int zkontroluj_druhou_diagonalu(void) /*Zkontroluje, jestli nejsou dve stejna cisla na digonale*/
{                                     /*pomoci nasledujici funkce*/
	int i;
	int vysledek = 1;

		if (! zkontroluj_druhou_vstupni_diagonalu(i)) vysledek = 0;

	return vysledek;
}

int zkontroluj_druhou_vstupni_diagonalu(int i)
{
    int m, n, l, k, j;


 for (i = 0; i < 8; i++) {
     m = 8; n = 0;
     n = m - i;
        if ( sudoku[i][m] == 0 ) continue;
        for (j = i + 1; j < 9; j++) {
            n = 8; l = 0;
            l = n - j;
            if (sudoku[j][l] == sudoku[i][m]) {
                printf("chyba v digonale na radku %d a %d: stejna cisla\n", i + 1, j + 1);
                return (0);
            }
        }
    }
    return 1;
}/*konec zkontroluj_druhou_vstupni_diagonalu*/

int zkontroluj_vstupni_radky(void) /*Zkontroluje, jestli nejsou dve stejna cisla na radkach*/
{
	int radek;
	int vysledek = 1;
	for (radek = 0; radek < 9; radek++) {
		if (! zkontroluj_vstupni_radek(radek)) vysledek = 0;
	}/*konec for*/
	return vysledek;
}/*konec zkontroluj_vstupni_radky*/

int zkontroluj_vstupni_radek(int radek) /*Zkontroluje, jestli nejsou dve stejna cisla na radkach */
{
	int i, j;

	for (i = 0; i < 8; i++) {
		if ( sudoku[radek][i] == 0 ) continue;
		for (j = i + 1; j < 9; j++) {
			if (sudoku[radek][i] == sudoku[radek][j]) {
				printf("Chyba radku %d: stejna cisla\n", radek + 1);
				return 0;
			}/*konec if*/
		}/*konec for j*/
	}/*konec for i*/
	return 1;
}/* konec zkontroluj_vstupni_radek*/

int zkontroluj_vstupni_sloupce(void) /*Zkontroluje, jestli nejsou stejna cisla ve sloupcich*/
{
	int sloupec;
	int vysledek = 1;
	for (sloupec = 0; sloupec < 9; sloupec++) {
		if (! zkontroluj_vstupni_sloupec(sloupec)) vysledek = 0;
	}/*konec for*/
	return vysledek;
}/*konec zkontroluj_vstupni_sloupce*/

int zkontroluj_vstupni_sloupec(int sloupec) /*Zkontroluje, jestli nejsou stejna cisla ve sloupci*/
{
	int i, j;
	for (i = 0; i < 8; i++) {
		if ( sudoku[i][sloupec] == 0 ) continue;
		for (j = i + 1; j < 9; j++) {
			if (sudoku[i][sloupec] == sudoku[j][sloupec]) {
				printf("Chyba sloupec %d: stejna cisla\n", sloupec + 1);
				return 0;
			}/*konec if*/
		}/*konec for j*/
	}/*konec for i*/
	return 1;
}/*konec zkontroluj_vstupni_sloupec*/


int zkontroluj_vstupni_ctverecky(void) /*Zkontroluje, jestli nejsou stejna ciala v malych ctvercich (3x3)*/
{
	int ctverecek;
	int vysledek = 1;
	for (ctverecek = 0; ctverecek < 9; ctverecek++) {
		if (! zkontroluj_vstupni_ctverecek(ctverecek)) vysledek = 0;
	}/*konec for*/
	return vysledek;
}/*konec zkontroluj_vstupni_ctverecky*/

int zkontroluj_vstupni_ctverecek(int ctverecek) /*Zkontroluje, jestli nejsou stejna cisla v malem cverci (3x3)*/
{
	char buffer[35];
	int i, j;

	transformuj_ctverecek(buffer, ctverecek);

	for (i = 0; i < 8; i++) {
		if (buffer[i] == 0 ) continue;
		for (j = i + 1; j < 9; j++) {
			if (buffer[i] == buffer[j]) {
				printf("Chyba v 3x3 %d: stejna cisla\n", ctverecek + 1);
				return 0;
			}/*konec if*/
		}/*konec for j*/
	}/*konec for  */
	return 1;
}/*konec zkontroluj_vstupni_ctverecek*/


void transformuj_ctverecek(char buffer[], int ctverecek) /*Prevede ctverec 3x3 do 1-dimenzionalniho pole*/
{
	int i, j, k, l, m;

	k = (((ctverecek) % 3) * 3);
	l = (((ctverecek + 3) / 3) * 3) - 3;
	m = 0;
	for (j = l; j < l + 3; j++) {
		for (i = k; i < k + 3; i++) {
			buffer[m++] = sudoku[j][i];
		}/*konec for i*/
	}/*konec for j*/
}/*konec transformuj_ctverecek*/

/*------Funkce pro reseni------*/

void vyres_sudoku(void) /*rekurzivni funkce*/
{
	int radek, sloupec, cislo, buffer_cislo;

	for (radek = 0; radek < 9; radek++) {
		for (sloupec = 0; sloupec < 9; sloupec++) {
			if (sudoku[radek][sloupec]) continue;
			for (cislo = 1; cislo <= 9; cislo++) {
				if (! volne_pole_cislo(cislo, radek, sloupec)) continue;
				buffer_cislo = sudoku[radek][sloupec];
				sudoku[radek][sloupec] = cislo;
				citac++;
				/*zobraz_sudoku_cekani();*/
				vyres_sudoku();
				if (hotove_sudoku()) return;
                sudoku[radek][sloupec] = buffer_cislo;
			}/*konec for cislo*/
			return;
		}/*konec for sloupec*/
	}/*konec for radek*/
	return;
}/*konec vyres_sudoku */

int volne_pole_cislo(int cislo, int radek, int sloupec) /*Funkce testuje, jestli cislo uz je v poli, radku, 3x3 nebo diagonale*/
{
    char buffer[35];

	int i, j, k, l, m, n, a , b;



 	for (i = 0; i < 8; i++) {
             a = 0;
    	     a +=  i;
            if (sudoku[i][a] == 0 ) continue;
		for (j = i + 1; j < 9; j++) {
		   b = 0;
              b += j;
			if (sudoku[j][b] == sudoku[i][a]) return (0);
        }
    }

        for (i = 0; i < 8; i++) {
            k = 8;
            m = 0;
            m = k - i;
            if ( sudoku[i][m] == 0 ) continue;
        for (j = i + 1; j < 9; j++) {
            n = 8;
            l = 0;
            l = n - j;
            if (sudoku[j][l] == sudoku[i][m]) return (0);
        }
    }

	for (i = 0; i < 9; i++) if (sudoku[radek][i] == cislo)   return(0);
	for (i = 0; i < 9; i++) if (sudoku[i][sloupec] == cislo) return(0);



	transformuj_ctverecek_poli(buffer, radek, sloupec);
	for (i = 0; i < 9; i++) if (buffer[i] == cislo) return (0);


	/* Jestli se mozne dane cislo doplnit podle splnenych podminek vrati funkce TRUE*/
	return(1);
}/*konec volne_pole_cislo*/

void transformuj_ctverecek_poli(char buffer[], int radek, int sloupec)
{
	int i, j, k;

	while ((radek % 3) != 0) radek--;
	while ((sloupec % 3) != 0) sloupec--;
	k = 0;
	for (j = radek; j < radek + 3; j++) {
		for (i = sloupec; i < sloupec + 3; i++) {
			buffer[++k] = sudoku[j][i];
		}/*konec for i*/
	}/*konec for j*/
}/*konec transformuj_ctverecek_poli*/

/*-------Ostatni-------*/
void zobraz_sudoku_cekani(void) /*Zobrazi sudoku a bude cekat na stisknuti klavesy*/
{

	zobraz_sudoku();
	printf("%ld, zadejte klavesu pro pokracovani", citac);
	cekani();
}/*konec zobraz_sudoku_cekani */

void zobraz_sudoku(void) /*zobraz sudoku*/
{
	int radek, sloupec;
	for (radek = 0; radek < 9; radek++) {
		for (sloupec = 0; sloupec < 9; sloupec++) {
			printf(" %1d ", sudoku[radek][sloupec]);
			if ( ((sloupec % 3) == 2) && (sloupec < 8) ) {
				printf(" | ");
			}
		}/*konec for sloupec*/
		printf("\n");
		if ( ((radek % 3) == 2) && (radek < 8) ) {
			obrazek(33);
		}
	}/*konec for radek*/
	printf("\n");
}/*konec zobraz_sudoku*/

void obrazek(int cislo) /*zobrazuje dany znak, aby byl vysledek prehlednejsi*/
{
	int i;
	for (i = 1; i <= cislo; i++) {
		printf("-");
	}
	printf("\n");
}/*konec obrazek*/

int hotove_sudoku(void)                 /*zkontroluje, jestli je sudoku hotove(plne)*/
{                                       /*jestli ano vraci TRUE, jestli ne vraci FALSE*/
	int radek, sloupec;                 /*zacina od konce*/
	for (radek = 8; radek >= 0; radek--) {
		for (sloupec = 8; sloupec >= 0; sloupec--) {
			if (sudoku[radek][sloupec] == 0 ) {
				return 0;
			}
		}/*konec for sloupec*/
	}/*konec for radek*/
	return 1;
}/*konec hotove_sudoku*/

void cekani(void) /*Ceka na stisk klavesy enter*/
{
	char c;
	while(1){
		c = fgetc(stdin);
		if (c == feof(stdin) || c == 0x0A) return;
	}/*konec while*/
}/*konec funkce cekani*/
Nahlásit jako SPAM
IP: 93.185.11.–
Epoxi0
Newbie
28. 10. 2013   #2
-
0
-

Program funguje, ale možná by nemusel fungovat správně nebo by řešení mohlo trvar příliš dlouho. Kdyby jste si něčeho někdo všiml, prosím napište.

Nahlásit jako SPAM
IP: 93.185.11.–
Epoxi0
Newbie
28. 10. 2013   #3
-
0
-

   

int zkontroluj_druhou_vstupni_diagonalu(int i)
{
    int m, n, l, k, j;


 for (i = 0; i < 8; i++) {
     m = 8; n = 0;
     n = m - i;
        if ( sudoku[i][m] == 0 ) continue;
        for (j = i + 1; j < 9; j++) {
            n = 8; l = 0;
            l = n - j;
            if (sudoku[j][l] == sudoku[i][m]) {
                printf("chyba v digonale na radku %d a %d: stejna cisla\n", i + 1, j + 1);
                return (0);
            }
        }
    }
    return 1;
}/*konec zkontroluj_druhou_vstupni_diagonalu*/

Prehlidl jsem tu drobnost. Místo m má být n. Cvičící říká, že má může byt chyba v proměnných. Nic jsme nenašel, Program funguje navenek správně.

Nahlásit jako SPAM
IP: 93.185.11.–
Epoxi0
Newbie
28. 10. 2013   #4
-
0
-

+ pro přehlednost jsem upravil tohle  

int zkontroluj(void)
{
  int i, a, j, b;

  for (i = 0; i < 8; i++) {
             a = 0;
    	     a +=  i;
            if (sudoku[i][a] == 0 ) continue;
		for (j = i + 1; j < 9; j++) {
		      b = 0;
              b += j;
			if (sudoku[j][b] == sudoku[i][a]) return (0);
        }
    }
}

int zkontroluj2(void)
{
  int i, j, k, m, n, l;

        for (i = 0; i < 8; i++) {
            k = 8;
            m = 0;
            m = k - i;
            if ( sudoku[i][m] == 0 ) continue;
        for (j = i + 1; j < 9; j++) {
            n = 8;
            l = 0;
            l = n - j;
            if (sudoku[j][l] == sudoku[i][m]) return (0);
        }
    }
}

int volne_pole_cislo(int cislo, int radek, int sloupec) /*Funkce testuje, jestli cislo uz je v poli, radku, 3x3 nebo diagonale*/
{
    int i;
    char buffer[50];

	zkontroluj();
	zkontroluj2();

	for (i = 0; i < 9; i++) if (sudoku[radek][i] == cislo)   return(0);
	for (i = 0; i < 9; i++) if (sudoku[i][sloupec] == cislo) return(0);



	transformuj_ctverecek_poli(buffer, radek, sloupec);
	for (i = 0; i < 9; i++) if (buffer[i] == cislo) return (0);


	/* Jestli se mozne dane cislo doplnit podle splnenych podminek vrati funkce TRUE*/
	return(1);
}/*konec volne_pole_cislo*/


Zapsal jsem i do funkčních prototypů

Nahlásit jako SPAM
IP: 93.185.11.–
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, 11 hostů

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ý