How do I hide numbers from a table of sudoku? - c++

I'm trying to write a program that will give the user a sudoku puzzle to solve. But I'm stuck on hiding numbers by difficulty level. How do I do that?

Considering you have a 9x9 matrix of integers
int sudoku[9][9];
and this matrix is filled with a correct Sudoku, just replace some entries by 0 for example. Remember that Sudoku are often symmetric around their centre.
// Hide (i,j) from solution
sudoku[i][j] = 0;
sudoku[8-i][8-j] = 0;
Each time you hide two numbers from the solution, check back with your solver that it can still be solved. Finally, associate difficulty with a certain amount of loops of such a process
for (k=0; k < difficulty; ) {
// randomly select (i,j) so that:
// - 0 <= i <= 4
// - 0 <= j <= 4
// - (i,j) != (4, 4)
// - solution[i][j] != 0 (i.e., (i, j) has not already been randomly selected
save1 = solution[i][j];
solution[i][j] = 0;
save2 = solution[8-i][8-j];
solution[8-i][8-j] = 0;
if (!can_be_solved(solution)) {
// (i, j) was not a good choice!
solution[i][j] = save1;
solution[8-i][8-j] = save2;
}
else {
// it's still OK, let's go one step further
k += 1;
}
}
//
}

You could write a sudoku solver and then just randomly generate sudoku boards and test if they are valid with your sudoku solver. In your method that generates the boards, you could have an input that specifies the number of numbers that will be shown on the beginning board. Take a look at the standard number of numbers for different difficulties and base it off of that.

Related

Implementing a crossover function for multiple "Salesmen" TSP in a genetic algorithm

