Simple recursive Sudoku solver Announcing the arrival of Valued Associate #679: Cesar Manara Unicorn Meta Zoo #1: Why another podcast?What is an algorithm to solve sudoku in efficient way in c?SudokuSharp Solver with advanced featuresSudoku solver in C++N-Queens - Brute force - bit by bitSolver for a number-game (8-queens applied to Sudoku)Sudoku Solver in C++ weekend challengeSudoku puzzle solving algorithm that uses a rule-based approach to narrow the depth searchSudoku solver recursive solution with clear structureRuby Sudoku Solver without classesFast and flexible Sudoku Solver in C++What is an algorithm to solve sudoku in efficient way in c?

Marquee sign letters

Is it OK if I do not take the receipt in Germany?

Does every subgroup of an abelian group have to be abelian?

Is there an efficient way for synchronising audio events real-time with LEDs using an MCU?

What to do with someone that cheated their way though university and a PhD program?

Are `mathfont` and `mathspec` intended for same purpose?

Is a self contained air-bullet cartridge feasible?

Coin Game with infinite paradox

Does Prince Arnaud cause someone holding the Princess to lose?

Errors in solving coupled pdes

Why did Europeans not widely domesticate foxes?

Retract an already submitted recommendation letter (written for an undergrad student)

yticklabels on the right side of yaxis

Where can I find how to tex symbols for different fonts?

Can I criticise the more senior developers around me for not writing clean code?

What do you call an IPA symbol that lacks a name (e.g. ɲ)?

What were wait-states, and why was it only an issue for PCs?

Why isPrototypeOf() returns false?

What is the evidence that custom checks in Northern Ireland are going to result in violence?

Why aren't road bicycle wheels tiny?

Raising a bilingual kid. When should we introduce the majority language?

So I pre ordered a game on my friends home screen but on my Xbox, does that mean I don't get the game and I lost 60$?

How long can a nation maintain a technological edge over the rest of the world?

Israeli soda type drink



Simple recursive Sudoku solver



Announcing the arrival of Valued Associate #679: Cesar Manara
Unicorn Meta Zoo #1: Why another podcast?What is an algorithm to solve sudoku in efficient way in c?SudokuSharp Solver with advanced featuresSudoku solver in C++N-Queens - Brute force - bit by bitSolver for a number-game (8-queens applied to Sudoku)Sudoku Solver in C++ weekend challengeSudoku puzzle solving algorithm that uses a rule-based approach to narrow the depth searchSudoku solver recursive solution with clear structureRuby Sudoku Solver without classesFast and flexible Sudoku Solver in C++What is an algorithm to solve sudoku in efficient way in c?



.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








17












$begingroup$


My Sudoku solver is fast enough and good with small data (4*4 and 9*9 Sudoku). But with a 16*16 board it takes too long and doesn't solve 25*25 Sudoku at all. How can I improve my program in order to solve giant Sudoku faster?



I use backtracking and recursion.



It should work with any size Sudoku by changing only the define of SIZE, so I can't make any specific bit fields or structs that only work for 9*9, for example.



#include <stdio.h>
#include <math.h>

#define SIZE 16
#define EMPTY 0

int SQRT = sqrt(SIZE);

int IsValid (int sudoku[SIZE][SIZE], int row, int col, int number);
int Solve(int sudoku[SIZE][SIZE], int row, int col);

int main()
int sudoku[SIZE][SIZE] =
0,1,2,0,0,4,0,0,0,0,5,0,0,0,0,0,
0,0,0,0,0,2,0,0,0,0,0,0,0,14,0,0,
0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,
11,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,
0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,16,0,0,0,0,0,0,2,0,0,0,0,0,
0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,
0,0,14,0,0,0,0,0,0,4,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,1,16,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,14,0,0,13,0,0,
0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,
16,0,0,0,0,0,11,0,0,3,0,0,0,0,0,0,
;
/*
int sudoku[SIZE][SIZE] =
6,5,0,8,7,3,0,9,0,
0,0,3,2,5,0,0,0,8,
9,8,0,1,0,4,3,5,7,
1,0,5,0,0,0,0,0,0,
4,0,0,0,0,0,0,0,2,
0,0,0,0,0,0,5,0,3,
5,7,8,3,0,1,0,2,6,
2,0,0,0,4,8,9,0,0,
0,9,0,6,2,5,0,8,1
;*/

if (Solve (sudoku,0,0))

for (int i=0; i<SIZE; i++)

for (int j=0; j<SIZE; j++)
printf("%2d ", sudoku[i][j]);

printf ("n");


else

printf ("No solution n");

return 0;


int IsValid (int sudoku[SIZE][SIZE], int row, int col, int number)

int prRow = SQRT*(row/SQRT);
int prCol = SQRT*(col/SQRT);

for (int i=0;i<SIZE;i++)
if (sudoku[i][col] == number) return 0;
if (sudoku[row][i] == number) return 0;
if (sudoku[prRow + i / SQRT][prCol + i % SQRT] == number) return 0;
return 1;


int Solve(int sudoku[SIZE][SIZE], int row, int col)

if (SIZE == row)
return 1;


if (sudoku[row][col])
if (col == SIZE-1)
if (Solve (sudoku, row+1, 0)) return 1;
else
if (Solve(sudoku, row, col+1)) return 1;

return 0;


for (int number = 1; number <= SIZE; number ++)

if(IsValid(sudoku,row,col,number))

sudoku [row][col] = number;

if (col == SIZE-1)
if (Solve(sudoku, row+1, 0)) return 1;
else
if (Solve(sudoku, row, col+1)) return 1;


sudoku [row][col] = EMPTY;


return 0;










share|improve this question











$endgroup$







  • 1




    $begingroup$
    Can you add a 9x9 and 16x16 file? It will make answering easier.
    $endgroup$
    – Oscar Smith
    Mar 25 at 15:16










  • $begingroup$
    When you added the 16 X 16 grid you left the size at 9 rather than changing it to 16. This might lead to the wrong results.
    $endgroup$
    – pacmaninbw
    Mar 25 at 15:32






  • 5




    $begingroup$
    Sudoku is NP complete. No matter what improvements you make to your code, it will become exceptionally slow as SIZE becomes large.
    $endgroup$
    – Benjamin Kuykendall
    Mar 25 at 15:35










  • $begingroup$
    @pacmaninbw oh sorry, I only forgot to change it while I was editing my post earlier. With that part there is no problem, but thank you!
    $endgroup$
    – yeosco
    Mar 25 at 15:40






  • 1




    $begingroup$
    Have you tried to use any heuristic? For example if you try solving for the number that occurs the most often first you will have a smaller problem set to solve.
    $endgroup$
    – pacmaninbw
    Mar 25 at 15:42

















17












$begingroup$


My Sudoku solver is fast enough and good with small data (4*4 and 9*9 Sudoku). But with a 16*16 board it takes too long and doesn't solve 25*25 Sudoku at all. How can I improve my program in order to solve giant Sudoku faster?



I use backtracking and recursion.



