Diagonalní sudoku – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama
Reklama

Diagonalní sudoku – C / C++ – Fórum – Programujte.comDiagonalní sudoku – C / C++ – Fórum – Programujte.com

 

Hledá se programátor! Plat 1 800 € + bonusy (firma Boxmol.com)
Epoxi0
Newbie
15. 10. 2013   #1
-
0
-

   

#include <stdio.h>
#include <string.h>
/* Size of the sub-squares also called "boxes", "blocks", "regions" */
#define MIN 3
/* Size of the large square also called "grid" */
#define MAX 9
/* Return code functions */
#define FALSE 0
#define TRUE 1

char sudoku[MAX][MAX]; /* The grid */
long int citac; /* Test counter */
int g_display_flag; /* Flag for displaying set by the option -a */
/********/
int main(int argc, char *argv[]);
int zobraz_pamarametr(char t[]);
/**** INPUTS AND CHECKS ****/
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 sub_square);
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);

/**** RESOLUTION ****/
void vyres_sudoku(void);
int volne_pole_cislo(int number, int row, int sloupec);
void transformuj_ctverecek_poli(char buffer[], int radek, int sloupec);
/**** MISCELLANEOUS ****/
void zobraz_sudoku_cekani(void);
void zobraz_sudoku(void);
void obrazek(int cislo);
int hotove_sudoku(void);
void cekani(void);
int zkontroluj_vstupni_diagonalu2(void);

/******/
int main(int argc, char *argv[])
/******/
{
	/* Display option in resolve() function. */
	g_display_flag = ((argc >= 2) && (zobraz_pamarametr(argv[1])));
	/**********/
	printf("\n******* SUDOKU *******\n\n");
	printf("Sudoku zobrazuje reseni krok po kroku.\n\n");
	printf("Zadej %d radku o %d cislech.\n", MAX, MAX);
	printf("Cisla mohou byt oddelena libovolnym cislem.\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("Wrong problem...\n");
		printf("Tests: %ld\n\n", citac);
	}/* end while */
	printf("\n");
	return 0;
}

/*******************/
int zobraz_pamarametr (char t[])
/*******************/
{
	/* Return TRUE if the user has typed an application with a display option
	in the form: a, A, or /a, /A, or -a, -A, etc ... otherwise return FALSE. */
	char c;
	if (strlen(t) == 1) c = t[0];
	else if (strlen(t) == 2) c = t[1];
	else c = 0;
	return ((c == 'A') || (c == 'a'));
}/* end display_parameter */

/***************************/
/**** INPUTS AND CHECKS ****/
/***************************/

/************/
int zadej_zadani(void)
/************/
{/* User inputs 9 lines of 9 digits. */
	int radek;
	printf("Enter your Sudoku puzzle: \n");
	while (TRUE){
		for (radek = 0; radek < MAX; radek++){
			if (! zadej_radek(radek)) return (FALSE);
		}/* end for */
		printf("\nSudoku problem: \n");
		zobraz_sudoku();
		if (zkontroluj_vstupni_zadani()) return(TRUE);
		else printf("\n");
	}/* end while */
}/* input_grid */

/**************/
int zadej_radek(int radek)
/**************/
{
/* The user must enter a line from 0 to 9 digits
separated or not by one or more characters.
Only the first 9 digits are retained.
The most practical: Numerical keypad and
put a point after every 3rd number.
Avoid using gets() because of overflows.
In this case, remember to completely empty the buffer. */
	int c, i;
	int sloupec = 0;
	int vysledek = TRUE;
	/* Reset to zero of the cells in the row. */
	for (i = 0; i < MAX; i++) {
		sudoku[radek][i] = 0;
	}/* for */
	/*******/
	printf("row %d : ", radek + 1);
	while(TRUE){
		c = fgetc(stdin);
		if (c == feof(stdin) || c == 0x0A) return vysledek;
		else if ((c == 'Q') || (c == 'q')) vysledek = FALSE;
		/* Transfer the keyboard input line into the row of the grid. */
		else if ( (vysledek) && (sloupec < MAX) && (c >= '0') && (c <= '9')) {
            sudoku[radek][sloupec++] = c - 48;
		}/*end if */
	}/* end while */
}/*end input_a_line */

int zkontroluj_diagonalu(void)
/*********************/
{/* Checks if no duplicate into the columns. */
	int i;
	int vysledek = TRUE;

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

	return vysledek;
}

int zkontroluj_vstupni_diagonalu(int i)
/*******************/
{/* Checks if no duplicate into the row. */
	int j;
	for (i = 0; i < MAX - 1; i++) {
		if ( sudoku[i][i] == 0 ) continue;
		for (j = i + 1; j < MAX; j++) {
			if (sudoku[j][j] == sudoku[i][i]) {
				printf("Error row %d and %d equal numbers\n", i + 1, j + 1);
             return FALSE;
			}/* end if */
		}/* end for j */
	}/* end for i */
	return TRUE;
}/* end check_input_a_row */