I’m trying to solve a variant of the TSP problem with “multiple salesmen". I have a series of n waypoints and m drones and I want to generate a result which sorts of balances the number of waypoints between drones and returns an acceptable shortest travelling time. At the moment, I'm not really too worried about finding an optimal solution, I just want something that works at this point. I've sort of distilled my problem to a traditional TSP run multiple times. My example is for a series of waypoints:
[0,1,2,3,4,5,6,7,8,9,10,11]
where 0 == 11 is the start and end point. Say I have 4 drones, I want to generate something like:
Drone A = [0,1,2,3,11]
Drone B = [0,5,6,7,11]
Drone C = [0,4,8,11]
Drone D = [0,9,10,11]
However, I’m struggling to generate a consistent output in my crossover function. My current function looks like this:
DNA DNA::crossover( DNA &parentB)
{
// sol holds the individual solution for
// each drone
std::vector<std::vector<std::size_t>> sol;
// contains the values in flattened sol
// used to check for duplicates
std::vector<std::size_t> flat_sol;
// returns the number of solutions
// required
int number_of_paths = this→getSolution().size();
// limits the number of waypoints required for each drone
// subtracting 2 to remove “0” and “11”
std::size_t max_wp_per_drone = ((number_of_cities-2)/number_of_drones) + 1;
for(std::size_t i = 0; i < number_of_paths; i++)
{
int start = rand() % (this->getSolution().at(i).size() -2) + 1;
int end = start + 1 + rand() % ((this->getSolution().at(i).size()-2) - start +1);
std::vector<std::size_t>::const_iterator first = this->getSolution().at(i).begin()+start;
std::vector<std::size_t>::const_iterator second = this- >getSolution().at(i).begin()+end;
// First Problem occurs here… Sometimes, newOrder can return nothing based on
//the positions of start and end. Tried to mitigate by putting a while loop
to regenerate the vector
std::vector<std::size_t> newOrder(first, second);
// RETURNS a vector from the vector of vectors sol
flat_sol = flatten(sol);
// compare new Order with solution and remove any duplicates..
for(std::size_t k = 0; k < newOrder.size(); k++ )
{
int duplicate = newOrder.at(k);
if(std::find(flat_sol.begin(), flat_sol.end(), duplicate) != flat_sol.end())
{
// second problem is found here, sometimes,
// new order might only return a vector with a single value
// or values that have already been assigned to another drone.
// In this case, those values are removed and newOrder is now 0
newOrder.erase(newOrder.begin()+k);
}
}
// attempt to create the vectors here.
for(std::size_t j = 1; j <=parentB.getSolution().at(i).size()-2; j++)
{
int city = parentB.getSolution().at(i).at(j);
if(newOrder.empty())
{
if(std::find(flat_sol.begin(), flat_sol.end(), city) == flat_sol.end())
{
newOrder.push_back(city);
}
}
else if((std::find(newOrder.begin(), newOrder.end(), city) == newOrder.end())
&&(std::find(flat_sol.begin(), flat_sol.end(), city) == flat_sol.end())
&& newOrder.size() < max_wp_per_drone )
{
newOrder.push_back(city);
}
}
sol.push_back(newOrder);
}
// waypoints and number_of drones are known,
//0 and 11 are appended to each vector in sol in the constructor.
return DNA(sol, waypoints, number_of_drones);
}
A sample output from my previous runs return the following:
[0,7,9,8, 11]
[0, 1,2,4,11]
[0, 10, 6, 11]
[0,3,11]
// This output is missing one waypoint.
[0,10,7,5, 11]
[0, 8,3,1,11]
[0, 6, 9, 11]
[0,2,4,11]
// This output is correct.
Unfortunately, this means in my subsequent generations of new children. and me getting the correct output seems to be random. For example, for one generation, I had a population size which had 40 correct children and 60 children with missing waypoints while in some cases, I've had more correct children. Any tips or help is appreciated.
Solved this by taking a slightly different approach. Instead of splitting the series of waypoints before perfoming crossover, I simply pass the series of waypoints
[0,1,2,3,4,5,6,7,8,9,10,11]
perform crossover, and when computing fitness of each set, I split the waypoints based on m drones and find the best solution of each generation. New crossover function looks like this:
DNA DNA::crossover( DNA &parentB)
{
int start = rand () % (this->getOrder().size()-1);
int end = getRandomInt<std::size_t>(start +1 , this->getOrder().size()-1);
std::vector<std::size_t>::const_iterator first = this->getOrder().begin() + start;
std::vector<std::size_t>::const_iterator second = this->getOrder().begin() + end;
std::vector<std::size_t> newOrder(first, second);
for(std::size_t i = 0; i < parentB.getOrder().size(); i++)
{
int city = parentB.getOrder().at(i);
if(std::find(newOrder.begin(), newOrder.end(), city) == newOrder.end())
{
newOrder.push_back(city);
}
}
return DNA(newOrder, waypoints, number_of_drones);
}

Number of paths in mXn grid

Is there a way to find the number of paths in mXn grid moving one cell at a time either downward, right or diagonally down-right using Permutation, starting from (1,1) and reaching (m,n)? I know there is a straight-forward DP solution and also P&C solution (i.e. m+n-2Cn-1) if the movement is only downward and right.
Look up Delannoy numbers. The combinatoric solution is expressed as a sum of multinomials.
Let t be the number of diagonal moves, the equation becomes:
This just needs a slight extension to the already existing solution DP solution that computes the path allowing movements only downwards and rightwards.
The only change you need to make is to count the number of ways you can reach a point if you move diagonally as well.
The code I took from http://www.geeksforgeeks.org/count-possible-paths-top-left-bottom-right-nxm-matrix/ should help you understand it better.
// Returns count of possible paths to reach cell at row number m and column
// number n from the topmost leftmost cell (cell at 1, 1)
int numberOfPaths(int m, int n)
{
// Create a 2D table to store results of subproblems
int count[m][n];
// Count of paths to reach any cell in first column is 1
for (int i = 0; i < m; i++)
count[i][0] = 1;
// Count of paths to reach any cell in first column is 1
for (int j = 0; j < n; j++)
count[0][j] = 1;
// Calculate count of paths for other cells in bottom-up manner using
// the recursive solution
for (int i = 1; i < m; i++)
{
for (int j = 1; j < n; j++)
// Rightwards Downwards Diagnoally right
count[i][j] = count[i-1][j] + count[i][j-1] + count[i-1][j-1];
}
return count[m-1][n-1];
}