It should work with any size Sudoku by changing only the define of SIZE, so I can't make any specific bit fields or structs that only work for 9*9, for example.



#include <stdio.h>
#include <math.h>

#define SIZE 16
#define EMPTY 0

int SQRT = sqrt(SIZE);

int IsValid (int sudoku[SIZE][SIZE], int row, int col, int number);
int Solve(int sudoku[SIZE][SIZE], int row, int col);

int main()
int sudoku[SIZE][SIZE] =
0,1,2,0,0,4,0,0,0,0,5,0,0,0,0,0,
0,0,0,0,0,2,0,0,0,0,0,0,0,14,0,0,
0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,
11,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,
0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,16,0,0,0,0,0,0,2,0,0,0,0,0,
0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,
0,0,14,0,0,0,0,0,0,4,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,1,16,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,14,0,0,13,0,0,
0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,
16,0,0,0,0,0,11,0,0,3,0,0,0,0,0,0,
;
/*
int sudoku[SIZE][SIZE] =
6,5,0,8,7,3,0,9,0,
0,0,3,2,5,0,0,0,8,
9,8,0,1,0,4,3,5,7,
1,0,5,0,0,0,0,0,0,
4,0,0,0,0,0,0,0,2,
0,0,0,0,0,0,5,0,3,
5,7,8,3,0,1,0,2,6,
2,0,0,0,4,8,9,0,0,
0,9,0,6,2,5,0,8,1
;*/

if (Solve (sudoku,0,0))

for (int i=0; i<SIZE; i++)

for (int j=0; j<SIZE; j++)
printf("%2d ", sudoku[i][j]);

printf ("n");


else

printf ("No solution n");

return 0;


int IsValid (int sudoku[SIZE][SIZE], int row, int col, int number)

int prRow = SQRT*(row/SQRT);
int prCol = SQRT*(col/SQRT);

for (int i=0;i<SIZE;i++)
if (sudoku[i][col] == number) return 0;
if (sudoku[row][i] == number) return 0;
if (sudoku[prRow + i / SQRT][prCol + i % SQRT] == number) return 0;
return 1;


int Solve(int sudoku[SIZE][SIZE], int row, int col)

if (SIZE == row)
return 1;


if (sudoku[row][col])
if (col == SIZE-1)
if (Solve (sudoku, row+1, 0)) return 1;
else
if (Solve(sudoku, row, col+1)) return 1;

return 0;


for (int number = 1; number <= SIZE; number ++)

if(IsValid(sudoku,row,col,number))

sudoku [row][col] = number;

if (col == SIZE-1)
if (Solve(sudoku, row+1, 0)) return 1;
else
if (Solve(sudoku, row, col+1)) return 1;


sudoku [row][col] = EMPTY;


return 0;










share|improve this question











$endgroup$







  • 1




    $begingroup$
    Can you add a 9x9 and 16x16 file? It will make answering easier.
    $endgroup$
    – Oscar Smith
    Mar 25 at 15:16










  • $begingroup$
    When you added the 16 X 16 grid you left the size at 9 rather than changing it to 16. This might lead to the wrong results.
    $endgroup$
    – pacmaninbw
    Mar 25 at 15:32






  • 5




    $begingroup$
    Sudoku is NP complete. No matter what improvements you make to your code, it will become exceptionally slow as SIZE becomes large.
    $endgroup$
    – Benjamin Kuykendall
    Mar 25 at 15:35










  • $begingroup$
    @pacmaninbw oh sorry, I only forgot to change it while I was editing my post earlier. With that part there is no problem, but thank you!
    $endgroup$
    – yeosco
    Mar 25 at 15:40






  • 1




    $begingroup$
    Have you tried to use any heuristic? For example if you try solving for the number that occurs the most often first you will have a smaller problem set to solve.
    $endgroup$
    – pacmaninbw
    Mar 25 at 15:42













17












17








17


3



$begingroup$


My Sudoku solver is fast enough and good with small data (4*4 and 9*9 Sudoku). But with a 16*16 board it takes too long and doesn't solve 25*25 Sudoku at all. How can I improve my program in order to solve giant Sudoku faster?



I use backtracking and recursion.



It should work with any size Sudoku by changing only the define of SIZE, so I can't make any specific bit fields or structs that only work for 9*9, for example.



#include <stdio.h>
#include <math.h>

#define SIZE 16
#define EMPTY 0

int SQRT = sqrt(SIZE);

int IsValid (int sudoku[SIZE][SIZE], int row, int col, int number);
int Solve(int sudoku[SIZE][SIZE], int row, int col);

int main()
int sudoku[SIZE][SIZE] =
0,1,2,0,0,4,0,0,0,0,5,0,0,0,0,0,
0,0,0,0,0,2,0,0,0,0,0,0,0,14,0,0,
0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,
11,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,
0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,16,0,0,0,0,0,0,2,0,0,0,0,0,
0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,
0,0,14,0,0,0,0,0,0,4,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,1,16,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,14,0,0,13,0,0,
0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,
16,0,0,0,0,0,11,0,0,3,0,0,0,0,0,0,
;
/*
int sudoku[SIZE][SIZE] =
6,5,0,8,7,3,0,9,0,
0,0,3,2,5,0,0,0,8,
9,8,0,1,0,4,3,5,7,
1,0,5,0,0,0,0,0,0,
4,0,0,0,0,0,0,0,2,
0,0,0,0,0,0,5,0,3,
5,7,8,3,0,1,0,2,6,
2,0,0,0,4,8,9,0,0,
0,9,0,6,2,5,0,8,1
;*/

if (Solve (sudoku,0,0))

for (int i=0; i<SIZE; i++)

for (int j=0; j<SIZE; j++)
printf("%2d ", sudoku[i][j]);

printf ("n");


else

printf ("No solution n");

return 0;


int IsValid (int sudoku[SIZE][SIZE], int row, int col, int number)

int prRow = SQRT*(row/SQRT);
int prCol = SQRT*(col/SQRT);

for (int i=0;i<SIZE;i++)
if (sudoku[i][col] == number) return 0;
if (sudoku[row][i] == number) return 0;
if (sudoku[prRow + i / SQRT][prCol + i % SQRT] == number) return 0;
return 1;


int Solve(int sudoku[SIZE][SIZE], int row, int col)

if (SIZE == row)
return 1;


if (sudoku[row][col])
if (col == SIZE-1)
if (Solve (sudoku, row+1, 0)) return 1;
else
if (Solve(sudoku, row, col+1)) return 1;

return 0;


for (int number = 1; number <= SIZE; number ++)

if(IsValid(sudoku,row,col,number))

sudoku [row][col] = number;

if (col == SIZE-1)
if (Solve(sudoku, row+1, 0)) return 1;
else
if (Solve(sudoku, row, col+1)) return 1;


sudoku [row][col] = EMPTY;


return 0;










share|improve this question











$endgroup$




My Sudoku solver is fast enough and good with small data (4*4 and 9*9 Sudoku). But with a 16*16 board it takes too long and doesn't solve 25*25 Sudoku at all. How can I improve my program in order to solve giant Sudoku faster?