int zkontroluj_druhou_diagonalu(void)
/*********************/
{/* Checks if no duplicate into the columns. */
	int i;
	int vysledek = TRUE;

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

	return vysledek;
}

int zkontroluj_druhou_vstupni_diagonalu(int i)
/*******************/
{/* Checks if no duplicate into the row. */
	int j, k, l;
	for (i = 0; i < MAX - 1; i++) {
      k = 9 - i;
		if ( sudoku[i][k] == 0 ) continue;
		for (j = i + 1; j > MAX + 1; i ++) {
		    l = 9 - j;
			if (sudoku[i][k] == sudoku[j][l]) {
				printf("Error row %d and %d equal numbers\n", i + 1, j + 1);
				return FALSE;
			}/* end if */
		}/* end for j */
	}/* end for i */
	return TRUE;
}/* end check_input_a_row */

/******************/
int zkontroluj_vstupni_zadani(void)
/******************/
{/* Check whether any duplicate throughout the grid. */
	int vysledek = TRUE;
	if (! zkontroluj_vstupni_radky())         vysledek = FALSE;
	if (! zkontroluj_vstupni_sloupce())       vysledek = FALSE;
	if (! zkontroluj_vstupni_ctverecky())     vysledek = FALSE;
    if (! zkontroluj_diagonalu())             vysledek = FALSE;
	if (! zkontroluj_druhou_diagonalu())      vysledek = FALSE;
	return vysledek;
}/* end check_input_grid */

/******************/
int zkontroluj_vstupni_radky(void)
/******************/
{/* Checks if no duplicate into the rows. */
	int radek;
	int vysledek = TRUE;
	for (radek = 0; radek < MAX; radek++) {
		if (! zkontroluj_vstupni_radek(radek)) vysledek = FALSE;
	}/* end for */
	return vysledek;
}/* end check_input_rows */

/*******************/
int zkontroluj_vstupni_radek(int radek)
/*******************/
{/* Checks if no duplicate into the row. */
	int i, j;
	for (i = 0; i < MAX - 1; i++) {
		if ( sudoku[radek][i] == 0 ) continue;
		for (j = i + 1; j < MAX; j++) {
			if (sudoku[radek][i] == sudoku[radek][j]) {
				printf("Error row %d: and  equal numbers\n", radek + 1);
				return FALSE;
			}/* end if */
		}/* end for j */
	}/* end for i */
	return TRUE;
}/* end check_input_a_row */


/*********************/
int zkontroluj_vstupni_sloupce(void)
/*********************/
{/* Checks if no duplicate into the columns. */
	int sloupec;
	int vysledek = TRUE;
	for (sloupec = 0; sloupec < MAX; sloupec++) {
		if (! zkontroluj_vstupni_sloupec(sloupec)) vysledek = FALSE;
	}/* end for */
	return vysledek;
}/* end check_input_columns */

/**********************/
int zkontroluj_vstupni_sloupec(int sloupec)
/**********************/
{/* Checks if no duplicate into the column. */
	int i, j;
	for (i = 0; i < MAX - 1; i++) {
		if ( sudoku[i][sloupec] == 0 ) continue;
		for (j = i + 1; j < MAX; j++) {
			if (sudoku[i][sloupec] == sudoku[j][sloupec]) {
				printf("Error column %d: equal numbers\n", sloupec + 1);
				return FALSE;
			}/* end if */
		}/* end for j */
	}/* end for i */
	return TRUE;
}/* end check_input_a_column */

/*************************/
int zkontroluj_vstupni_ctverecky(void)
/*************************/
{/* Checks if no duplicate into the sub-squares of 3 x 3. */
	int ctverecek;
	int vysledek = TRUE;
	for (ctverecek = 0; ctverecek < MAX; ctverecek++) {
		if (! zkontroluj_vstupni_ctverecek(ctverecek)) vysledek = FALSE;
	}/* end for */
	return vysledek;
}/* end check_input_sub_squares */

/**************************/
int zkontroluj_vstupni_ctverecek(int ctverecek)
/**************************/
{/* Checks if no duplicate into the sub-square of 3 x 3. */
	char buffer[MAX + 10];
	int i, j;
	transformuj_ctverecek(buffer, ctverecek);
	for (i = 0; i < MAX - 1; i++) {
		if (buffer[i] == 0 ) continue;
		for (j = i + 1; j < MAX; j++) {
			if (buffer[i] == buffer[j]) {
				printf("Error sub-square %d: equal numbers\n", ctverecek + 1);
				return FALSE;
			}/* end if */
		}/* end for j */
	}/* end for i */
	return TRUE;
}/* end check_input_a_sub_square */