Trying to multiply the kiddy way

I'm supposed to multiply two 3-digit numbers the way we used to do in childhood.
I need to multiply each digit of a number with each of the other number's digit, calculate the carry, add the individual products and store the result.
I was able to store the 3 products obtained (for I/P 234 and 456):
1404
1170
0936
..in a 2D array.
Now when I try to arrange them in the following manner:
001404
011700
093600
to ease addition to get the result; by:
for(j=5;j>1;j--)
{
xx[0][j]=xx[0][j-2];
}
for(j=4;j>0;j--)
{
xx[1][j]=xx[1][j-1];
}
xx is the 2D array I've stored the 3 products in.
everything seems to be going fine till I do this:
xx[0][0]=0;
xx[0][1]=0;
xx[1][0]=0;
Here's when things go awry. The values get all mashed up. On printing, I get 001400 041700 093604.
What am I doing wrong?
Assuming the first index of xx is the partial sum, that the second index is the digit in that sum, and that the partial sums are stored with the highest digit at the lowest index,
for (int i = 0; i < NUM_DIGITS; i++) // NUM_DIGITS = number of digits in multiplicands
{
for (int j = 5; j >= 0; j--) // Assuming 5 is big enough
{
int index = (j - 1) - (NUM_DIGITS - 1) - i;
xx[i][j] = index >= 0 ? xx[i][index] : 0;
}
}
There are definitely more efficient/logical ways of doing this, of course, such as avoiding storing the digits individually, but within the constraints of the problem, this should give you the right answer.

Game of life continues bounds

So I've been trying my hand at game of life and I noticed that the cells only stay confined within the grid that I've created. I want to try and make it continuous so if a cell reaches one side it will continue from the other side. Similar to the game pac-man when you leave from the left to come back into the game from the right side. Here is an image of how it would look as the cell moves out of bounds http://i.stack.imgur.com/dofv6.png
Here is the code that I have which confines everything. So How would I make it wrap back around?
int NeighborhoodSum(int i, int j) {
int sum = 0;
int k, l;
for (k=i-1;k<=i+1;k++) {
for (l=j-1;l<=j+1;l++) {
if (k>=0 && k<gn && l>=0 && l<gm && !(k==i && l==j)) {
sum+=current[k][l];
}
}
}
return sum;
}
Based on dshepherd suggestion this is what I have come up with.
if (!(k == i && l == j)) {
sum += current[k][l];
} else if (k == 1 || k == -1) { // rows
sum += current[k+1][l];
} else if (l == 1 || l == -1) { // columns
sum += current[k][l+1];
}
Start considering a one dimension array, of size ARRAY_SIZE.
What do you want that array to return when you ask for a cell of a negative index ? What about a for an index >= ARRAY_SIZE ? What operators does that make you think of (hint : <= 0, % ARRAY_SIZE, ...)
This will lead you to a more generic solution that dshepherd's one, for example if you want in the future to be able to specify life / death rules more than just one index around the cell.
Assuming a grid size of 0 to n-1 for x and 0 to m-1 for y (where n is the size of the x dimension and m is the size of the y dimension, what you want to do is check if the coordinates are in-range, and move accordingly. So (pseudocode):
// normal move calculation code here
if (x < 0) { x = n-1; }
if (x >= n) { x = 0; }
if (y < 0) { y = m-1; }
if (y >= m) { y = 0; }
// carry out actual move here
With the start position marked as red, you need to calculate a movement into, or a breeding into, a new square: you need to check for whether it would fall out of bounds. If it does then the new cell would be born in either of the orange positions, if not it could be born
in any of the blue positions:
Hope that helps:) Let me know if you need more information though:)
It looks like you are taking a summation over nearest neighbours, so all you need to do to make it wrap around is to extend the summation to include the cells on the other side if (i,j) is an edge cell.
You could do this fairly easily by adding else statements to the central if to check for the cases where l or k are -1 or gn/gm (i.e. just past the edges) and add the appropriate term from the cell on the opposite side.
Update:
What you've added in your edit is not what I meant, and I'm pretty sure it won't work. I think you need to carefully think through exactly what it is that the initial code does before you go any further. Maybe get some paper and do some example cases by hand?
More specific advice (but do what I said above before you try to use this):
You can't directly take current[k][l] if k or l are negative or greater than gn/gm respectively because there is no array entry with that index (the program should segfault). What you actually want it to do is use the 0th entry anywhere that it would normally use the gnth entry, and so on for all the other boundaries.
You will probably need to split the if statement into 5 parts not 3 because the cases for k < 0 and k > gn are different (similarly for l).
You are comparing against completely the wrong values with (k == 1 || k == -1) and similarly for l