I use backtracking and recursion.



It should work with any size Sudoku by changing only the define of SIZE, so I can't make any specific bit fields or structs that only work for 9*9, for example.



#include <stdio.h>
#include <math.h>

#define SIZE 16
#define EMPTY 0

int SQRT = sqrt(SIZE);

int IsValid (int sudoku[SIZE][SIZE], int row, int col, int number);
int Solve(int sudoku[SIZE][SIZE], int row, int col);

int main()
int sudoku[SIZE][SIZE] =
0,1,2,0,0,4,0,0,0,0,5,0,0,0,0,0,
0,0,0,0,0,2,0,0,0,0,0,0,0,14,0,0,
0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,
11,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,
0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,16,0,0,0,0,0,0,2,0,0,0,0,0,
0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,
0,0,14,0,0,0,0,0,0,4,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,1,16,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,14,0,0,13,0,0,
0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,
16,0,0,0,0,0,11,0,0,3,0,0,0,0,0,0,
;
/*
int sudoku[SIZE][SIZE] =
6,5,0,8,7,3,0,9,0,
0,0,3,2,5,0,0,0,8,
9,8,0,1,0,4,3,5,7,
1,0,5,0,0,0,0,0,0,
4,0,0,0,0,0,0,0,2,
0,0,0,0,0,0,5,0,3,
5,7,8,3,0,1,0,2,6,
2,0,0,0,4,8,9,0,0,
0,9,0,6,2,5,0,8,1
;*/

if (Solve (sudoku,0,0))

for (int i=0; i<SIZE; i++)

for (int j=0; j<SIZE; j++)
printf("%2d ", sudoku[i][j]);

printf ("n");


else

printf ("No solution n");

return 0;


int IsValid (int sudoku[SIZE][SIZE], int row, int col, int number)

int prRow = SQRT*(row/SQRT);
int prCol = SQRT*(col/SQRT);

for (int i=0;i<SIZE;i++)
if (sudoku[i][col] == number) return 0;
if (sudoku[row][i] == number) return 0;
if (sudoku[prRow + i / SQRT][prCol + i % SQRT] == number) return 0;
return 1;


int Solve(int sudoku[SIZE][SIZE], int row, int col)

if (SIZE == row)
return 1;


if (sudoku[row][col])
if (col == SIZE-1)
if (Solve (sudoku, row+1, 0)) return 1;
else
if (Solve(sudoku, row, col+1)) return 1;

return 0;


for (int number = 1; number <= SIZE; number ++)

if(IsValid(sudoku,row,col,number))

sudoku [row][col] = number;

if (col == SIZE-1)
if (Solve(sudoku, row+1, 0)) return 1;
else
if (Solve(sudoku, row, col+1)) return 1;


sudoku [row][col] = EMPTY;


return 0;







performance c recursion sudoku






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 25 at 23:58









Stephen Rauch

3,77061630




3,77061630










asked Mar 25 at 14:59









yeoscoyeosco

865




865







  • 1




    $begingroup$
    Can you add a 9x9 and 16x16 file? It will make answering easier.
    $endgroup$
    – Oscar Smith
    Mar 25 at 15:16










  • $begingroup$
    When you added the 16 X 16 grid you left the size at 9 rather than changing it to 16. This might lead to the wrong results.
    $endgroup$
    – pacmaninbw
    Mar 25 at 15:32






  • 5




    $begingroup$
    Sudoku is NP complete. No matter what improvements you make to your code, it will become exceptionally slow as SIZE becomes large.
    $endgroup$
    – Benjamin Kuykendall
    Mar 25 at 15:35










  • $begingroup$
    @pacmaninbw oh sorry, I only forgot to change it while I was editing my post earlier. With that part there is no problem, but thank you!
    $endgroup$
    – yeosco
    Mar 25 at 15:40






  • 1




    $begingroup$
    Have you tried to use any heuristic? For example if you try solving for the number that occurs the most often first you will have a smaller problem set to solve.
    $endgroup$
    – pacmaninbw
    Mar 25 at 15:42












  • 1




    $begingroup$
    Can you add a 9x9 and 16x16 file? It will make answering easier.
    $endgroup$
    – Oscar Smith
    Mar 25 at 15:16










  • $begingroup$
    When you added the 16 X 16 grid you left the size at 9 rather than changing it to 16. This might lead to the wrong results.
    $endgroup$
    – pacmaninbw
    Mar 25 at 15:32






  • 5




    $begingroup$
    Sudoku is NP complete. No matter what improvements you make to your code, it will become exceptionally slow as SIZE becomes large.
    $endgroup$
    – Benjamin Kuykendall
    Mar 25 at 15:35










  • $begingroup$
    @pacmaninbw oh sorry, I only forgot to change it while I was editing my post earlier. With that part there is no problem, but thank you!
    $endgroup$
    – yeosco
    Mar 25 at 15:40






  • 1




    $begingroup$
    Have you tried to use any heuristic? For example if you try solving for the number that occurs the most often first you will have a smaller problem set to solve.
    $endgroup$
    – pacmaninbw
    Mar 25 at 15:42







1




1




$begingroup$
Can you add a 9x9 and 16x16 file? It will make answering easier.
$endgroup$
– Oscar Smith
Mar 25 at 15:16




$begingroup$
Can you add a 9x9 and 16x16 file? It will make answering easier.
$endgroup$
– Oscar Smith
Mar 25 at 15:16












$begingroup$
When you added the 16 X 16 grid you left the size at 9 rather than changing it to 16. This might lead to the wrong results.
$endgroup$
– pacmaninbw
Mar 25 at 15:32




$begingroup$
When you added the 16 X 16 grid you left the size at 9 rather than changing it to 16. This might lead to the wrong results.
$endgroup$
– pacmaninbw
Mar 25 at 15:32




5




5




$begingroup$
Sudoku is NP complete. No matter what improvements you make to your code, it will become exceptionally slow as SIZE becomes large.
$endgroup$
– Benjamin Kuykendall
Mar 25 at 15:35




$begingroup$
Sudoku is NP complete. No matter what improvements you make to your code, it will become exceptionally slow as SIZE becomes large.
$endgroup$
– Benjamin Kuykendall
Mar 25 at 15:35












$begingroup$
@pacmaninbw oh sorry, I only forgot to change it while I was editing my post earlier. With that part there is no problem, but thank you!
$endgroup$
– yeosco
Mar 25 at 15:40




$begingroup$
@pacmaninbw oh sorry, I only forgot to change it while I was editing my post earlier. With that part there is no problem, but thank you!
$endgroup$
– yeosco
Mar 25 at 15:40




1




1




$begingroup$
Have you tried to use any heuristic? For example if you try solving for the number that occurs the most often first you will have a smaller problem set to solve.
$endgroup$
– pacmaninbw
Mar 25 at 15:42




$begingroup$
Have you tried to use any heuristic? For example if you try solving for the number that occurs the most often first you will have a smaller problem set to solve.
$endgroup$
– pacmaninbw
Mar 25 at 15:42










