I have found a function on internet here for solving my problem on Sudoku written in C language.I have almost everything done but I am stuck here, I can't check the 3x3 box if any value is duplicated:
/**
* Check if a value contains in its 3x3 box for a cell.
* #param row current row index.
* #param col current column index.
* #return true if this cell is incorrect or duplicated in its 3x3 box.
*/
private boolean containedIn3x3Box(int row, int col, int value) {
// Find the top left of its 3x3 box to start validating from
int startRow = row / 3 * 3;
int startCol = col / 3 * 3;
// Check within its 3x3 box except its cell
for (int i = startRow; i < startRow + 3; i++)
for (int j = startCol; j < startCol + 3; j++) {
if (!(i == row && j == col)) {
if (cells[i][j] == value){
return true;
}
}
}
return false;
}
Up here is the function and I put it in my program here:
int valid(int k, int ii, int jj)
{
int i,start,final,j;
start=ii/3*3;
final=jj/3*3;
for(i = 1; i <= 9; ++i) {
if (i != ii && v[i][jj] == k)
return 0;
if (i != jj && v[ii][i] == k)
return 0;
}
for(i=start;i<=start+3;i++)
for(j=final;j<=final+3;j++)
{
if(!(i==ii && j==jj))
{
if(v[i][j]==k)
return 0;
}
}
return 1;
}
I have read on the website where I took this function and tried to understand the program. The program compares values with value part. My loop is not working well.
Your problem is with the loop start and end value.
The example uses 0-based counts. The three triplets have indexes (0,1,2) (3,4,5) (6,7,8).
You want to use 1-based loops.
You have missed to change the lower limit on the double loop:
int valid(int k, int ii, int jj)
{
int i,start,final,j;
start=ii/3*3;
final=jj/3*3;
for(i = 1; i <= 9; ++i) {
if (i != ii && v[i][jj] == k)
return 0;
if (i != jj && v[ii][i] == k)
return 0;
}
for(i=start+1;i<=start+3;i++) // Changed lower limit
for(j=final+1;j<=final+3;j++) // Changed lower limit
{
if(!(i==ii && j==jj))
{
if(v[i][j]==k)
return 0;
}
}
return 1;
}
Related
I am trying my hands at making a 4x4 Sudoku solver but I do not understand why the code produce any output. Is the loop running for too long or have I done a stupid yet fatal mistake in the do while loop. I do not seem to get into running the anotherround() function.
Here is my first attempt. The logic should be fine.
#include <stdio.h>
#define SIZE 4
void printBoard(int[][SIZE]);
void solve(int[][SIZE]);
int anotherRound(int[][SIZE]);
void checkBox(int[][SIZE], int, int, int, int);
int main(void)
{
int board[4][4] = {
{0,3,4,0},
{4,0,0,2},
{1,0,0,3},
{0,2,1,0}
};
solve(board); // solve the puzzle now!
printf("Sudoku puzzle solved:\n");
printBoard(board);
return 0;
}
// To print the 4x4 Sudoku board.
void printBoard(int board[][SIZE])
{
int r, c;
for (r = 0; r < SIZE; r++)
{
for (c = 0; c < SIZE; c++)
printf("%d ", board[r][c]);
printf("\n");
}
}
// Solving a Sudoku puzzle using a very simple
// algorithm (algorithm A in the write-up).
// It only solves the simplest puzzles.
void solve(int board[][SIZE])
{
int blankCellFound; // indicate whether there is still some blank cell
do
{
blankCellFound = anotherRound(board);
} while (blankCellFound == 1);
}
// Apply loop body of algorithm A and return 1 if there are still
// blank cells, or 0 if there is no more blank cell.
int anotherRound(int board[][SIZE])
{
int r, c,
sum, // Sum of elements in a row or column
countZero; // Number of zeroes in a row or column
// Check every row
for (r = 0; r < SIZE; r++)
{
sum = 0;
countZero = 0;
for (c = 0; c < SIZE; c++)
{
if (board[r][c] == 0)
countZero++;
else
sum += board[r][c];
}
if (countZero == 1)
{ // A single zero is present
for (c = 0; c < SIZE; c++)
{ // To find the position of the single zero
if (board[r][c] == 0)
{
board[r][c] = 10 - sum; // Replace the single zero with the obvious value
break;
}
}
}
}
// Check every column
for (c = 0; c < SIZE; c++)
{
sum = 0;
countZero = 0;
for (r = 0; r < SIZE; r++)
{
if (board[r][c] == 0)
countZero++;
else
sum += board[r][c];
}
if (countZero == 1)
{ // A single zero is present
for (r = 0; r < SIZE; r++)
{ // To find the position of the single zero
if (board[r][c] == 0)
{
board[r][c] = 10 - sum; // Replace the single zero with the obvious value
break;
}
}
}
}
// Check every box
checkBox(board, 0, 2, 0, 2);
checkBox(board, 0, 2, 2, 4);
checkBox(board, 2, 4, 0, 2);
checkBox(board, 2, 4, 2, 4);
// Check if there are any blank cells
for (r = 0; r < SIZE; r++)
{
for (c = 0; c < SIZE; c++)
{
if (board[r][c] == 0) // Blank cell found
return 1;
}
}
return 0; // No blank cell
}
// This function checks a 2X2 box if there is a single zero.
// If so, it replaces the zero with the obvious value.
// Precond: lrow <= urow, lcol <= ucol, 0 <= lrow, urow, lcol, ucol <= SIZE
void checkBox(int board[][SIZE], int lrow, int urow, int lcol, int ucol)
{
int r, c,
sum = 0, // Sum of elements in the 2X2 box
countZero = 0; // Number of zeroes in the 2X2 box
for (r = lrow; r < urow; r++)
{ // lrow and urow are the lower and upper limits of the rows
for (c = lcol; c < ucol; c++)
{ // lcol and ucol are the lower and upper limits of the columns
if (board[r][c] == 0)
countZero++;
else
sum += board[r][c];
}
}
if (countZero == 1)
{ // A single zero is present
for (r = lrow; r < urow; r++)
{
for (c = lcol; c < ucol; c++)
{ // To find the position of the single zero
if (board[r][c] == 0)
{
board[r][c] = 10 - sum; // Replace the single zero with the obvious value
break;
}
}
}
}
} ```
As you wrote, this algorithm can only solve the simplest puzzles.
Basically, it checks if there is a single zero in any row, column or 2x2 box, and then replace this zero with the missing value.
However, you test it with a more complex puzzle, when no row, column or box have this property. It therefore enter in an infinite loop,
in the solve(.) function.
For example, your code provides the correct answer, with this slightly modified puzzle:
int board[4][4] = {
{2,3,4,0},
{4,0,0,2},
{1,0,0,3},
{0,2,1,0}
};
I'm trying to solve the 8 queens puzzle problem in C. I'm having problems with the recursive search. The program is supposed to start at a given column:
execute(tabuleiro,8,0);
Where the 8 is the number of columns in the board, and 0 is the start column.
This works when I start at column 0. When I send any other column number to the recursive search, the program just counts to the last column. For example, if I choose to start the search from the number 5 column, the code search from the column 5 to 7, after this it should search from 0 to 4, but it doesn't do that.
If I do this:
execute(tabuleiro,8,3);
It fills in only the last 5 colummns, and does not return to column 0 to finish the solution:
Also, how can I select the initial position for the queen in this code? Like I said before, the column is assigned in the code, but I'm not sure how to pick the correct column.
The code has 3 functions: one is to display the board, a second to check if the move is legal (so one queen doesn't attack the other), and the last one to place one queen and recur for the remainder of the board.
#include <stdlib.h>
#include <windows.h>
int sol = 0;
void viewtab(int tab[][8], int N)
{
int i,j;
for( i = 0; i < N; i++)
{
for( j = 0; j < N; j++)
{
if(tab[i][j] == 1)
printf("R\t");
else
printf("-\t");
}
printf("\n\n");
}
printf("\n\n");
system("pause");
printf("\n");
}
int secury(int tab[][8], int N, int lin, int col)
{
// this function is to check if the move is secury
int i, j;
// attack in line
for(i = 0; i < N; i++)
{
if(tab[lin][i] == 1)
return 0;
}
//attack in colune
for(i = 0; i < N; i++)
{
if(tab[i][col] == 1)
return 0;
}
// attack in main diagonal
//
for(i = lin, j = col; i >= 0 && j >= 0; i--, j--)
{
if(tab[i][j] == 1)
return 0;
}
for(i = lin, j = col; i < N && j < N; i++, j++)
{
if(tab[i][j] == 1)
return 0;
}
// attack in main secondary
for(i = lin, j = col; i >= 0 && j < N; i--, j++)
{
if(tab[i][j] == 1)
return 0;
}
for(i = lin, j = col; i < N && j >= 0; i++, j--)
{
if(tab[i][j] == 1)
return 0;
}
// if arrive here the move is secury and return true
return 1;
}
void execute(int tab[][8], int N, int col)
{
int i;
if(col == N)
{
printf("Solution %d ::\n\n", sol + 1);
viewtab(tab, N);
sol++;
return;
}
for( i = 0; i < N; i++)
{
// check if is secury to put the queen at that colune
if(secury(tab, N, i, col))
{
// insert the queen (with 1)
tab[i][col] = 1;
// call recursive
execute(tab, N, col + 1);
// remove queen (backtracking)
tab[i][col] = 0;
}
}
}
int main()
{
int i, j, tabuleiro[8][8];
for (i = 0; i < 8; i = i + 1)
for (j = 0; j < 8; j = j + 1) tabuleiro[i][j] = 0;
execute(tabuleiro,8,0);
return 0;
}
The search always stops in the rightmost column because you specifically tell it to stop there:
void execute(int tab[][8], int N, int col)
{
int i;
if(col == N)
{
printf("Solution %d ::\n\n", sol + 1);
viewtab(tab, N);
sol++;
return;
}
Look at your termination condition: you check the current column against the highest column number, and stop there.
If you want to go back to column 0, you have to change your loop logic. For instance, let col reach N, at which point you reset it to 0, and let it continue until you hit the original value. Another way is to continue until the count of placed queens is N.
You choose the initial point in the same way: you pick the first one and make your recursive call. If that eventually results in a solution, you print it. If not, your top-most call continues to the next row (line) of the board and puts the first queen there.
This is already in your main logic. Just make sure that secury will return true when the board is empty, rather than false or throwing an error.
A. You can place the first Queen at (0,0).
B. And begin the search also from (0,0).
C. I do not see any need to start looking for some other index.
Successfully!!
I'm doing another exercise and I have to :
"Write a recursive function to print all solution to the eight queens chess problem, return the number of solutions and the function prototype must be : int function(void)
To work around the no argument rule I used static variables.
I've done it (with google's help), and it works, but they don't allow to use for loops and for some reason I can't manage to convert the last two for loops to while loops.
It' driving me crazy, it should be easy! I think it's the recursion that mess it up...
Here's the working function :
int function()
{
static int count = 0;
static int col = 0;
const int n = 8;
static int hist[8] = {10, 10, 10, 10, 10, 10, 10, 10};
int i1 = 0;
if (col == n) {
count++;
while (i1++ < n)
{
putchar('0' + hist[i1-1] + 1);
}
putchar('\n');
}
for (int i = 0; i < n; i++) {
int j = 0;
for (j = 0; j < col && !(hist[j] == i || (hist[j] - i) == col - j || -(hist[j] - i) == col - j); j++);
if (j < col) {
continue;
}
hist[col] = i;
col++;
function();
col--;
}
return count;
}
And I tried to convert the two last for loops to while loops like this :
int i = 0;
while (i < n)
{
int j = 0;
while (j < col && !(hist[j] == i || (hist[j] - i) == col - j || -(hist[j] - i) == col - j))
{
j++;
}
if (j < col) {
continue;
}
hist[col] = i;
col++;
function();
col--;
i++;
}
But it doesn't work, is there more the for loops than it seems ? I'm new to recursion, I thought I got it but it seems I was wrong...
I ran the code and found the problem. It is with the line
if (j < col) {
continue;
}
since this isn't a continue statement that goes to a for loop, you have to increment i in this condition as well.
if (j < col) {
i++; // add this line
continue;
}
You can change the first loop to
while(i++<n)
and it works fine.
Consider a zero-indexed array A of N integers. Indices of this array are integers from 0 to N−1. Take an index K.
Index J is called an ascender of K if A[J] > A[K]. Note that if A[K] is a maximal value in the array A, then K has no ascenders.
Ascender J of K is called the closest ascender of K if abs(K−J) is the smallest possible value (that is, if the distance between J and K is minimal).
Note that K can have at most two closest ascenders: one smaller and one larger than K.
Here is a C++ solution where complexity is O(n).
Note that there are two loops however each iteration the number of element goes by a factor of 1/2 or the search range goes up by a factor of x2.
For example the first iteration take N time, but the second iteration is already N/2.
vector<long> ascender(vector <long> A)
{
long N = A.size();
vector<long> R(N,0);
vector<long> IndexVector(N,0); //This vector contains the index of elements with R=0
vector<long> RangeVector(N,0); //This vector define the loop range for each element
IndexVector[N-1]=N-1;
unsigned long CompxTest = 0;
for (long counter=0;counter<N;counter++)
{
IndexVector[counter] = counter; // we start that all elements needs to be consider
RangeVector[counter] = 1; // we start by looking only and neighbors
}
long Length = N;
long range;
while (Length>1)
{
long index = 0;
cout<<endl<<Length;
long J;
for (long counter=0;counter<Length;counter++)
{
CompxTest++; // Just to test complexity
J = IndexVector[counter]; // Get the index that need to be consider
range = RangeVector[J];
//cout<<" ("<<A[J]<<","<<J<<")";
if (range > N)
{
cout<<endl<<"Mini assert "<<range<<" N "<<N;
break;
}
if (J<(N-range) && A[J+range] > A[J])
{
R[J] = range;
}
if (J<(N-range) && A[J+range] < A[J] && R[J+range]==0)
{
R[J+range] = range;
}
if (J<(N-range) && A[J] == A[J+range] && R[J+range]==0)
{
R[J+range] = - range;
}
if (R[J]==0) // Didn't find ascender for this element - need to consider in next iteration
{
if (R[J+range]>2) //We can increase the range because the current element is smaller
RangeVector[J] += R[J+range]-2;
if (R[J+range]<-2)
RangeVector[J] += -R[J+range]-2;
RangeVector[J]++;
IndexVector[index] = J;
index++;
}
}
Length = index;
}
for (long counter=0;counter<N;counter++)
{
if (R[counter] < 0)
{
unsigned Value = abs(R[counter]);
if (counter+Value<N && A[counter]<A[counter+Value])
R[counter] = Value;
if (counter > Value && R[counter-Value]==0)
R[counter] = 0;
R[counter] = Value + R[counter-Value];
if (counter > Value && Value < R[counter - Value])
{
long PossibleSolution = R[counter - Value] + Value;
if (PossibleSolution <N && A[PossibleSolution]>A[counter])
R[counter] = abs(counter - PossibleSolution);
}
}
}
cout<<endl<<"Complex "<<CompxTest;
return R;
}
//
// C++ using multimap. -- INCOMPLETE
// The multimap MM is effectively the "inverse" of the input array AA
// since it is ordered by pair(value, index), where index refers to the index in
// input array AA, and value is the value in AA at that index.
// Input AA is of course ordered as (index, value).
// So when we read out of MM in value order, (a sorted set of values), each value
// is mapped to the index in the original array AA.
//
int ascender(int AA[], int N, int RR[]) {
multimap<int, int> MM;
// simply place the AA array into the multimap
int i;
for (i = 0; i < N; i++) {
int value = AA[i];
int index = i;
MM.insert(make_pair(value, index));
}
// simply read the multimap in order,
// and set output RR as the distance from one value's
// original index to the next value's original index.
//
// THIS code is incomplete, since it is wrong for duplicate values.
//
multimap<int, int>::iterator pos;
for (pos = MM.begin(); pos != MM.end(); ++pos) {
int value = pos->first;
int index = pos->second;
++pos;//temporarily move ahead to next item
// NEED to FURTHER CONSIDER repeat values in setting RR
RR[index] = (pos)->second - index;
--pos;
}
return 1;
}
1. Sort the array (if not pre-sorted)
2. Subtract every element with its adjacent element and store result in another
array.
Example: 1 3 5 6 8 -----> (after subtraction) 2 2 1 2
3. Find the minimal element in the new array.
4. Device a logic which would relate the minimal element in the new array to the
two elements in the original one.
public class Solution {
final static int MAX_INTEGER = 2147483647;
public static int maximal(int[] A) {
int max = A[0];
int length = A.length;
for (int i = 1; i < length; i++) {
if (A[i] > max) {
max = A[i];
}
}
return max;
}
public static int ascender(int[] a,int length, int k) {
int smallest = MAX_INTEGER;
int index = 0;
if (k<0 || k>length-1) {
return -1;
}
for (int i = 0; i < length; i++) {
// Index J is called an ascender of K if A[J] > A[K].
if(a[i] > a[k]) {
int abs = Math.abs(i-k);
if ( abs < smallest) {
smallest = abs;
index = i;
}
}
}
return index;
}
public static int[] array_closest_ascenders(int[] A) {
int length = A.length;
int[] R = new int[length];
for (int K = 0; K < length; K++) {
// Note that if A[K] is a maximal value in the array A,
// then K has no ascenders.
// if K has no ascenders then R[K] = 0.
if (A[K] == maximal(A)) {
R[K] = 0;
break;
}
// if K has the closest ascender J, then R[K] = abs(K-J);
// that is, R[K] is equal to the distance between J and K
int J = ascender(A, A.length, K);
if (J != -1) {
R[K] = Math.abs(K - J);
}
}
return R;
}
public static void main(String[] args) {
int[] a = { 4, 3, 1, 4, -1, 2, 1, 5, 7 };
/* int[] a = {-589630174, 806785750, -495838474, -648898313,
149290786, -798171892, 584782920, -288181260, -252589640,
133741336, -174886978, -897913872 }; */
int[] R = array_closest_ascenders(a);
for (int element : R) {
System.out.print(element + " ");
}
}
}
Some notes about the code. I guess break in array_closest_ascenders method should be replaced by continue so that all elements are analyzed for their ascenders.
And, surely, maximal(A) have to be moved out of a loop; instead assign maximal value to some variable before entering the loop and use it within the loop, thus avoiding redundant calculation of max value.
Here is C# Solution
class Program
{
static void Main(string[] args)
{
int[] A = new int[] { 4, 3, 1, 4, -1, 2, 1, 5, 7 };
int[] B = new int[A.Length];
int[] R = new int[A.Length];
Program obj = new Program();
obj.ABC(A,B, R);
}
public void ABC(int[] A,int[]B, int[] R)
{
int i, j, m,k;
// int temp = 0;
int n = A.Length - 1;
for (i = 0; i < n; i++)
{
for (j = 0; j <= n; j++)
{
if (A[i] < A[j])
{
m = Math.Abs(j - i);
R[i] = m;
break;
}
}
for (j = i-1; j > 0; j--)
{
if (A[i] < A[j])
{
k = Math.Abs(j - i);
B[i] = k;
break;
}
}
}
for (i = 0; i < n; i++)
{
if (R[i] > B[i] && (B[i] == 0))
{
R[i] = R[i];
//Console.WriteLine(R[i]);
//Console.ReadLine();
}
else { R[i] = B[i]; }
}
}
}
Basically in the search function I compare the first element of the array with the one immediately right, if it's bigger this means it is the first closest ascendant. For the other elements I compare the one immediately at left and afterward the one immediately right his first right element. The first one which is bigger is the closest ascendant, and I keep iterate this way until I don't find an element bigger than one I am considering or I return 0.
class ArrayClosestAscendent {
public int[] solution(int[] A) {
int i;
int r[] = new int[A.length];
for(i=0;i<A.length;i++){
r[i] = search(A, i);
}
return r;
}
public int search(int[] A, int i) {
int j,k;
j=i+1;
k=i-1;
int result = 0;
if(j <= A.length-1 && (A[j]>A[i]))
return Math.abs(j-i);
j++;
while(k>=0 || j < A.length){
if(k >= 0 && A[k] > A[i]){
return Math.abs(i-k);
}else if(j < A.length && A[j] > A[i]){
return Math.abs(i-j);
}else{
j++;
k--;
}
}
return result;
}
}
I was trying to calculate the determinant of a 3 * 3 matrix (or more) with the matrix values ranging from (-1, to 1). However, I get a result of 0 when I calculate the determinant.
[...]
srand(time(NULL));
//Random generation of values between -1 and 1
for(i = 0; i < 3; i++)
{
for(j = 0; j < 3; j++)
{
temp = (rand() % (500)) + 0;
temp = temp/250;
array[i][j] = (temp - 1);
}
[...]
double array2[10][10];
double detrm = 0;
int s = 1;
int i, j, m, n, c;
for (c = 0; c < x; c++)
{
m = 0;
n = 0;
for (i = 0; i < x; i++)
{
for (j = 0; j < x; j++)
{
array2[i][j] = 0;
if (i != 0 && j != c)
{
array2[m][n] = a[i][j];
if ( n < (x - 2))
{
n++;
}
else
{
n = 0;
m++;
}
}
}
}
detrm = detrm + (s*a[0][c]*determinant(array2, (x - 1)));
s = -1*s;
}
return(detrm);
This may Help - see comments within the code for an explanation:
static int CalcDeterminant(vector<vector<int>> Matrix)
{
//this function is written in c++ to calculate the determinant of matrix
// it's a recursive function that can handle matrix of any dimension
int det = 0; // the determinant value will be stored here
if (Matrix.size() == 1)
{
return Matrix[0][0]; // no calculation needed
}
else if (Matrix.size() == 2)
{
//in this case we calculate the determinant of a 2-dimensional matrix in a
//default procedure
det = (Matrix[0][0] * Matrix[1][1] - Matrix[0][1] * Matrix[1][0]);
return det;
}
else
{
//in this case we calculate the determinant of a squared matrix that have
// for example 3x3 order greater than 2
for (int p = 0; p < Matrix[0].size(); p++)
{
//this loop iterate on each elements of the first row in the matrix.
//at each element we cancel the row and column it exist in
//and form a matrix from the rest of the elements in the matrix
vector<vector<int>> TempMatrix; // to hold the shaped matrix;
for (int i = 1; i < Matrix.size(); i++)
{
// iteration will start from row one cancelling the first row values
vector<int> TempRow;
for (int j = 0; j < Matrix[i].size(); j++)
{
// iteration will pass all cells of the i row excluding the j
//value that match p column
if (j != p)
{
TempRow.push_back(Matrix[i][j]);//add current cell to TempRow
}
}
if (TempRow.size() > 0)
TempMatrix.push_back(TempRow);
//after adding each row of the new matrix to the vector tempx
//we add it to the vector temp which is the vector where the new
//matrix will be formed
}
det = det + Matrix[0][p] * pow(-1, p) * CalcDeterminant(TempMatrix);
//then we calculate the value of determinant by using a recursive way
//where we re-call the function by passing to it the new formed matrix
//we keep doing this until we get our determinant
}
return det;
}
}
};
You have a crufty way of updating m and n. You should increment m in the outer loop over i, and initialize n within the outer loop and increment it within the inner loop. I think that your code would work as you wrote it, but I think that your conditional should have been i < n-1 instead of i < n-2. But instead of changing the fewest number of characters to get the code to work, I recommend restructuring the increments so that the issue doesn't arise.