n-th or Arbitrary Combination of a Large Set

Say I have a set of numbers from [0, ....., 499]. Combinations are currently being generated sequentially using the C++ std::next_permutation. For reference, the size of each tuple I am pulling out is 3, so I am returning sequential results such as [0,1,2], [0,1,3], [0,1,4], ... [497,498,499].
Now, I want to parallelize the code that this is sitting in, so a sequential generation of these combinations will no longer work. Are there any existing algorithms for computing the ith combination of 3 from 500 numbers?
I want to make sure that each thread, regardless of the iterations of the loop it gets, can compute a standalone combination based on the i it is iterating with. So if I want the combination for i=38 in thread 1, I can compute [1,2,5] while simultaneously computing i=0 in thread 2 as [0,1,2].
EDIT Below statement is irrelevant, I mixed myself up
I've looked at algorithms that utilize factorials to narrow down each individual element from left to right, but I can't use these as 500! sure won't fit into memory. Any suggestions?
Here is my shot:
int k = 527; //The kth combination is calculated
int N=500; //Number of Elements you have
int a=0,b=1,c=2; //a,b,c are the numbers you get out
while(k >= (N-a-1)*(N-a-2)/2){
k -= (N-a-1)*(N-a-2)/2;
a++;
}
b= a+1;
while(k >= N-1-b){
k -= N-1-b;
b++;
}
c = b+1+k;
cout << "["<<a<<","<<b<<","<<c<<"]"<<endl; //The result
Got this thinking about how many combinations there are until the next number is increased. However it only works for three elements. I can't guarantee that it is correct. Would be cool if you compare it to your results and give some feedback.
If you are looking for a way to obtain the lexicographic index or rank of a unique combination instead of a permutation, then your problem falls under the binomial coefficient. The binomial coefficient handles problems of choosing unique combinations in groups of K with a total of N items.
I have written a class in C# to handle common functions for working with the binomial coefficient. It performs the following tasks:
Outputs all the K-indexes in a nice format for any N choose K to a file. The K-indexes can be substituted with more descriptive strings or letters.
Converts the K-indexes to the proper lexicographic index or rank of an entry in the sorted binomial coefficient table. This technique is much faster than older published techniques that rely on iteration. It does this by using a mathematical property inherent in Pascal's Triangle and is very efficient compared to iterating over the set.
Converts the index in a sorted binomial coefficient table to the corresponding K-indexes. I believe it is also faster than older iterative solutions.
Uses Mark Dominus method to calculate the binomial coefficient, which is much less likely to overflow and works with larger numbers.
The class is written in .NET C# and provides a way to manage the objects related to the problem (if any) by using a generic list. The constructor of this class takes a bool value called InitTable that when true will create a generic list to hold the objects to be managed. If this value is false, then it will not create the table. The table does not need to be created in order to use the 4 above methods. Accessor methods are provided to access the table.
There is an associated test class which shows how to use the class and its methods. It has been extensively tested with 2 cases and there are no known bugs.
To read about this class and download the code, see Tablizing The Binomial Coeffieicent.
The following tested code will iterate through each unique combinations:
public void Test10Choose5()
{
String S;
int Loop;
int N = 500; // Total number of elements in the set.
int K = 3; // Total number of elements in each group.
// Create the bin coeff object required to get all
// the combos for this N choose K combination.
BinCoeff<int> BC = new BinCoeff<int>(N, K, false);
int NumCombos = BinCoeff<int>.GetBinCoeff(N, K);
// The Kindexes array specifies the indexes for a lexigraphic element.
int[] KIndexes = new int[K];
StringBuilder SB = new StringBuilder();
// Loop thru all the combinations for this N choose K case.
for (int Combo = 0; Combo < NumCombos; Combo++)
{
// Get the k-indexes for this combination.
BC.GetKIndexes(Combo, KIndexes);
// Verify that the Kindexes returned can be used to retrive the
// rank or lexigraphic order of the KIndexes in the table.
int Val = BC.GetIndex(true, KIndexes);
if (Val != Combo)
{
S = "Val of " + Val.ToString() + " != Combo Value of " + Combo.ToString();
Console.WriteLine(S);
}
SB.Remove(0, SB.Length);
for (Loop = 0; Loop < K; Loop++)
{
SB.Append(KIndexes[Loop].ToString());
if (Loop < K - 1)
SB.Append(" ");
}
S = "KIndexes = " + SB.ToString();
Console.WriteLine(S);
}
}
You should be able to port this class over fairly easily to C++. You probably will not have to port over the generic part of the class to accomplish your goals. Your test case of 500 choose 3 yields 20,708,500 unique combinations, which will fit in a 4 byte int. If 500 choose 3 is simply an example case and you need to choose combinations greater than 3, then you will have to use longs or perhaps fixed point int.
You can describe a particular selection of 3 out of 500 objects as a triple (i, j, k), where i is a number from 0 to 499 (the index of the first number), j ranges from 0 to 498 (the index of the second, skipping over whichever number was first), and k ranges from 0 to 497 (index of the last, skipping both previously-selected numbers). Given that, it's actually pretty easy to enumerate all the possible selections: starting with (0,0,0), increment k until it gets to its maximum value, then increment j and reset k to 0 and so on, until j gets to its maximum value, and so on, until j gets to its own maximum value; then increment i and reset both j and k and continue.
If this description sounds familiar, it's because it's exactly the same way that incrementing a base-10 number works, except that the base is much funkier, and in fact the base varies from digit to digit. You can use this insight to implement a very compact version of the idea: for any integer n from 0 to 500*499*498, you can get:
struct {
int i, j, k;
} triple;
triple AsTriple(int n) {
triple result;
result.k = n % 498;
n = n / 498;
result.j = n % 499;
n = n / 499;
result.i = n % 500; // unnecessary, any legal n will already be between 0 and 499
return result;
}
void PrintSelections(triple t) {
int i, j, k;
i = t.i;
j = t.j + (i <= j ? 1 : 0);
k = t.k + (i <= k ? 1 : 0) + (j <= k ? 1 : 0);
std::cout << "[" << i << "," << j << "," << k << "]" << std::endl;
}
void PrintRange(int start, int end) {
for (int i = start; i < end; ++i) {
PrintSelections(AsTriple(i));
}
}
Now to shard, you can just take the numbers from 0 to 500*499*498, divide them into subranges in any way you'd like, and have each shard compute the permutation for each value in its subrange.
This trick is very handy for any problem in which you need to enumerate subsets.