d2jsp
Log InRegister
d2jsp Forums > Off-Topic > Computers & IT > Programming & Development > 1000 Fg For Whoever Can Fix My Code
Prev123Next
Add Reply New Topic New Poll
Member
Posts: 1,995
Joined: Jun 28 2006
Gold: 7.41
Mar 17 2014 11:14pm
Quote (Azrad @ Mar 17 2014 11:25pm)
actually this will (properly implemented) solve a sudoku in a few seconds, even with a slow language like python (in my experience).


I thought he was given a sudoku board and asked to solve it. I wasn't aware he was just generating a board. You are correct, generating a board is simple. Solving a partially completed board is not.
Member
Posts: 10,812
Joined: Oct 15 2009
Gold: Locked
Warn: 20%
Mar 17 2014 11:29pm
Quote (Minkomonster @ Mar 17 2014 10:14pm)
I thought he was given a sudoku board and asked to solve it. I wasn't aware he was just generating a board. You are correct, generating a board is simple. Solving a partially completed board is not.


oh i thought the same thing at first. but solving one is rather simple with brute force in my experience
Member
Posts: 1,995
Joined: Jun 28 2006
Gold: 7.41
Mar 17 2014 11:33pm
Quote (Azrad @ Mar 18 2014 12:29am)
oh i thought the same thing at first. but solving one is rather simple with brute force in my experience


According to his assignment specs, it only needs to check row and col. It doesn't even need to check blocks.

And based on when he last edited his post and when I submitted mine, I missed him by 5 minutes. poop.
Member
Posts: 2,769
Joined: Dec 24 2009
Gold: 14.00
Mar 18 2014 09:50am
Quote (Minkomonster @ Mar 18 2014 12:06am)
If it is just row or column here you go:

Code
#include<cstdlib>
#include <stdio.h>
#include <time.h>
bool unassigned(int** grid, int n, int& r, int& c)
{
    for(r = 0; r < n; r++)
        for(c = 0; c < n; c++)
            if(grid[r][c] == 0)
              return true;
    return false;
}

bool conflicts(int** grid,int n, int r, int c, int x)
{
    for(int i = 0; i < n; i++)
        if(grid[r][i] == x || grid[i][c] == x) return true;
    return false;
}
bool solve(int** grid, int n)
{
    int r, c;
    if(!unassigned(grid,n,r,c))
        return true;
   
    for(int i = 1; i <= n; i++)
    {
        if(!conflicts(grid,n,r,c,i))
        {
          grid[r][c] = i;
          if(solve(grid,n))
          {
              return true;
          }
          grid[r][c] = 0;
        }
    }
    return false;
}

int main()
{
    srand (time(NULL));
    int n = 9;
   
    int r = rand()%n;
    int c = rand()%n;
    int x = 1+rand()%n;
   
    int* grid[n];
      for(int i = 0; i < n; i++)
      {
        grid[i] = new int[n];
        for(int j = 0; j < n; j++)
            grid[i][j] = 0;
         
    }
 
    grid[r][c] = x;
     
    solve(grid,n);
   
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < n; j++)
          printf("%d",grid[i][j]);
        printf("\n");
    }
    scanf("%d");
   
   
   
}


1000fg?


Edit: Any questions, feel free to ask.


Quote (Foxic @ Mar 17 2014 11:26pm)
That's not what the problem is.  When a cell runs out of values to put in (i.e they're all restricted) it just goes onto the next cell


The program has to generate an N size (specified by user) grid filled with numbers, where there are no repeats in any row/column.  Have to use backtracking, or recursion, or both, and result has to be random (different result each time you run the prog)


I don't see backtracking or recursion, but I'm pretty bad at reading code. Either one, or both is required

This post was edited by Foxic on Mar 18 2014 09:52am
Member
Posts: 1,995
Joined: Jun 28 2006
Gold: 7.41
Mar 18 2014 10:14am
The solve function is a recursive backtracking algorithm. It first searches for an unassigned cell if there is one. It then cycles through all possible values and checks if it can recursively solve the grid with that value with no conflicts. If it can't it backtracks and repeats. The program does exactly what you asked.


I'd also like to point out that 'recursive backtracking" is redundant. Backtracking implies recursion as it is a depth first search.

This post was edited by Minkomonster on Mar 18 2014 10:19am
Member
Posts: 2,769
Joined: Dec 24 2009
Gold: 14.00
Mar 18 2014 03:14pm
One more problem, the first row and column are always the same. Need them to be random

Edit: A pattern keeps appearing, first row/column are incremental and the diagonal is all the same number, I got this result 10 times in a row. This has to be a completely random variation

This post was edited by Foxic on Mar 18 2014 03:38pm
Member
Posts: 1,995
Joined: Jun 28 2006
Gold: 7.41
Mar 18 2014 04:04pm
Quote (Foxic @ Mar 18 2014 04:14pm)
One more problem, the first row and column are always the same. Need them to be random

Edit: A pattern keeps appearing, first row/column are incremental and the diagonal is all the same number, I got this result 10 times in a row.  This has to be a completely random variation