2 Answers
2






active

oldest

votes


















15












$begingroup$

The first thing that will help is to switch this from a recursive algorithm to an iterative one. This will prevent the stack overflow that prevents you from solving 25x25, and will be a bit faster to boot.



However to speed this up more, you will probably need to use a smarter algorithm. If you track what numbers are possible in each square, you will find that much of the time, there is only 1 possibility. In this case, you know what number goes there. You then can update all of the other squares in the same row, col, or box as the one you just filled in. To implement this efficiently, you would want to define a set (either a bitset or hashset) for what is available in each square, and use a heap to track which squares have the fewest remaining possibilities.






share|improve this answer









$endgroup$








  • 2




    $begingroup$
    Might I suggest Dancing links as an entry point for your search into a smarter algoriothm?
    $endgroup$
    – WorldSEnder
    Mar 25 at 19:42






  • 1




    $begingroup$
    The max recursion depth of this algorithm = number of squares, I think. 25*25 is only 625. The recursion doesn't create a copy of the board in each stack frame, so it probably only uses about 32 bytes per frame on x86-64. (Solve doesn't have any locals other than its args to save across a recursive call: an 8-byte pointer and 2x 4-byte int. That plus a return address, and maintaining 16-byte stack alignment as per the ABI, probably adds up to a 32-byte stack frame on x86-64 Linux or OS X. Or maybe 48 bytes with Windows x64 where the shadow space alone takes 32 bytes.)
    $endgroup$
    – Peter Cordes
    Mar 25 at 23:49







  • 2




    $begingroup$
    Anyway, that's only 25*25*48 = 30kB (not 30kiB) of stack memory max, which trivial (stack limits of 1MiB to 8MiB are common). Even a factor of 10 error in my reasoning isn't a problem. So it's not stack overflow, it's simply the O(SIZE^SIZE) exponential time complexity that stops SIZE=25 from running in usable time.
    $endgroup$
    – Peter Cordes
    Mar 25 at 23:54











  • $begingroup$
    Yeah, any idea why it wasn't returning for 25x25 before? Just speed?
    $endgroup$
    – Oscar Smith
    Mar 25 at 23:57










  • $begingroup$
    @OscarSmith: I'd assume just speed, yeah, that's compatible with the OP's wording. n^n grows very fast! Or maybe an unsolvable board? Anyway, Sudoku solutions finder using brute force and backtracking goes into detail on your suggestion to try cells with fewer possibilities first. There are several other Q&As in the "related" sidebar that look useful.
    $endgroup$
    – Peter Cordes
    Mar 26 at 0:00


















9












$begingroup$

The strategy needs work: brute-force search is going to scale very badly. As an order-of-magnitude estimate, observe that the code calls IsValid() around SIZE times for each cell - that's O(n³), where n is the SIZE.



Be more consistent with formatting. It's easier to read (and to search) code if there's a consistent convention. To take a simple example, we have:




int IsValid (int sudoku[SIZE][SIZE], int row, int col, int number)
int Solve(int sudoku[SIZE][SIZE], int row, int col)

if (Solve (sudoku,0,0))
if(IsValid(sudoku,row,col,number))



all with differing amounts of space around (. This kind of inconsistency gives an impression of code that's been written in a hurry, without consideration for the reader.



Instead of defining SIZE and deriving SQRT, it's simpler to start with SQRT and define SIZE to be (SQRT * SQRT). Then there's no need for <math.h> and no risk of floating-point approximation being unfortunately truncated when it's converted to integer.




The declaration/definition of main() should specify that it takes no arguments:



int main(void)


If we write int main(), that declares main as a function that takes an unspecified number of arguments (unlike C++, where () is equivalent to (void)).



You can see that C compilers treat void foo() differently from void foo(void) on the Godbolt compiler explorer.






share|improve this answer











$endgroup$








  • 2




    $begingroup$
    Very good suggestion to make SQRT a compile-time constant. The code uses stuff like prRow + i / SQRT and i % SQRT, which will compile to a runtime integer division (like x86 idiv) because int SQRT is a non-const global! And with a non-constant initializer, so I don't think this is even valid C. But fun fact: gcc does accept it as C (doing constant-propagation through sqrt even with optimization disabled). But clang rejects it. godbolt.org/z/4jrJmL. Anyway yes, we get nasty idiv unless we use const int sqrt (or better unsigned) godbolt.org/z/NMB156
    $endgroup$
    – Peter Cordes
    Mar 25 at 20:22











Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f216171%2fsimple-recursive-sudoku-solver%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









15












$begingroup$

The first thing that will help is to switch this from a recursive algorithm to an iterative one. This will prevent the stack overflow that prevents you from solving 25x25, and will be a bit faster to boot.



However to speed this up more, you will probably need to use a smarter algorithm. If you track what numbers are possible in each square, you will find that much of the time, there is only 1 possibility. In this case, you know what number goes there. You then can update all of the other squares in the same row, col, or box as the one you just filled in. To implement this efficiently, you would want to define a set (either a bitset or hashset) for what is available in each square, and use a heap to track which squares have the fewest remaining possibilities.






share|improve this answer









$endgroup$








  • 2




    $begingroup$
    Might I suggest Dancing links as an entry point for your search into a smarter algoriothm?
    $endgroup$
    – WorldSEnder
    Mar 25 at 19:42






  • 1




    $begingroup$
    The max recursion depth of this algorithm = number of squares, I think. 25*25 is only 625. The recursion doesn't create a copy of the board in each stack frame, so it probably only uses about 32 bytes per frame on x86-64. (Solve doesn't have any locals other than its args to save across a recursive call: an 8-byte pointer and 2x 4-byte int. That plus a return address, and maintaining 16-byte stack alignment as per the ABI, probably adds up to a 32-byte stack frame on x86-64 Linux or OS X. Or maybe 48 bytes with Windows x64 where the shadow space alone takes 32 bytes.)
    $endgroup$
    – Peter Cordes
    Mar 25 at 23:49







  • 2




    $begingroup$
    Anyway, that's only 25*25*48 = 30kB (not 30kiB) of stack memory max, which trivial (stack limits of 1MiB to 8MiB are common). Even a factor of 10 error in my reasoning isn't a problem. So it's not stack overflow, it's simply the O(SIZE^SIZE) exponential time complexity that stops SIZE=25 from running in usable time.
    $endgroup$
    – Peter Cordes
    Mar 25 at 23:54











  • $begingroup$
    Yeah, any idea why it wasn't returning for 25x25 before? Just speed?
    $endgroup$
    – Oscar Smith
    Mar 25 at 23:57










  • $begingroup$
    @OscarSmith: I'd assume just speed, yeah, that's compatible with the OP's wording. n^n grows very fast! Or maybe an unsolvable board? Anyway, Sudoku solutions finder using brute force and backtracking goes into detail on your suggestion to try cells with fewer possibilities first. There are several other Q&As in the "related" sidebar that look useful.
    $endgroup$
    – Peter Cordes
    Mar 26 at 0:00