/*******************/
void transformuj_ctverecek(char buffer[], int ctverecek)
/*******************/
{/* Transfer the sub-square of 3 x 3 into a one-dimensional array. */
	int i, j, x, y, z;
	x = (((ctverecek) % MIN) * MIN);
	y = (((ctverecek + MIN) / MIN) * MIN) - MIN;
	z = 0;
	for (j = y; j < y + MIN; j++) {
		for (i = x; i < x + MIN; i++) {
			buffer[z++] = sudoku[j][i];
		}/* end for i */
	}/* end for j */
}/* end trans_sub_square */


/**** RESOLUTION ****/
/********************/

void vyres_sudoku(void)
/**********/
{/* Attention, recursive function... */
	int radek, sloupec, cislo, buffer_cislo;
	for (radek = 0; radek < MAX; radek++) {
		for (sloupec = 0; sloupec < MAX; sloupec++) {
			if (sudoku[radek][sloupec]) continue;
			for (cislo = 1; cislo <= MAX; cislo++) {
				if (! volne_pole_cislo(cislo, radek, sloupec)) continue;
				buffer_cislo = sudoku[radek][sloupec];
				sudoku[radek][sloupec] = cislo;
				citac++;
				if (g_display_flag) zobraz_sudoku_cekani();
				vyres_sudoku();
				if (hotove_sudoku()) return;
				/* To see all the solutions of the grids
				with multiple solutions,
				switch the line above as a comment and
				remove the comment command of the line below. */
				/* if (hotove_sudoku()) zobraz_sudoku_cekani();*/
				sudoku[radek][sloupec] = buffer_cislo;
			}/* end for number */
			return;
		}/* end for col */
	}/* end for row */
	return;
}/* end resolve */

int volne_pole_cislo(int cislo, int radek, int sloupec)
/**********************/
{
/* Test if the number is already in
the line, or the column, or the sub-square of 3 X 3
afferent at the cell pointed to by line and column. */
	char buffer[MAX + 10];
	int i;
	/* If the number is used in the line return FALSE */
	for (i = 0; i < MAX; i++) if (sudoku[radek][i] == cislo) return(FALSE);
	/* If the number is used in the column return FALSE */
	for (i = 0; i < MAX; i++) if (sudoku[i][sloupec] == cislo) return(FALSE);
	/* If the number is used in the sub-square of 3 X 3 return FALSE */
	transformuj_ctverecek_poli(buffer, radek, sloupec);
	for (i = 0; i < MAX; i++) if (buffer[i] == cislo) return (FALSE);
	/* whereby the number is available for the cell, return TRUE. */
	return(TRUE);
}/* end free_cell_for_number */

/***************************/
void transformuj_ctverecek_poli(char buffer[], int radek, int sloupec)
/***************************/
/* Transfer the sub-square of 3 x 3 of
the cell into a one-dimensional array. */
{
	int i, j, k;
	while ((radek % MIN) != 0) radek--;
	while ((sloupec % MIN) != 0) sloupec--;
	k = 0;
	for (j = radek; j < radek + MIN; j++) {
		for (i = sloupec; i < sloupec + MIN; i++) {
			buffer[++k] = sudoku[j][i];
		}/* end for i */
	}/* end for j */
}/* end trans_sub_square_of_cell */

/***********************/
/**** MISCELLANEOUS ****/
/***********************/

/***********************/
void zobraz_sudoku_cekani(void)
/***********************/
{/* Display the grid with wait for the enter key on the keybord. */
	zobraz_sudoku();
	printf("%ld, hit the enter key for continuation.", citac);
	cekani();
}/* display_grid_waiting */

/***************/
void zobraz_sudoku(void)
/***************/
{/* Display the grid. */
	int radek, sloupec;
	for (radek = 0; radek < MAX; radek++) {
		for (sloupec = 0; sloupec < MAX; sloupec++) {
			printf(" %1d ", sudoku[radek][sloupec]);
			if ( ((sloupec % MIN) == MIN - 1) && (sloupec < MAX - 1) ) {
				printf(" | ");
			}
		}/* end for col */
		printf("\n");
		if ( ((radek % MIN) == MIN - 1) && (radek < MAX-1) ) {
			obrazek(33);
		}
	}/* end for row */
	printf("\n");
}/* end display_grid */

/*****************/
void obrazek(int cislo)
/*****************/
{/* Displays a sequence of asterisk character. */
	int i;
	for (i = 1; i <= cislo; i++) {
		printf("-");
	}
	printf("\n");
}/* end display_string */

