I'm trying to modify an N-Queen puzzle solver to an N-Empress solver (Where the pieces can move like both rook and knight)
The code places (or at least tries to place) the chancellors in a way that they do not threaten each other. And backtracks to print all of the possible solutions. However, I can't get it to output the correct amount of solutions. The current ones it outputs is correct, but it doesn't output all of them. Not sure what condition I'm missing.
#include<stdio.h>
#include<math.h>
/*
N=4:8 Solutions
N=5:20 Solutions
N=8:2766 Solutions
*/
int board[20],count;
int main()
{
int n,i,j,numPuzzle;
void queen(int row,int n);
printf("Enter Number of Queens:");
scanf("%d", &n);
queen(1,n);
return 0;
}
//function for printing the solution
void print(int n)
{
int i,j;
printf("\n\nSolution %d:\n\n",++count);
for(i=1;i<=n;++i)
printf("\t%d",i);
for(i=1;i<=n;++i)
{
printf("\n\n%d",i);
for(j=1;j<=n;++j) //for nxn board
{
if(board[i]==j)
printf("\tQ"); //queen at i,j position
else
printf("\t-"); //empty slot
}
}
}
/*funtion to check conflicts
If no conflict for desired postion returns 1 otherwise returns 0*/
int place(int row,int column)
{
int i;
for(i=1;i<=row-1;++i)
{
//checking column and digonal conflicts
//printf("\nboard[i]=%d column=%d\n",board[i],column);
if(board[i]==column)
{
return 0;
}
if( (abs(board[i]-(column+3))==abs(i-row)) )
{
return 0;
}
if( (abs(board[i]-(column-3))==abs(i-row)) )
{
return 0;
}
if( (abs(board[i]+(column-3))==abs(i-row)) )
{
return 0;
}
if( (abs(board[i]+(column+3))==abs(i-row)) )
{
return 0;
}
}
return 1; //no conflicts
}
//function to check for proper positioning of queen
void queen(int row,int n)
{
int column;
for(column=1;column<=n;++column)
{
if(place(row,column))
{
board[row]=column; //no conflicts so place queen
if(row==n) //dead end
print(n); //printing the board configuration
else //try queen with next position
queen(row+1,n);
}
}
}
The place method is doesn't seem to be covering all cases. In knight move, the difference in columns and difference in rows sum up to 3.
int place(int row,int column)
{
int i;
for(i=1;i<=row-1;++i)
{
//checking column and digonal conflicts
//printf("\nboard[i]=%d column=%d\n",board[i],column);
if(board[i]==column)
{
return 0;
}
if(abs(board[i]-column)+abs(row-i)==3 )
{
return 0;
}
}
return 1; //no conflicts
}
The check against the Knight attack involves testing four tiles in relation to the current one. (There are eight possible Knight moves, but you only have to look in the rows that you have already placed Chancellors in, of course.)
in place, you probe the tile column and row, so you should check
board[row - 1] != column ± 2 (only if row -1 is on the board)
board[row - 2] != column ± 1 (only if row - 2 is on the board)
While you need to check all rows for attacking Rooks, the check for the Knight move is done only once. So:
int place(int row, int column)
{
int i;
if (row > 1 && abs(column - board[row - 1]) == 2) return 0;
if (row > 2 && abs(column - board[row - 2]) == 1) return 0;
for (i = 1; i < row; ++i) {
if (board[i] == column) return 0;
}
return 1;
}
Related
I need to implement McEliece in C and this function is supposed to put a
matrix in systematic form. (U need a such matrix to encrypt the message by
matrix vector multiplication. Can someone help me to understand it?
You can find the whole code with all classes here. This function is from the file mat.c
int * mat_rref(binmat_t A)//This code is supposed to put matrix A in
//systematic form. typedef struct matrix{int
//rown, int coln, int alloc_size}*binmat_t;
{
int i,j,failcnt,findrow,max=A->coln - 1;
int *perm;
perm = malloc(A->coln * sizeof(int));//initialise permutation
for(i=0;i<A->coln;i++)
perm[i]=i;//initialize permutation.
failcnt = 0;
for(i=0;i<A->rown;i++,max--)
{
findrow=0;
for(j=i;j<A->rown;j++)
{
if(mat_coeff(A,j,max))//(A->elem[(j*A->coln)+max])
{
//max--;
if (i!=j)//not needed as ith row is 0 and jth row is 1.
A=mat_rowxor(A,i,j);//xor to the row.(swap)?
findrow=1;
break;
}//largest value found (end if)
// break;
}
if(!findrow)//if no row with a 1 found then swap last column and the column with no 1 down.
{
perm[A->coln - A->rown - 1 - failcnt] = max;
failcnt++;
if (!max)
{
return NULL;
}
i--;
}
else
{
perm[i+A->coln - A->rown] = max;
for(j=i+1;j<A->rown;j++)//fill the column downwards with 0's
{
if(mat_coeff(A,j,(max)))//(A->elem[j*A->coln+max+1])
A=mat_rowxor(A,j,i);//check the arg. order.
}
for(j=i-1;j>=0;j--)//fill the column with 0's upwards too.
{
if(mat_coeff(A,j,(max)))//(A->elem[j*A->coln+max+1])
A=mat_rowxor(A,j,i);
}
}
}//end for(i)
return(perm);
}
The following question I was asked to solve using backtracking:
It's supposed to return the length of the longest subset of differences that replaces a sign.
For example:
for this given series [11,6,7,8,9] it returns 3.
because it includes this subset [11,8,9] and [11,6,8] .
*In this series a:[11,8,9] a[1]-a[0]<0 and a[2]-a[1]>0 .In other words the sign of the difference between each neighbor changes. *
I pretty much finished the coding but have no idea how to return the max length using backtracking.
Any note/help will be highly appreciated.
/* this function checks if we can add another number to the sequence
and still the differences between the numbers replace a sign.It's enough
to check the last two*/
int check_rec(int series[],int arr[],int n)
{ int count=0,c=n;
int temp1=0,temp2=0;
while(c>=0 && count!=2)
{
if (arr[c]==1 && count==0)
{ temp1=series[c];
count++;
}
if (arr[c]==1 && count==1 )
{ temp1=series[c];
count++;
}
c--;
}
if(count<2) return 1;
if(temp1>temp2 && series[n+1] < temp1) return 1;
if(temp1<temp2 && series[n+1]> temp1) return 1;
return 0;
}
int count_ones(int arr[],int n)
{ int c;
for(int i=0;i<n;i++)
{
if(arr[i])
c++;
}
return c;
}
// 1 in the array helper indicates that the index has been chosen.
void max_crazy(int series[], int n,int helper[],int length,int max[])
{
if(n==0)
{
int x=count_ones(helper,n);
if(x>max[0])
max[0]=x;
}
for(int i=0;i<2;i++)
{
if(n!=length && i==1 && !check_rec(series,helper,length-n))
continue;
helper[0]=i;
max_crazy(series,n-1,helper+1,length,max);
}
}
you can send a pointer that saves the max in the recursive function , and every time you reach the if(n==0) you have to check if the count_ones bigger than max then max=count_ones
This is an exercise that I took from an exam. It asks to write a function that receives an unsorted array v[] and a number X and the function will return 1 if X is present in v[] or 0 if X is not present in v[]. The function must be recursive and must work in this manner:
1. Compares X with the element in the middle of v[];
2. The function calls itself (recursion!!) on upper half and on the lower half of v[];
So I've written this function:
int occ(int *p,int dim,int X){
int pivot,a,b;
pivot=(dim)/2;
if(dim==0) //end of array
return 0;
if(*(p+pivot)==X) //verify if the element in the middle is X
return 1;
a=occ(p,pivot,X); //call on lower half
b=occ(p+pivot,dim-pivot,X); //call on upper half
if(a+b>=1) //if X is found return 1 else 0
return 1;
else{
return 0;
}
}
I tried to simulated it on a sheet of paper and it seems to be correct (Even though I'm not sure) then I've written it on ideone and it can't run the program!
Here is the link: https://ideone.com/ZwwpAW
Is my code actually wrong (probably!) or is it a problem related to ideone. Can someone help me? Thank you in advance!!!
The problem is with b=occ(p+pivot,dim-pivot,X); when pivot is 0. i.e. when dim is 1.
the next function call becomes occ(p,1,X); This again leads to the call occ(p,1,X); in a continuous loop.
It can be fixed by adding a condition to the call, as shown in the code below.
int occ(int *p,int dim,int X){
int pivot,a=0,b=0;
pivot=(dim)/2;
if(dim==0){
return 0;
}
if(*(p+pivot)==X)
return 1;
if (pivot != 0)
{
a=occ(p,pivot,X);
b=occ(p+pivot,dim-pivot,X);
}
if(a+b>=1)
return 1;
else{
return 0;
}
}
The implemetation is causing a stack overflow, as the recursion does not terminate if the input contains only one element. This can be fixed as follows.
int occ(int *p, int dim, int X)
{
int pivot, a, b;
pivot = (dim) / 2;
if (dim == 0)
{
return 0;
}
if (*(p + pivot) == X)
{
return 1;
}
if (dim == 1)
{
if (*(p + pivot) == X)
{
return 1;
}
else
{
return 0;
}
}
a = occ(p, pivot, X);
b = occ(p + pivot, dim - pivot, X);
if (a + b >= 1)
{
return 1;
}
else
{
return 0;
}
}
It's enought to change only this one line in the source code to avoid the endless loop with occ(p,1,X):
//if(dim==0) //end of array
if (pivot == 0)
return 0;
i'm writing c code to check whether given matrix is valid sudoku solution or not.
Input would be matrix of n*n size.
I have written code to check row and column but i'm not getting how to validate grids of sqrt(n)*sqrt(n) size.
my code is here
#include<stdio.h>
int main()
{
int i,j,count=0,sumrow;
int sumcol;
int n;
scanf("%d",&n);
int arr[n+1][n+1];
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
scanf("%d",&arr[i][j]);
for(i=1;i<=n;i++)
{
sumcol=0;
for(j=1;j<=n;j++)
sumcol+=arr[j][i];
if(sumcol!=(n*(n+1)/2))
count++;
}
for(i=1;i<=n;i++)
{
sumrow=0;
for(j=1;j<=n;j++)
{
sumrow+=arr[i][j];
}
// printf("%d\n",sumrow);
if(sumrow!=(n*(n+1)/2))
count++;
}
//printf("count%d ",count);
if(count==0)
printf("yes");
else
printf("no");
return 0;
}
Here i have a better solution. Instead of sum, we can use an integer flag.
//read sudoku
for(i=0;i<9;i++)
for(j=0;j<9;j++)
{
scanf("%c",&c);
a[i][j]=c-'0';
}
//checking rows
for(i=0;i<9;i++)
{
flag=0x0000;
for(j=0;j<9;j++)
flag|=1<<(a[i][j]-1);
if(flag!=0x01FF)
report("row",i,j-1);
}
//checking cols
for(j=0;j<9;j++)
{
flag=0x0000;
for(i=0;i<9;i++)
flag|=1<<(a[i][j]-1);
if(flag!=0x01FF)
report("col",i-1,j);
}
//checking Squares (3x3)
for(si=0;si<3;si++)
{
for(sj=0;sj<3;sj++)
{
flag=0x0000;
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
flag|=1<<(a[si*3+i][sj*3+j]-1);
}
if(flag!=0x01FF)
report("square",si*3+i-1,sj*3+j-1);
}
}
printf("\nThe sudoku is correct");
For detailed description, You may visit this link
You can check each of the smaller squares whether they are valid or not.For example if n=9 you have to check each of the 3 by 3 squares.To check each smaller square you can use an array of 10 elements and check whether any of the 1 to 9 value is repeated or not.
The algorithm is as follows
for each of the smaller grids
if(any of the digit repeats in a smaller grid)
return 0;
return 1;//valid
Following is some code to do the same
//A is the grid
int small=sqrt(n);
for(int i=0;i<small;i++)
{
for(int j=0;j<small;j++)
{
int row=small*i;//this will find the corresponding row
int col=small*j;//this will find the corresponding column
vector<int> used(10,0)
for(int p=row; p<row+small; p++) {
for(int q=col; q<col+small; q++)
{
if(A[p][q]=='0')//0 is not valid
return 0;
if(used[A[p][q]-'0']==1)//this digit has already been used
return 0;
if(used[A[p][q]-'0']) return 0;
used[A[p][q]-'0']=1;//now this particular digit has occurred and should not occur again
}
}
}
}
//if all's well return 1
return 1;
Note that the above code assumes that entire grid is filled and is not empty.If you want to check a partially filled grid,introduce a check.
int main() {
int a[10][10],i,j,n,k,sum,sum1,sum2,sum3,x,l;
printf("enter the size N of N*N sudoku\n");
scanf("%d",&n);
printf("enter the entries of sudoku row wise \n");
for (i=1;i<=n;i++) {
for (j=1;j<=n;j++) {
scanf("%d",&a[i][j]);
}
printf("\n");
}
printf("---------------------------------\n\n\n\n");
printf("the matrix you entered is \n");
for (i=1;i<=n;i++) {
for (j=1;j<=n;j++) {
printf("%d",a[i][j]);
printf("|");
}
printf("\n");
}
for (i=1;i<=n;i++) {
for (k=i;k==i;k++) {
sum=0;
for (j=1;j<=n;j++) {
sum = sum + a[i][j];
}
if(sum!=45)
x=1;
}
}
for (j=1;j<=n;j++) {
for(k=j;k==j;k++) {
sum=0;
for (i=1;i<=n;i++) {
sum = sum+a[i][j];
}
if (sum!=45)
x=1;
}
}
for (k=1;k<=3;k++) {
l = (1+(k-1)*n/3);
for (i=l;i<=k*n/3;i++) {
for(j=1;j<=3;j++) {
sum1 = sum1+a[i][j];
}
for (j=4;j<=6;j++) {
sum2 = sum2+a[i][j];
}
for (j=7;j<=9;j++) {
sum3 = sum3+a[i][j];
}
}
if (sum1!=45||sum2!=45||sum3!=45)
x=1;
}
if (x==1)
printf("sudoku not correct \n");
else
printf("correct sudoku");
return 0;
}
bool validateMatrix(int g_iMatrix1[][MAXCOLS],
int iROWS,
int iCOLS)
{
bool bRowUsed[MAXROWS][MAXCOLS] = {0};
bool bColUsed[MAXROWS][MAXCOLS] = {0};
bool bBlockUsed[MAXROWS][MAXCOLS] = {0};
//Matrix to keep record if current value is already set in current row..
memset(bRowUsed, false, (MAXROWS) * (MAXCOLS));
//Matrix to keep record if current value is already set in current column..
memset(bColUsed, false, (MAXCOLS) * (MAXCOLS));
//Matrix to keep record if current value is already set in current block of iSQRT * iSQRT..
//Lets assume the matrix is of size 9 * 9..
//So there will be 9 block of 3 * 3..
//Number the blocks from left to right as 0 to 8..
//We will be mapping 0 the block to 0th row, 1st block to 1st row, 2nd block to 2nd row and so on..
memset(bBlockUsed, false, (MAXROWS) * (MAXCOLS));
int iRows = 0,iCols = 0;
int iSQRT = int(sqrt(MAXCOLS));
for(iRows = 0;iRows < iROWS;iRows++)
{
for(iCols = 0;iCols < iCOLS;iCols++)
{
if(bRowUsed[iRows][g_iMatrix1[iRows][iCols] - 1] == true)
{
return false;
}
if(bColUsed[g_iMatrix1[iRows][iCols] - 1][iCols] == true)
{
return false;
}
//Number the blocks from left to right as 1 to 9..
//We will be mapping 0 the block to 0th row, 1st block to 1st row, 2nd block to 2nd row and so on..
//((iRows / iSQRT) * iSQRT) + (iCols / iSQRT) will map the block with above logic..
if(bBlockUsed[((iRows / iSQRT) * iSQRT) + (iCols / iSQRT)][g_iMatrix1[iRows][iCols] - 1] == true)
{
return false;
}
bRowUsed[iRows][g_iMatrix1[iRows][iCols] - 1] = true;
bColUsed[g_iMatrix1[iRows][iCols] - 1][iCols] = true;
bBlockUsed[((iRows / iSQRT) * iSQRT) + (iCols / iSQRT)][g_iMatrix1[iRows][iCols] - 1] = true;
}
}
return true;
}
I have been asked this question during an interview, and have been struggling to find an elegant solution (in C), Problem statement:
You are given a two-dimensional array with M rows and N columns.
You are initially positioned at (0,0) which is the top-left cell in
the array.
You are allowed to move either right or downwards.
The array is filled with 1′s and 0′s. A 1 indicates that you can move
through that cell, a 0 indicates that you cannot move through the
cell.
Write a function in C ‘numberOfPaths’ which takes in the above two dimensional array, return the number of valid paths from the top-left cell to the bottom-right cell (i.e. [0,0] to [M-1,N-1]).
Edit: forgot to mention that the requirement is for a recursive solution
help would be greatly appreciated!
Thanks
If you are looking for a recursive solution you can use DFS.
DFS (array, x, y)
{
if (array [x][y]==0 || x>M || y>N){
return;
}
if (x==M && y==N){
count++;
return;
}
DFS (array, x, y+1);
DFS (array, x+1, y);
}
The number of paths to a given point is just the number of paths to the point above, plus the number of paths to the point to the left. So, the pseudo-code would roughly be:
num_paths[0][0] = 1;
for (x = 0; x < M; ++x)
for (y = 0; y < N; ++y)
if (!allowed_through[x][y])
num_paths[x][y] = 0;
else
num_paths[x][y] = num_paths[x-1][y] + num_paths[x][y-1];
You need special cases for x=0 and y=0, but otherwise, I think that should do.
#include <stdio.h>
int count=0;
int maxrows = 10;
int maxcols = 10;
int M, N;
void DFS (int array[][10], int x, int y)
{
int r, c;
/* process element at input row and column */
if (array [x][y]==0 || x>M || y>N){
/* no path forward; return */
return;
}
if (x==M-1 && y==N-1){
/* found path; increment count */
count++;
return;
}
/* recurse: to matrix starting from same row, next column */
r = x;
c = y +1;
if (c < N-1) {
DFS (array, r,c);
} else {
/* if last column - check to see */
/* if rest of rows in last column allow for a path */
int tr = r;
while ( tr <= M-1) {
if (array[tr][c] == 1) {
tr++;
}
else {
return;
}
}
/* reached last node - path exists! */
count++;
}
/* recurse: to matrix starting from next row, same column */
r = x+1;
c = y;
if (r < M-1) {
DFS (array, r,c);
} else {
/* if last row - check to see */
/* if rest of columns in last row allow for a path */
int tc = c;
while ( tc <= N-1) {
if (array[r][tc] == 1) {
tc++;
} else {
return;
}
}
/* reached last node - path exists! */
count++;
}
}
int main () {
int i, j;
scanf("%d %d",&M,&N);
int a[10][10] = {};
int row, col;
for(i=0;i<M;i++)
for(j=0;j<N;j++)
scanf("%d", &a[i][j]);
if ((M > maxrows) || (N > maxcols)) {
printf("max of 10 rows and 10 cols allowed for input\n");
return (-1);
};
/* print input matrix */
for(row=0;row<M;row++) {
for(col=0;col<N;col++){
printf("%d ",a[row][col]);
}
printf(" EOR\n");
}
DFS(a,0,0);
printf("number of paths is %d\n", count);
return 0;
}
Try this function its a preliminary step before printing all the paths.
If the size of the vector Out is 0 then the # of paths are 0, but if size(Out) > 0 then the size of vector Nodes + 1 are the total number of paths from top left to bottom right.
#include <iostream>
#include <vector>
using namespace std;
typedef vector<pair<int,int> > vPii;
bool pathTL2BR( int Arr2D[][4], vPii &Out, vPii &Nodes,
int _x,int _y, int _M, int _N)
{
bool out1 = false;
bool out2 = false;
if( Arr2D[_x][_y] == 1 )
{
if( _y+1 < _N )
out1 = pathTL2BR( Arr2D, Out, Nodes, _x, _y+1, _M, _N);
if( _x+1 < _M )
out2 = pathTL2BR( Arr2D, Out, Nodes, _x+1, _y, _M, _N);
if( (out1 || out2) ||
( (_x == (_M-1)) && (_y == (_N-1)) ) )
{
if(out1 && out2)
Nodes.push_back( make_pair(_x,_y ) );
Out.push_back( make_pair(_x,_y ) );
return true;
}
else
return false;
}
else
return false;
}
// Driver program to test above function
int main()
{
int Arr2D[][4] = {
{1,1,1,1},
{0,1,0,1},
{0,1,0,1},
{0,1,0,1}
};
vPii Out;
vPii Nodes;
vector<vPii> Output;
pathTL2BR( Arr2D, Out, Nodes, 0, 0, 4, 4);
return 0;
}
This is a python solution, I have put explanations in the comments.
def find_num_paths(arr_2D, i, j):
# i,j is the start point and you have to travel all the way back to 0,0
if i == j and i == 0:
return 1 # you have reached the start point
if i < 0 or j < 0 or arr_2D[i][j] == 0: # out of range or no path from that point
return 0
if arr_2D[i][j] == 1:
return find_num_paths(arr_2D, i, j-1) + find_num_paths(arr_2D, i-1, j) + find_num_paths(arr_2D, i-1, j-1) # you could go one step above, to the left or diagonally up.