15












$begingroup$

The first thing that will help is to switch this from a recursive algorithm to an iterative one. This will prevent the stack overflow that prevents you from solving 25x25, and will be a bit faster to boot.



However to speed this up more, you will probably need to use a smarter algorithm. If you track what numbers are possible in each square, you will find that much of the time, there is only 1 possibility. In this case, you know what number goes there. You then can update all of the other squares in the same row, col, or box as the one you just filled in. To implement this efficiently, you would want to define a set (either a bitset or hashset) for what is available in each square, and use a heap to track which squares have the fewest remaining possibilities.






share|improve this answer









$endgroup$








  • 2




    $begingroup$
    Might I suggest Dancing links as an entry point for your search into a smarter algoriothm?
    $endgroup$
    – WorldSEnder
    Mar 25 at 19:42






  • 1




    $begingroup$
    The max recursion depth of this algorithm = number of squares, I think. 25*25 is only 625. The recursion doesn't create a copy of the board in each stack frame, so it probably only uses about 32 bytes per frame on x86-64. (Solve doesn't have any locals other than its args to save across a recursive call: an 8-byte pointer and 2x 4-byte int. That plus a return address, and maintaining 16-byte stack alignment as per the ABI, probably adds up to a 32-byte stack frame on x86-64 Linux or OS X. Or maybe 48 bytes with Windows x64 where the shadow space alone takes 32 bytes.)
    $endgroup$
    – Peter Cordes
    Mar 25 at 23:49







  • 2




    $begingroup$
    Anyway, that's only 25*25*48 = 30kB (not 30kiB) of stack memory max, which trivial (stack limits of 1MiB to 8MiB are common). Even a factor of 10 error in my reasoning isn't a problem. So it's not stack overflow, it's simply the O(SIZE^SIZE) exponential time complexity that stops SIZE=25 from running in usable time.
    $endgroup$
    – Peter Cordes
    Mar 25 at 23:54











  • $begingroup$
    Yeah, any idea why it wasn't returning for 25x25 before? Just speed?
    $endgroup$
    – Oscar Smith
    Mar 25 at 23:57










  • $begingroup$
    @OscarSmith: I'd assume just speed, yeah, that's compatible with the OP's wording. n^n grows very fast! Or maybe an unsolvable board? Anyway, Sudoku solutions finder using brute force and backtracking goes into detail on your suggestion to try cells with fewer possibilities first. There are several other Q&As in the "related" sidebar that look useful.
    $endgroup$
    – Peter Cordes
    Mar 26 at 0:00













15












15








15





$begingroup$

The first thing that will help is to switch this from a recursive algorithm to an iterative one. This will prevent the stack overflow that prevents you from solving 25x25, and will be a bit faster to boot.



However to speed this up more, you will probably need to use a smarter algorithm. If you track what numbers are possible in each square, you will find that much of the time, there is only 1 possibility. In this case, you know what number goes there. You then can update all of the other squares in the same row, col, or box as the one you just filled in. To implement this efficiently, you would want to define a set (either a bitset or hashset) for what is available in each square, and use a heap to track which squares have the fewest remaining possibilities.






share|improve this answer









$endgroup$



The first thing that will help is to switch this from a recursive algorithm to an iterative one. This will prevent the stack overflow that prevents you from solving 25x25, and will be a bit faster to boot.



However to speed this up more, you will probably need to use a smarter algorithm. If you track what numbers are possible in each square, you will find that much of the time, there is only 1 possibility. In this case, you know what number goes there. You then can update all of the other squares in the same row, col, or box as the one you just filled in. To implement this efficiently, you would want to define a set (either a bitset or hashset) for what is available in each square, and use a heap to track which squares have the fewest remaining possibilities.







share|improve this answer












share|improve this answer



share|improve this answer










answered Mar 25 at 15:56









Oscar SmithOscar Smith

2,9611123




2,9611123







  • 2




    $begingroup$
    Might I suggest Dancing links as an entry point for your search into a smarter algoriothm?
    $endgroup$
    – WorldSEnder
    Mar 25 at 19:42






  • 1




    $begingroup$
    The max recursion depth of this algorithm = number of squares, I think. 25*25 is only 625. The recursion doesn't create a copy of the board in each stack frame, so it probably only uses about 32 bytes per frame on x86-64. (Solve doesn't have any locals other than its args to save across a recursive call: an 8-byte pointer and 2x 4-byte int. That plus a return address, and maintaining 16-byte stack alignment as per the ABI, probably adds up to a 32-byte stack frame on x86-64 Linux or OS X. Or maybe 48 bytes with Windows x64 where the shadow space alone takes 32 bytes.)
    $endgroup$
    – Peter Cordes
    Mar 25 at 23:49







  • 2




    $begingroup$
    Anyway, that's only 25*25*48 = 30kB (not 30kiB) of stack memory max, which trivial (stack limits of 1MiB to 8MiB are common). Even a factor of 10 error in my reasoning isn't a problem. So it's not stack overflow, it's simply the O(SIZE^SIZE) exponential time complexity that stops SIZE=25 from running in usable time.
    $endgroup$
    – Peter Cordes
    Mar 25 at 23:54











  • $begingroup$
    Yeah, any idea why it wasn't returning for 25x25 before? Just speed?
    $endgroup$
    – Oscar Smith
    Mar 25 at 23:57










  • $begingroup$
    @OscarSmith: I'd assume just speed, yeah, that's compatible with the OP's wording. n^n grows very fast! Or maybe an unsolvable board? Anyway, Sudoku solutions finder using brute force and backtracking goes into detail on your suggestion to try cells with fewer possibilities first. There are several other Q&As in the "related" sidebar that look useful.
    $endgroup$
    – Peter Cordes
    Mar 26 at 0:00












  • 2




    $begingroup$
    Might I suggest Dancing links as an entry point for your search into a smarter algoriothm?
    $endgroup$
    – WorldSEnder
    Mar 25 at 19:42






  • 1




    $begingroup$
    The max recursion depth of this algorithm = number of squares, I think. 25*25 is only 625. The recursion doesn't create a copy of the board in each stack frame, so it probably only uses about 32 bytes per frame on x86-64. (Solve doesn't have any locals other than its args to save across a recursive call: an 8-byte pointer and 2x 4-byte int. That plus a return address, and maintaining 16-byte stack alignment as per the ABI, probably adds up to a 32-byte stack frame on x86-64 Linux or OS X. Or maybe 48 bytes with Windows x64 where the shadow space alone takes 32 bytes.)
    $endgroup$
    – Peter Cordes
    Mar 25 at 23:49







  • 2




    $begingroup$
    Anyway, that's only 25*25*48 = 30kB (not 30kiB) of stack memory max, which trivial (stack limits of 1MiB to 8MiB are common). Even a factor of 10 error in my reasoning isn't a problem. So it's not stack overflow, it's simply the O(SIZE^SIZE) exponential time complexity that stops SIZE=25 from running in usable time.
    $endgroup$
    – Peter Cordes
    Mar 25 at 23:54











  • $begingroup$
    Yeah, any idea why it wasn't returning for 25x25 before? Just speed?
    $endgroup$
    – Oscar Smith
    Mar 25 at 23:57










  • $begingroup$
    @OscarSmith: I'd assume just speed, yeah, that's compatible with the OP's wording. n^n grows very fast! Or maybe an unsolvable board? Anyway, Sudoku solutions finder using brute force and backtracking goes into detail on your suggestion to try cells with fewer possibilities first. There are several other Q&As in the "related" sidebar that look useful.
    $endgroup$
    – Peter Cordes
    Mar 26 at 0:00