You did not state this. You said the entire grid had to be random. So, i chose a random cell and populated it with a random value to initialize the grid. I then solved the grid using this initial value. This generates a random grid. However, it may appear to be the same due to the fact that I am only initializing 1 square out of 81 (9x9). If you were to set n to be 3, the variance would change and you would see the randomness easiar. Would you like me to randomize the entire first row and then solve based on that?

Code

#include <stdio.h>
#include <time.h>
#include <conio.h>
#include <iostream>


bool randomize(int* row, int n)
{
for(int i = 0; i < n; i++) row[i] = i+1;
std::random_shuffle(&row[0],&row[n]);

}
bool unassigned(int** grid, int n, int& r, int& c)
{
for(r = 0; r < n; r++)
for(c = 0; c < n; c++)
if(grid[r][c] == 0)
return true;
return false;
}

bool conflicts(int** grid,int n, int r, int c, int x)
{
for(int i = 0; i < n; i++)
if(grid[r][i] == x || grid[i][c] == x) return true;
return false;
}
bool solve(int** grid, int n)
{
int r, c;

//if there are no unassigned cells then the
//grid has been completely solved
if(!unassigned(grid,n,r,c))
return true;

//otherwise, choose a value for the unassigned cell
for(int i = 1; i <= n; i++)
{
//ensure there are no conflicts with this value
if(!conflicts(grid,n,r,c,i))
{
//assign the value to this cell
grid[r][c] = i;

//attempt to recursively solve every remaining unassigned cell
if(solve(grid,n))
{
//if the board is completely solved we return true
return true;
}

//otherwise this value was not correct. reset and continue
grid[r][c] = 0;
}
}

//we have exhausted all possibilities for this cell and did not
//obtain a solved board, so backtrack and try again
return false;
}

int main()
{
srand (time(NULL));

int n = 9;



int* grid[n];
for(int i = 0; i < n; i++)
{
grid[i] = new int[n];
for(int j = 0; j < n; j++)
grid[i][j] = 0;

}

//randomize a random row to initialize the grid
int r = rand()%n;
randomize(grid[r],n);


//solve the board using backtracking
solve(grid,n);

for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
printf("%d",grid[i][j]);
printf("\n");
}
scanf("%d");





}



Here, I randomized a random row. I also added line comments to show you what the algorithm does. and to highlight the recursion and the backtracking.

This post was edited by Minkomonster on Mar 18 2014 04:20pm
Member
Posts: 1,995
Joined: Jun 28 2006
Gold: 7.41
Mar 18 2014 04:41pm
here now it fully randomizes from a list of candidates.

Code
#include <stdio.h>
#include <time.h>
#include <conio.h>
#include <iostream>


bool randomize(int* row, int n)
{
for(int i = 0; i < n; i++) row[i] = i+1;
std::random_shuffle(&row[0],&row[n]);

}
bool unassigned(int** grid, int n, int& r, int& c)
{
for(r = 0; r < n; r++)
for(c = 0; c < n; c++)
if(grid[r][c] == 0)
return true;
return false;
}

bool conflicts(int** grid,int n, int r, int c, int x)
{
for(int i = 0; i < n; i++)
if(grid[r][i] == x || grid[i][c] == x) return true;
return false;
}
bool solve(int** grid, int n)
{
int r, c;

//if there are no unassigned cells then the
//grid has been completely solved
if(!unassigned(grid,n,r,c))
return true;

//generate a list of candidates for this cell, and randomize it
int cand[n];
randomize(cand,n);
int ncand = n;

//otherwise, choose a random value for this cell and attempt to solve
for(int i = cand[0]; ncand > 0; ncand--)
{

//ensure there are no conflicts with this value
if(!conflicts(grid,n,r,c,i))
{
//assign the value to this cell
grid[r][c] = i;

//attempt to recursively solve every remaining unassigned cell
if(solve(grid,n))
{
//if the board is completely solved we return true
return true;
}

//otherwise this value was not correct. reset and continue
grid[r][c] = 0;

//remove candidate
cand[0] = cand[ncand-1];
}
}

//we have exhausted all possibilities for this cell and did not
//obtain a solved board, so backtrack and try again
return false;
}

int main()
{
srand (time(NULL));

int n = 9;



int* grid[n];
for(int i = 0; i < n; i++)
{
grid[i] = new int[n];
for(int j = 0; j < n; j++)
grid[i][j] = 0;

}


//solve the board using backtracking
solve(grid,n);

for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
printf("%d",grid[i][j]);
printf("\n");
}
scanf("%d");





}


This post was edited by Minkomonster on Mar 18 2014 04:45pm
Member
Posts: 1,995
Joined: Jun 28 2006
Gold: 7.41
Mar 18 2014 08:15pm
Anyone that sees this do me a favor, OP PM'd me and said he tried running the above code and it bombed out. Can anyone try to compile/run and see if you can replicate this? Because I cannot. He says he copied it exactly.
Member
Posts: 2,769
Joined: Dec 24 2009
Gold: 14.00
Mar 18 2014 08:30pm
Thanks for trying, even though I couldn't use your program I hope I gave you enough :/

Really sorry, not much time before deadline

This post was edited by Foxic on Mar 18 2014 08:30pm
Go Back To Programming & Development Topic List
Prev123Next
Add Reply New Topic New Poll