/****************/
int hotove_sudoku(void)
/****************/
/* Test if the grid is finished.
Return TRUE if grid completed, otherwise return FALSE.
Begins with the end of the grid,
this one being completed by its beginning. */
{
	int radek, sloupec;
	for (radek = MAX - 1; radek >= 0; radek--) {
		for (sloupec = MAX - 1; sloupec >= 0; sloupec--) {
			if (sudoku[radek][sloupec] == 0 ) {
				return FALSE;
			}
		}/* end for col */
	}/* end for row */
	return TRUE;
}/* end finished_grid */

/**********/
void cekani(void)
/**********/
{/* Wait for the enter key on the keybord. */
	char c;
	while(TRUE){
		c = fgetc(stdin);
		if (c == feof(stdin) || c == 0x0A) return;
	}/* end while */
}/* end waiting */

Zdravím, potřeboval bych tento program dopsat tak, aby z toho bylo diagonální sudoku. Snažím se něco dopsat do funkce int volne_pole_cislo(int cislo, int radek, int sloupec).

Nahlásit jako SPAM
IP: 2001:718:2:a2:6dec:bf3c:a...–
Reklama
Reklama
epoxi
~ Anonymní uživatel
35 příspěvků
15. 10. 2013   #2
-
0
-

Chapu, ze se do toho nikomu nechce. Programuju asi 2 mesice, mam velmi male zkusenosti s programovanim. Prosil bych aspon jak na to. Nevim s tim hnout. Obycejne sudoku je vsude na internetu, tak se da obkoukat jak se to ma delat

Zasláno z mobilního telefonu.

Nahlásit jako SPAM
IP: 2001:718:7:204:88ef:bd58:...–
Epoxi
~ Anonymní uživatel
35 příspěvků
16. 10. 2013   #3
-
0
-

No, dopsal jsem to takto a nefunguje to
 

int volne_pole_cislo(int cislo, int radek, int sloupec)
/**********************/
{
/* Test if the number is already in
the line, or the column, or the sub-square of 3 X 3
afferent at the cell pointed to by line and column. */
	char buffer[MAX + 10];
	int i, j,  k, l, m, n;
	for (i = 0; i < MAX; i++) if (sudoku[radek][i] == cislo) return(FALSE);
	/* If the number is used in the line return FALSE */
	for (i = 0; i < MAX; i++) if (sudoku[i][sloupec] == cislo) return(FALSE);
	/* If the number is used in the column return FALSE */


	for (i = 0; i < MAX - 1; i++) {
		if ( sudoku[i][i] == 0 ) continue;
		for (j = i + 1; j < MAX; j++) {
			if (sudoku[j][j] == sudoku[i][i]) return (FALSE);
        }
    }

	for (i = 0; i < MAX - 1; i++) {
       k = 8;
       m = 0;
	   m = k - i;
		if ( sudoku[i][m] == 0 ) continue;
		for (j = i + 1; j < MAX; j++) {
		    n = 8;
		    l = 0;
		    l = n - j;
			if (sudoku[j][l] == sudoku[i][m]) return (FALSE);
        }
    }
	/* If the number is used in the sub-square of 3 X 3 return FALSE */
	transformuj_ctverecek_poli(buffer, radek, sloupec);
	for (i = 0; i < MAX; i++) if (buffer[i] == cislo) return (FALSE);
	/* whereby the number is available for the cell, return TRUE. */
	return(TRUE);
}/* end free_cell_for_number */
Nahlásit jako SPAM
IP: 2001:718:2:a2:5566:171a:9...–
vitamin+8
Grafoman
16. 10. 2013   #4
-
0
-

#3 Epoxi
Konkretizuj problém, čo ti nefunguje?

Nahlásit jako SPAM
IP: 195.28.77.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
Epoxi
~ Anonymní uživatel
35 příspěvků
16. 10. 2013   #5
-
0
-

normální sudoku to resi normalne... mam za ukol udelat diagonalni sudoku. Jde o to, ze kdyz zadam same nuly tak mi to vyresi, ale ignoruje prvni diagonalu pole 00 a 88 jsou shodna. A pokud zadam nejake zadani z internetu, neni schopen to vyresit. Vyresi jenom nejake pripady, ale to je nahoda. Zvlastni je, ze pokud smazu


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

tak to vyresi. Potreboval bych na to neco lepsiho.

Nahlásit jako SPAM
IP: 2001:718:2:a2:5566:171a:9...–
Epoxi
~ Anonymní uživatel
35 příspěvků
16. 10. 2013   #6
-
0
-

http://sudokuonline.cz/diagonalni.html Pouzivam zadani z teto stranky. Nektera diagonalni sudoku to vyresi a nektera zase ne. Nemam tuseni proc.

Nahlásit jako SPAM
IP: 2001:718:7:204:3804:cb92:...–
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, 56 hostů

Podobná vlákna

Diagonální sudoku II — založil Epoxi

Cantorova diagonalni metoda — založil tanned88

Sudoku X — založil Epoxi

Projekt Sudoku — založil Zdeňa

Moderátoři diskuze

 

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