2




2




$begingroup$
Might I suggest Dancing links as an entry point for your search into a smarter algoriothm?
$endgroup$
– WorldSEnder
Mar 25 at 19:42




$begingroup$
Might I suggest Dancing links as an entry point for your search into a smarter algoriothm?
$endgroup$
– WorldSEnder
Mar 25 at 19:42




1




1




$begingroup$
The max recursion depth of this algorithm = number of squares, I think. 25*25 is only 625. The recursion doesn't create a copy of the board in each stack frame, so it probably only uses about 32 bytes per frame on x86-64. (Solve doesn't have any locals other than its args to save across a recursive call: an 8-byte pointer and 2x 4-byte int. That plus a return address, and maintaining 16-byte stack alignment as per the ABI, probably adds up to a 32-byte stack frame on x86-64 Linux or OS X. Or maybe 48 bytes with Windows x64 where the shadow space alone takes 32 bytes.)
$endgroup$
– Peter Cordes
Mar 25 at 23:49





$begingroup$
The max recursion depth of this algorithm = number of squares, I think. 25*25 is only 625. The recursion doesn't create a copy of the board in each stack frame, so it probably only uses about 32 bytes per frame on x86-64. (Solve doesn't have any locals other than its args to save across a recursive call: an 8-byte pointer and 2x 4-byte int. That plus a return address, and maintaining 16-byte stack alignment as per the ABI, probably adds up to a 32-byte stack frame on x86-64 Linux or OS X. Or maybe 48 bytes with Windows x64 where the shadow space alone takes 32 bytes.)
$endgroup$
– Peter Cordes
Mar 25 at 23:49





2




2




$begingroup$
Anyway, that's only 25*25*48 = 30kB (not 30kiB) of stack memory max, which trivial (stack limits of 1MiB to 8MiB are common). Even a factor of 10 error in my reasoning isn't a problem. So it's not stack overflow, it's simply the O(SIZE^SIZE) exponential time complexity that stops SIZE=25 from running in usable time.
$endgroup$
– Peter Cordes
Mar 25 at 23:54





$begingroup$
Anyway, that's only 25*25*48 = 30kB (not 30kiB) of stack memory max, which trivial (stack limits of 1MiB to 8MiB are common). Even a factor of 10 error in my reasoning isn't a problem. So it's not stack overflow, it's simply the O(SIZE^SIZE) exponential time complexity that stops SIZE=25 from running in usable time.
$endgroup$
– Peter Cordes
Mar 25 at 23:54













$begingroup$
Yeah, any idea why it wasn't returning for 25x25 before? Just speed?
$endgroup$
– Oscar Smith
Mar 25 at 23:57




$begingroup$
Yeah, any idea why it wasn't returning for 25x25 before? Just speed?
$endgroup$
– Oscar Smith
Mar 25 at 23:57












$begingroup$
@OscarSmith: I'd assume just speed, yeah, that's compatible with the OP's wording. n^n grows very fast! Or maybe an unsolvable board? Anyway, Sudoku solutions finder using brute force and backtracking goes into detail on your suggestion to try cells with fewer possibilities first. There are several other Q&As in the "related" sidebar that look useful.
$endgroup$
– Peter Cordes
Mar 26 at 0:00




$begingroup$
@OscarSmith: I'd assume just speed, yeah, that's compatible with the OP's wording. n^n grows very fast! Or maybe an unsolvable board? Anyway, Sudoku solutions finder using brute force and backtracking goes into detail on your suggestion to try cells with fewer possibilities first. There are several other Q&As in the "related" sidebar that look useful.
$endgroup$
– Peter Cordes
Mar 26 at 0:00













9












$begingroup$

The strategy needs work: brute-force search is going to scale very badly. As an order-of-magnitude estimate, observe that the code calls IsValid() around SIZE times for each cell - that's O(n³), where n is the SIZE.



Be more consistent with formatting. It's easier to read (and to search) code if there's a consistent convention. To take a simple example, we have:




int IsValid (int sudoku[SIZE][SIZE], int row, int col, int number)
int Solve(int sudoku[SIZE][SIZE], int row, int col)

if (Solve (sudoku,0,0))
if(IsValid(sudoku,row,col,number))



all with differing amounts of space around (. This kind of inconsistency gives an impression of code that's been written in a hurry, without consideration for the reader.



Instead of defining SIZE and deriving SQRT, it's simpler to start with SQRT and define SIZE to be (SQRT * SQRT). Then there's no need for <math.h> and no risk of floating-point approximation being unfortunately truncated when it's converted to integer.




The declaration/definition of main() should specify that it takes no arguments:



int main(void)


If we write int main(), that declares main as a function that takes an unspecified number of arguments (unlike C++, where () is equivalent to (void)).



You can see that C compilers treat void foo() differently from void foo(void) on the Godbolt compiler explorer.






share|improve this answer











$endgroup$








  • 2




    $begingroup$
    Very good suggestion to make SQRT a compile-time constant. The code uses stuff like prRow + i / SQRT and i % SQRT, which will compile to a runtime integer division (like x86 idiv) because int SQRT is a non-const global! And with a non-constant initializer, so I don't think this is even valid C. But fun fact: gcc does accept it as C (doing constant-propagation through sqrt even with optimization disabled). But clang rejects it. godbolt.org/z/4jrJmL. Anyway yes, we get nasty idiv unless we use const int sqrt (or better unsigned) godbolt.org/z/NMB156
    $endgroup$
    – Peter Cordes
    Mar 25 at 20:22















9












$begingroup$

The strategy needs work: brute-force search is going to scale very badly. As an order-of-magnitude estimate, observe that the code calls IsValid() around SIZE times for each cell - that's O(n³), where n is the SIZE.



Be more consistent with formatting. It's easier to read (and to search) code if there's a consistent convention. To take a simple example, we have:




int IsValid (int sudoku[SIZE][SIZE], int row, int col, int number)
int Solve(int sudoku[SIZE][SIZE], int row, int col)

if (Solve (sudoku,0,0))
if(IsValid(sudoku,row,col,number))



all with differing amounts of space around (. This kind of inconsistency gives an impression of code that's been written in a hurry, without consideration for the reader.



Instead of defining SIZE and deriving SQRT, it's simpler to start with SQRT and define SIZE to be (SQRT * SQRT). Then there's no need for <math.h> and no risk of floating-point approximation being unfortunately truncated when it's converted to integer.




The declaration/definition of main() should specify that it takes no arguments:



int main(void)


If we write int main(), that declares main as a function that takes an unspecified number of arguments (unlike C++, where () is equivalent to (void)).



You can see that C compilers treat void foo() differently from void foo(void) on the Godbolt compiler explorer.






share|improve this answer











$endgroup$








  • 2




    $begingroup$
    Very good suggestion to make SQRT a compile-time constant. The code uses stuff like prRow + i / SQRT and i % SQRT, which will compile to a runtime integer division (like x86 idiv) because int SQRT is a non-const global! And with a non-constant initializer, so I don't think this is even valid C. But fun fact: gcc does accept it as C (doing constant-propagation through sqrt even with optimization disabled). But clang rejects it. godbolt.org/z/4jrJmL. Anyway yes, we get nasty idiv unless we use const int sqrt (or better unsigned) godbolt.org/z/NMB156
    $endgroup$
    – Peter Cordes
    Mar 25 at 20:22













9












9








9





$begingroup$

The strategy needs work: brute-force search is going to scale very badly. As an order-of-magnitude estimate, observe that the code calls IsValid() around SIZE times for each cell - that's O(n³), where n is the SIZE.



Be more consistent with formatting. It's easier to read (and to search) code if there's a consistent convention. To take a simple example, we have:




int IsValid (int sudoku[SIZE][SIZE], int row, int col, int number)
int Solve(int sudoku[SIZE][SIZE], int row, int col)

if (Solve (sudoku,0,0))
if(IsValid(sudoku,row,col,number))



all with differing amounts of space around (. This kind of inconsistency gives an impression of code that's been written in a hurry, without consideration for the reader.



Instead of defining SIZE and deriving SQRT, it's simpler to start with SQRT and define SIZE to be (SQRT * SQRT). Then there's no need for <math.h> and no risk of floating-point approximation being unfortunately truncated when it's converted to integer.




The declaration/definition of main() should specify that it takes no arguments:



int main(void)


If we write int main(), that declares main as a function that takes an unspecified number of arguments (unlike C++, where () is equivalent to (void)).



You can see that C compilers treat void foo() differently from void foo(void) on the Godbolt compiler explorer.






share|improve this answer











$endgroup$



The strategy needs work: brute-force search is going to scale very badly. As an order-of-magnitude estimate, observe that the code calls IsValid() around SIZE times for each cell - that's O(n³), where n is the SIZE.



Be more consistent with formatting. It's easier to read (and to search) code if there's a consistent convention. To take a simple example, we have:




int IsValid (int sudoku[SIZE][SIZE], int row, int col, int number)
int Solve(int sudoku[SIZE][SIZE], int row, int col)

if (Solve (sudoku,0,0))
if(IsValid(sudoku,row,col,number))



all with differing amounts of space around (. This kind of inconsistency gives an impression of code that's been written in a hurry, without consideration for the reader.



Instead of defining SIZE and deriving SQRT, it's simpler to start with SQRT and define SIZE to be (SQRT * SQRT). Then there's no need for <math.h> and no risk of floating-point approximation being unfortunately truncated when it's converted to integer.




The declaration/definition of main() should specify that it takes no arguments:



int main(void)


If we write int main(), that declares main as a function that takes an unspecified number of arguments (unlike C++, where () is equivalent to (void)).



You can see that C compilers treat void foo() differently from void foo(void) on the Godbolt compiler explorer.







share|improve this answer














share|improve this answer



share|improve this answer








edited Mar 26 at 9:43

























answered Mar 25 at 16:00









Toby SpeightToby Speight

27.8k742120




27.8k742120







  • 2




    $begingroup$
    Very good suggestion to make SQRT a compile-time constant. The code uses stuff like prRow + i / SQRT and i % SQRT, which will compile to a runtime integer division (like x86 idiv) because int SQRT is a non-const global! And with a non-constant initializer, so I don't think this is even valid C. But fun fact: gcc does accept it as C (doing constant-propagation through sqrt even with optimization disabled). But clang rejects it. godbolt.org/z/4jrJmL. Anyway yes, we get nasty idiv unless we use const int sqrt (or better unsigned) godbolt.org/z/NMB156
    $endgroup$
    – Peter Cordes
    Mar 25 at 20:22












  • 2




    $begingroup$
    Very good suggestion to make SQRT a compile-time constant. The code uses stuff like prRow + i / SQRT and i % SQRT, which will compile to a runtime integer division (like x86 idiv) because int SQRT is a non-const global! And with a non-constant initializer, so I don't think this is even valid C. But fun fact: gcc does accept it as C (doing constant-propagation through sqrt even with optimization disabled). But clang rejects it. godbolt.org/z/4jrJmL. Anyway yes, we get nasty idiv unless we use const int sqrt (or better unsigned) godbolt.org/z/NMB156
    $endgroup$
    – Peter Cordes
    Mar 25 at 20:22







2




2




$begingroup$
Very good suggestion to make SQRT a compile-time constant. The code uses stuff like prRow + i / SQRT and i % SQRT, which will compile to a runtime integer division (like x86 idiv) because int SQRT is a non-const global! And with a non-constant initializer, so I don't think this is even valid C. But fun fact: gcc does accept it as C (doing constant-propagation through sqrt even with optimization disabled). But clang rejects it. godbolt.org/z/4jrJmL. Anyway yes, we get nasty idiv unless we use const int sqrt (or better unsigned) godbolt.org/z/NMB156
$endgroup$
– Peter Cordes
Mar 25 at 20:22




$begingroup$
Very good suggestion to make SQRT a compile-time constant. The code uses stuff like prRow + i / SQRT and i % SQRT, which will compile to a runtime integer division (like x86 idiv) because int SQRT is a non-const global! And with a non-constant initializer, so I don't think this is even valid C. But fun fact: gcc does accept it as C (doing constant-propagation through sqrt even with optimization disabled). But clang rejects it. godbolt.org/z/4jrJmL. Anyway yes, we get nasty idiv unless we use const int sqrt (or better unsigned) godbolt.org/z/NMB156
$endgroup$
– Peter Cordes
Mar 25 at 20:22

















draft saved

draft discarded
















































Thanks for contributing an answer to Code Review Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

Use MathJax to format equations. MathJax reference.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f216171%2fsimple-recursive-sudoku-solver%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Færeyskur hestur Heimild | Tengill | Tilvísanir | LeiðsagnarvalRossið - síða um færeyska hrossið á færeyskuGott ár hjá færeyska hestinum

He _____ here since 1970 . Answer needed [closed]What does “since he was so high” mean?Meaning of “catch birds for”?How do I ensure “since” takes the meaning I want?“Who cares here” meaningWhat does “right round toward” mean?the time tense (had now been detected)What does the phrase “ring around the roses” mean here?Correct usage of “visited upon”Meaning of “foiled rail sabotage bid”It was the third time I had gone to Rome or It is the third time I had been to Rome

Slayer Innehåll Historia | Stil, komposition och lyrik | Bandets betydelse och framgångar | Sidoprojekt och samarbeten | Kontroverser | Medlemmar | Utmärkelser och nomineringar | Turnéer och festivaler | Diskografi | Referenser | Externa länkar | Navigeringsmenywww.slayer.net”Metal Massacre vol. 1””Metal Massacre vol. 3””Metal Massacre Volume III””Show No Mercy””Haunting the Chapel””Live Undead””Hell Awaits””Reign in Blood””Reign in Blood””Gold & Platinum – Reign in Blood””Golden Gods Awards Winners”originalet”Kerrang! Hall Of Fame””Slayer Looks Back On 37-Year Career In New Video Series: Part Two””South of Heaven””Gold & Platinum – South of Heaven””Seasons in the Abyss””Gold & Platinum - Seasons in the Abyss””Divine Intervention””Divine Intervention - Release group by Slayer””Gold & Platinum - Divine Intervention””Live Intrusion””Undisputed Attitude””Abolish Government/Superficial Love””Release “Slatanic Slaughter: A Tribute to Slayer” by Various Artists””Diabolus in Musica””Soundtrack to the Apocalypse””God Hates Us All””Systematic - Relationships””War at the Warfield””Gold & Platinum - War at the Warfield””Soundtrack to the Apocalypse””Gold & Platinum - Still Reigning””Metallica, Slayer, Iron Mauden Among Winners At Metal Hammer Awards””Eternal Pyre””Eternal Pyre - Slayer release group””Eternal Pyre””Metal Storm Awards 2006””Kerrang! Hall Of Fame””Slayer Wins 'Best Metal' Grammy Award””Slayer Guitarist Jeff Hanneman Dies””Bullet-For My Valentine booed at Metal Hammer Golden Gods Awards””Unholy Aliance””The End Of Slayer?””Slayer: We Could Thrash Out Two More Albums If We're Fast Enough...””'The Unholy Alliance: Chapter III' UK Dates Added”originalet”Megadeth And Slayer To Co-Headline 'Canadian Carnage' Trek”originalet”World Painted Blood””Release “World Painted Blood” by Slayer””Metallica Heading To Cinemas””Slayer, Megadeth To Join Forces For 'European Carnage' Tour - Dec. 18, 2010”originalet”Slayer's Hanneman Contracts Acute Infection; Band To Bring In Guest Guitarist””Cannibal Corpse's Pat O'Brien Will Step In As Slayer's Guest Guitarist”originalet”Slayer’s Jeff Hanneman Dead at 49””Dave Lombardo Says He Made Only $67,000 In 2011 While Touring With Slayer””Slayer: We Do Not Agree With Dave Lombardo's Substance Or Timeline Of Events””Slayer Welcomes Drummer Paul Bostaph Back To The Fold””Slayer Hope to Unveil Never-Before-Heard Jeff Hanneman Material on Next Album””Slayer Debut New Song 'Implode' During Surprise Golden Gods Appearance””Release group Repentless by Slayer””Repentless - Slayer - Credits””Slayer””Metal Storm Awards 2015””Slayer - to release comic book "Repentless #1"””Slayer To Release 'Repentless' 6.66" Vinyl Box Set””BREAKING NEWS: Slayer Announce Farewell Tour””Slayer Recruit Lamb of God, Anthrax, Behemoth + Testament for Final Tour””Slayer lägger ner efter 37 år””Slayer Announces Second North American Leg Of 'Final' Tour””Final World Tour””Slayer Announces Final European Tour With Lamb of God, Anthrax And Obituary””Slayer To Tour Europe With Lamb of God, Anthrax And Obituary””Slayer To Play 'Last French Show Ever' At Next Year's Hellfst””Slayer's Final World Tour Will Extend Into 2019””Death Angel's Rob Cavestany On Slayer's 'Farewell' Tour: 'Some Of Us Could See This Coming'””Testament Has No Plans To Retire Anytime Soon, Says Chuck Billy””Anthrax's Scott Ian On Slayer's 'Farewell' Tour Plans: 'I Was Surprised And I Wasn't Surprised'””Slayer””Slayer's Morbid Schlock””Review/Rock; For Slayer, the Mania Is the Message””Slayer - Biography””Slayer - Reign In Blood”originalet”Dave Lombardo””An exclusive oral history of Slayer”originalet”Exclusive! Interview With Slayer Guitarist Jeff Hanneman”originalet”Thinking Out Loud: Slayer's Kerry King on hair metal, Satan and being polite””Slayer Lyrics””Slayer - Biography””Most influential artists for extreme metal music””Slayer - Reign in Blood””Slayer guitarist Jeff Hanneman dies aged 49””Slatanic Slaughter: A Tribute to Slayer””Gateway to Hell: A Tribute to Slayer””Covered In Blood””Slayer: The Origins of Thrash in San Francisco, CA.””Why They Rule - #6 Slayer”originalet”Guitar World's 100 Greatest Heavy Metal Guitarists Of All Time”originalet”The fans have spoken: Slayer comes out on top in readers' polls”originalet”Tribute to Jeff Hanneman (1964-2013)””Lamb Of God Frontman: We Sound Like A Slayer Rip-Off””BEHEMOTH Frontman Pays Tribute To SLAYER's JEFF HANNEMAN””Slayer, Hatebreed Doing Double Duty On This Year's Ozzfest””System of a Down””Lacuna Coil’s Andrea Ferro Talks Influences, Skateboarding, Band Origins + More””Slayer - Reign in Blood””Into The Lungs of Hell””Slayer rules - en utställning om fans””Slayer and Their Fans Slashed Through a No-Holds-Barred Night at Gas Monkey””Home””Slayer””Gold & Platinum - The Big 4 Live from Sofia, Bulgaria””Exclusive! Interview With Slayer Guitarist Kerry King””2008-02-23: Wiltern, Los Angeles, CA, USA””Slayer's Kerry King To Perform With Megadeth Tonight! - Oct. 21, 2010”originalet”Dave Lombardo - Biography”Slayer Case DismissedArkiveradUltimate Classic Rock: Slayer guitarist Jeff Hanneman dead at 49.”Slayer: "We could never do any thing like Some Kind Of Monster..."””Cannibal Corpse'S Pat O'Brien Will Step In As Slayer'S Guest Guitarist | The Official Slayer Site”originalet”Slayer Wins 'Best Metal' Grammy Award””Slayer Guitarist Jeff Hanneman Dies””Kerrang! Awards 2006 Blog: Kerrang! Hall Of Fame””Kerrang! Awards 2013: Kerrang! Legend”originalet”Metallica, Slayer, Iron Maien Among Winners At Metal Hammer Awards””Metal Hammer Golden Gods Awards””Bullet For My Valentine Booed At Metal Hammer Golden Gods Awards””Metal Storm Awards 2006””Metal Storm Awards 2015””Slayer's Concert History””Slayer - Relationships””Slayer - Releases”Slayers officiella webbplatsSlayer på MusicBrainzOfficiell webbplatsSlayerSlayerr1373445760000 0001 1540 47353068615-5086262726cb13906545x(data)6033143kn20030215029