Queen puzzle 4x4 - c

I am trying to solve this Queen problem of placing 4 queen in 4x4 matrix . I know it can be solved with backtracking algorithm . However i have not studied that and i am trying to solve it with my current knowledge . So what i am trying is to generate all possible combination of Queen in 4x4 matrix and print only one which cannot cancel each other .
1) For generating all combination , i am using rand function .
However there is obviously fault in my above coding . There are some outputs with only three '1' instead of four '1' . I am not able to eliminate this problem .
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
main()
{
srand(time(NULL));
int ar[30][30], i , j , a , b , c = -1, d = -1, k = 0;
while (1)
{
for (i = 0 ; i < 4 ; i++)
{
for (j = 0 ; j < 4 ; j++)
{
ar[i][j] = 0;
}
}
for (i = 0 ; i < 2 ; i++)
{
for (j = 0 ; j < 2 ; j++)
{
a = rand() % 3 ;
b = rand() % 3 ;
if (a != c || b != d)
{
ar[a][b] = 1 ; // here 1 = Queen
c = a ;
d = b;
}
}
}
}
}
2) Also is there any way i can reduce the time complexity using only these method ?

Instead of using temporary variables to check whether the array is filled, use the array itself!
for (i = 0 ; i < 2 ; i++)
{
for (j = 0 ; j < 2 ; j++)
{
a = rand() % 3 ;
b = rand() % 3 ;
if (ar[a][b] == 0)
{
ar[a][b] = 1 ; // here 1 = Queen
}
}
}
Your problem is that the inner loop will execute 4 times and you can only control 1 repeat with variables c and d.
Let's say a is 1 and b is 1: you make c = 1 and d = 1.
then a is 2 and b is 1 ... making c = 2 and d = 1.
then if a is 1 and b is 1 again, you cannot check for duplicate.

(1) You check only that a queen isn't placed on the same square as the last queen you placed. Remove the variables c and d and check whether ar[a][b] is still zero.
(2) Your scatter approach will produce many set-ups that are misses. Especially, because you don't enforce that ther cannot be any queens on the same rank and file. (In addition, rand() % 3 produces random values from 0 to 2, inclusively. You will never get a non-threatening configuration that way.)
If you want to use your random (bogosort) approach, you could use a one-dimensional array where the index is the rank and the number is the file where a queen is. Then you start with:
int queen[4] = {0, 1, 2, 3};
and shuffle the array. For 4 queens, that will yield 4! = 24 possibile configurations. You could try to iterate through them systematically.

The following is the brute force, backtracking code for the 8 queens problem, asked some time ago. Just change 8 to 4:
int checkBoard(int board[8][8]);
int putQueens(int board[8][8], int nQueens);
void printBoard(int board[8][8]);
int eightQueens(void)
{
int board[8][8];
memset(board, 0, sizeof(int)*64);
if (putQueens(board, 0)) {
printBoard(board);
return (1);
}
return(0);
}
int putQueens(int board[8][8], int nQueens)
{
int i, j;
for (i=0; i<8; i++) {
for (j=0; j<8; j++) {
if (board[i][j]==0) {
board[i][j]= 1;
if (checkBoard(board)) {
if (nQueens==7) return(1);
if (putQueens(board, nQueens+1)) return(1);
}
board[i][j]= 0;
}
}
}
return(0);
}
int checkBoard(int board[8][8])
{
int i, j;
for (i=0; i<8; i++) {
for (j=0; j<8; j++) {
if (board[i][j]) {
int ii, jj;
for (ii=i+1; ii<8; ii++) {
if (board[ii][j]) return(0);
}
for (jj=j+1; jj<8; jj++) {
if (board[i][jj]) return(0);
}
for (ii=i+1, jj=j+1; ii<8 && jj<8; ii++, jj++) {
if (board[ii][jj]) return(0);
}
for (ii=i-1, jj=j-1; ii>0 && jj>0; ii--, jj--) {
if (board[ii][jj]) return(0);
}
for (ii=i-1, jj=j+1; ii>0 && jj<8; ii--, jj++) {
if (board[ii][jj]) return(0);
}
for (ii=i+1, jj=j-1; ii<8 && jj>0; ii++, jj--) {
if (board[ii][jj]) return(0);
}
}
}
}
return (1);
}
void printBoard(int board[8][8])
{
int i,j;
printf(" ");
for (j=0; j<8; j++) printf(" %1d",j+1); printf("\n");
for (i=0; i<8; i++) {
printf("%1d ",i+1);
for (j=0; j<8; j++)
printf(" %1c", board[i][j]==0? '-':'*');
printf("\n");
}
}

Related

Checking whether a number exist in the same row or column matrix

I want to output Yay if the matrix doesn't contain the same number on the same row or column otherwise output Nay
this is for my college homework. I already tried to check the column and row in the same loop but the output still not right
#include <stdio.h>
int main()
{
int size;
int flag;
scanf("%d",&size);
char matrix[size][size];
for (int i = 0; i < size; i++)
{
for (int l = 0; l < size; l++)
{
scanf("%s",&matrix[i]);
}
}
for (int j = 0; j < size; j++){
for (int k = 0; k < size; k++){
if(matrix[j] == matrix[j+1] || matrix[j][k]==matrix[j][k+1])
{
flag = 1;
}
else
{
flag = 0;
}
}
}
if (flag == 1)
{
printf("Nay\n");
}
else
{
printf("Yay\n");
}
return 0;
}
I expect to output "Nay" when I input
3
1 2 3
1 2 3
2 1 3
and "Yay" when i input
3
1 2 3
2 3 1
3 1 2
Your matrix is a 2D array and you are referencing it using only a single subscript matrix[index] at several places which returns the address of the row. Index it using both the row and column indices. Try the code below:
{
int size;
int flag;
scanf("%d",&size);
char matrix[size][size];
for (int i = 0; i < size; i++)
{
for (int l = 0; l < size; l++)
{
scanf("%s",&matrix[i][l]);
}
}
for(int j = 0; j < size; j++){
for (int k = 0; j < size; j++){
if(matrix[j][0]== matrix[j][k] || matrix[k][0]==matrix[k][j])
{
flag = 1;
break;
}
else
{
flag = 0;
}
}
}
if (flag == 1)
{
printf("Nay\n");
}
else
{
printf("Yay\n");
}
return 0;
}
Your have a logic problem. Your flag is reset on every element in the matrix and thus only reflects the result of the last check.
In addition, you need a break; in your nested loop. The logic is, if your flag becomes 1, you are sure to say Nay, and you don't want the flag to be reset to 0.
int flag = 0;
for (int i = 0; i != size && !flag; ++i) {
for (int j = 0; j != size; ++j) {
if ( /* detection */ ) {
flag = 1;
break;
}
}
}
if (flag)
printf("Nay\n");
else
printf("Yay\n");
Note: The commented /* detection */ part requires more work. Since it's your homework, you may try it first. You could use a hash table for memorization. Or brutal force to make the program simply work. It seems that your detection only checks for neighboring elements, which is not sufficient to assert that an element is unique in its row or column. Consider
1 2 1
3 4 5
6 7 8
I can't do your homework for you. The following is the brutal-force way you may consider.
The if ( /* detection */ ) part could be if (has_same_element(matrix, i, j)), with a function (pseudo code)
int has_same_element(matrix, row, col)
{
for each element a in matrix's row except matrix[row][col] itself
if (a == matrix[row][col])
return 1
for each element b in matrix's col except matrix[row][col] itself
if (b == matrix[row][col])
return 1
return 0
}
Of course there are smarter ways, like using a hash table, in which case you don't even need the nested loop. For the time being, work out a feasible solution, instead of the best solution.

how to check if a matrix has the same value in a row or column in C

I have a homework problem. It requires us to make a matrix based on user's input. For example : if user input 4 so the matrix will be 4 X 4. After that, the program will check if the matrix has the same value in a row or column. and it will give yes or no output.
For example :
input :
2
1 2
2 1
Output :
Yes
(because that matrix doesnt has a same value in a row or a column.)
Input 2 :
3
4 5 6
7 8 9
7 3 3
Output :
No
(Because that matrix have same values in a row or column (3 & 3 and 7 & 7)
Input 3:
2
1 2
3 2
Output :
No
(because that matrix have same value on column 1.)
Input 4
2
1 1
3 4
Output :
No
(because that matrix has same value in first row(1 1)
I have tried to do that, but some 'cases' still doesnt work. For example, i tried to include a count in my code but some of the count is not true.
example :
input :
4
3 4 5 6
2 3 4 5
6 5 6 3
5 4 6 3
OUTPUT :
No
count : 2
(it supposed to be 3 because it has the same value which are 6 (on row 3), 6 on column 3, and 3 on column 4.)
#include "stdio.h"
int main()
{
int matrix[500][500];
int testcase;
int count = 0;
scanf("%d",&testcase); getchar();
for(unsigned i = 0; i < testcase; i++) {
for(unsigned j = 0; j < testcase; j++) {
scanf("%d",&matrix[i][j]); getchar();
}
}
// printf("[0,0] = %c",matrix[0][0]);
// printf("\n[0,1] = %c",matrix[0][1]);
// printf("\n[1,0] = %c",matrix[1][0]);
// printf("\n[1,1] = %c",matrix[1][1]);
for(unsigned i = 0; i < testcase; i++) {
for(unsigned j = 0; j < testcase; j++) {
if(matrix[i][j] == matrix[i][j+1]) {
count = count + 1;
}
else if(matrix[i][j] == matrix[i+1][j]) {
count = count + 1;
}
}
}
if(count > 0) {
printf("No\n");
} else{
printf("Yes\n");
}
printf("Count : %d\n",count );
getchar();
return 0;
}
As I see you check if 2 numbers of the same value differ only one column or one row here:
if(matrix[i][j] == matrix[i][j+1]) {
count = count + 1;
}
else if(matrix[i][j] == matrix[i+1][j]) {
count = count + 1;
}
I think that you might need a temp variable so that you can scan each line and then each column separately , for example:
temp = matrix[i][j];
if(checkRow(temp, i, j, matrix, testcase) == true) count++;
if(checkColumn(temp, i, j, matrix, testcase) == true) count++;
and the checkRow would be something like this:
bool checkRow(int temp, int row, int col, int matrix[][500], int size)
{
for(int i=col; i < size;)
{
if(temp == matrix[row][i]) return true;
}
return false;
}
and respectively you will build the checkColumn function.
EDIT:
Since you told me you haven't learned how to use functions yet, this would be your final program. It works and I might suggest that the final test case should output "count = 4" since there is a case that you might missed.
Here is the code:
#include "stdio.h"
int main()
{
int matrix[500][500];
int testcase;
int count = 0;
scanf("%d",&testcase); getchar();
int temp;
for(unsigned i = 0; i < testcase; i++) {
for(unsigned j = 0; j < testcase; j++) {
scanf("%d",&matrix[i][j]); getchar();
}
}
// printf("[0,0] = %c",matrix[0][0]);
// printf("\n[0,1] = %c",matrix[0][1]);
// printf("\n[1,0] = %c",matrix[1][0]);
// printf("\n[1,1] = %c",matrix[1][1]);
for(unsigned i = 0; i < testcase; i++) {
for(unsigned j = 0; j < testcase; j++) {
temp = matrix[i][j];
//Scan current row
for(unsigned k = j+1; k < testcase; k++)
{
if(temp == matrix[i][k])
{
count++;
break;
}
}
//Scan current column
for(unsigned k = i+1; k < testcase; k++)
{
if(temp == matrix[k][j])
{
count ++;
break;
}
}
}
}
if(count > 0) {
printf("No\n");
} else{
printf("Yes\n");
}
printf("Count : %d\n",count );
getchar();
return 0;
}
May I suggest that before you copy the code you must understand the algorithm that lies behind it. It's simple and brute force thinking.

Issues involving a function with an array (For task calculating matrix determinants)

I'm having issues getting a function to work which should find the determinant of an upper triangular matrix. My code seems to return clearly incorrect values, usually zero and I'm pretty certain that this is caused by me defining the function incorrectly some how. I suspect it is a basic error on my part but after staring at it for sometime I havent managed to figure it out. Here is the function and printing code:
int Determinant(int mat[20][20],int N)
{
int X=0,Det=0;
if (N==2){
Det=mat[0][0]*mat[1][1]-mat[0][1]*mat[1][0];
return(Det);
}
else {
for(X = 0; X < N; X++){
Det *= mat[X][X];
}
}
return (Det);
}
and the print function :
determinant=Determinant(matrix,n);
printf("Determinant = %d",determinant);
I'll include the full code that I've written so far to provide more detail. It's basic application at the moment is to define and n by n matrix (2
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int determinant(int mat[20][20],int N);
int Determinant(int mat[20][20],int N)
{
int X=0,Det=0;
if (N==2){
Det=mat[0][0]*mat[1][1]-mat[0][1]*mat[1][0];
return(Det);
}
else {
for(X = 0; X < N; X++){
Det *= mat[X][X];
}
}
return (Det);
}
int main()
{
int n=0,i=1;
printf("Please enter a number (n) between 2 and 4 to determine the dimensions of an (nxn) matrix \n");
scanf("%d",&n);
while(n<2||n>4){
printf("The value %d does not lie within the required range of 2-4, please re-enter \n",n);
scanf("%d",&n);
i++;
if (i>=3){
printf("\nYou have entered invalid values 3 times. The programme has been terminated");
exit(0);
}
}
printf("\n(%dx%d) matrix selected\n",n,n);
int matrix[n][n];
int f,g=0;
printf("Please enter matrix elements\n");
for(f=0;f<n;f++){
for(g=0;g<n;g++){
printf("Element[%d][%d] = ",f,g);
scanf("%d",&matrix[f][g]);
}
}
int k,j;
printf("\nThe matrix is\n");
for(k=0;k<n;k++){
printf("\n");
for(j=0;j<n;j++){
printf("%d\t",matrix[k][j]);
}
}
int temp=0,c=0,determinant=0;
float factor=0;
k=0;
/* Transform matrix into upper triangular */
for(i = 0; i < n - 1; i++)
{
/* Elementary Row Operation I */
if(matrix[i][i] == 0)
{
for(k = i; k < n; k++)
{
if(matrix[k][i] != 0)
{
for(j = 0; j < n; j++)
{
temp = matrix[i][j];
matrix[i][j] = matrix[k][j];
matrix[k][j] = temp;
}
k = n;
}
}
c++;
}
/* Elementary Row Operation III */
if(matrix[i][i] != 0)
{
for(k = i + 1; k < n; k++)
{
factor = -1.0 * matrix[k][i] / matrix[i][i];
for(j = i; j < n; j++)
{
matrix[k][j] = matrix[k][j] + (factor * matrix[i][j]);
}
}
}
}
printf("\nThe Upper triangular is\n");
for(k=0;k<n;k++){
printf("\n");
for(j=0;j<n;j++){
printf("%d\t",matrix[k][j]);
}
}
determinant=Determinant(matrix,n);
printf("Determinant = %d",determinant);
/*
*/
return 0;
}
The problem is basically the way you pass the matrix as a parameter. To see what I mean, change the definition of the function to read:
int Determinant(int mat[5][5],int N);
and instruct the function body to print the full 5x5 matrix passed:
int Determinant(int mat[5][5],int N)
{
printf("\n");
int a,b;
for(a = 0; a < 5; a++)
{
for(b = 0; b < 5; b++)
{
printf("%d\t", mat[a][b]);
}
printf("\n");
}
int X=0,Det=0;
Det = 1; // Add this too!
for(X = 0; X < N; X++) {
Det *= mat[X][X];
}
return (Det);
}
Now enter n=3 for the matrix dimension and pass the already upper triangular matrix
1 2 3
0 4 5
0 0 6
Observe the printout of the matrix passed in the Determinant() function, it will be something like this:
1 2 3 0 4
5 0 0 6 0
4196432 0 -163754450 0 -1253168992
32764 3 0 0 0
3 0 0 0 3
This means that your array has been "reshaped", and your actual data are stored in consecutive places in memory, unlike the original array.
TLDR: Although I am not very proficient with C, I think that you should define your 2d array as a dynamic one (for example using a double pointer).
PS: Don't forget to initialize Det variable to 1 instead of 0 in the function body, otherwise the product will always equal 0.

Generate all possible permutations in C

I'm trying to develop a code to solve the Travelling salesman problem in C, but I have some restrictions: I can only use "for, "while", "do", arrays, matrix and simple things like that, so, no functions or recursion (unfortunately).
What I've got so far:
The user will will type the city coordinates X and Y like this:
8.15 1.58
9.06 9.71
1.27 9.57
9.13 4.85
The code to storage the coordinates.
float city[4][2];
int i;
for (i=0; i<4; i++)
scanf("%f %f", &cidade[i][0], &cidade[i][1]);
There are 4 cities, so "i" goes from 0 to 3. X and Y are storaged on the second dimension of the matrix, [0] and [1].
The problem now is that I have to generate ALL POSSIBLE permutations of the first dimension of the matrix. It seems easy with just 4 cities, because all possible routes are (it must starts with city A everytime):
A B C D
A B D C
A C B D
A C D B
A D C B
A D B C
But I'll have to expand it for 10 cities. People have told me that it will use 9 nested foor loops, but I'm not being able to develop it =(
Can somebody give me an idea?
Extending to 10 (and looking up city names) as an exercise for the reader. And it's horrid, but that's what you get with your professor's limitations
#include <stdio.h>
int main(void) {
for (int one = 0; one < 4; one++) {
for (int two = 0; two < 4; two++) {
if (two != one) {
for (int three = 0; three < 4; three++) {
if (one != three && two != three) {
for (int four = 0; four < 4; four++)
if (one != four && two != four && three != four) {
printf("%d %d %d %d\n", one, two, three, four);
}
}
}
}
}
}
return 0;
}
This is based on https://stackoverflow.com/a/3928241/5264491
#include <stdio.h>
int main(void)
{
enum { num_perm = 10 };
int perm[num_perm];
int i;
for (i = 0; i < num_perm; i++) {
perm[i] = i;
}
for (;;) {
int j, k, l, tmp;
for (i = 0; i < num_perm; i++) {
printf("%d%c", perm[i],
(i == num_perm - 1 ? '\n' : ' '));
}
/*
* Find largest j such that perm[j] < perm[j+1].
* Break if no such j.
*/
j = num_perm;
for (i = 0; i < num_perm - 1; i++) {
if (perm[i + 1] > perm[i]) {
j = i;
}
}
if (j == num_perm) {
break;
}
for (i = j + 1; i < num_perm; i++) {
if (perm[i] > perm[j]) {
l = i;
}
}
tmp = perm[j];
perm[j] = perm[l];
perm[l] = tmp;
/* reverse j+1 to end */
k = (num_perm - 1 - j) / 2; /* pairs to swap */
for (i = 0; i < k; i++) {
tmp = perm[j + 1 + i];
perm[j + 1 + i] = perm[num_perm - 1 - i];
perm[num_perm - 1 - i] = tmp;
}
}
return 0;
}

C Programming and Matrix multiplication output issue

I'm currently learning C programming, to better my understanding of matrices in C I've tried to make this program.
I seem to be having problems with the output, as you can see the program has 3 functions.
The first one allows you to input the values for the array and then displays it. The second function performs the multiplication and the last should display the output of the multiplied matrix.
However the output is strange. Here is my code. The output is just below the code.
#include <stdio.h>
void read_matrix(int m2[][3] )
{
int i, j;
printf("input values for matrix in order of rows first \n");
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j++)
{
scanf("%d",&m2[i][j]);
}
}
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j++)
{
printf("%d ", m2[i][j]);
}
printf("\n");
}
}
void multiply_matrices(int m1[][3], int m2[][3] ,int m3[][3])
{
int i, j, k;
for (i = 0; i < 3; i++){
for (j = 0; j < 3; j++){
for (k = 0; k < 3; k++){
m3[i][j] +=m1[i][k]*m2[k][j];
}
}
}
}
void write_matrix(int m3[][3] )
{
int i, j;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j++)
{
printf("%d ", m3[i][j]);
}
printf("\n");
}
}
int main(void)
{
int matrix1[3][3], matrix2[3][3], matrix3[3][3];
read_matrix(matrix1);
read_matrix(matrix2);
multiply_matrices(matrix1, matrix2, matrix3);
write_matrix(matrix3);
return 0;
}
and this is the output!
input values for matrix in order of rows first
1
2
3
2
2
2
1
2
2
1 2 3
2 2 2
1 2 2
input values for matrix in order of rows first
2
1
1
1
2
1
2
1
2
2 1 1
1 2 1
2 1 2
-858993450 -858993452 -858993451 /*This is the multiplied matrix output!*/
-858993450 -858993452 -858993452
-858993452 -858993453 -858993453
Press any key to continue . . .
I fear it may be just a silly mistake; if so I'm sorry, but I can't see where I am going wrong at this moment.
Any help would be greatly appreciated.
You need to initialize all elements of matrix m3 to 0 before performing this operation
m3[i][j] +=m1[i][k]*m2[k][j];
in function multiply_matrices.
Initialize matrix3 in the function multiply matrix like this
for (int i=0;i<3;i++)
{
for (int j=0;j<3;j++)
{
m3[i][j]=0;
}
}
After this, do the multiplication and everything will work perfectly.
int m3[][]={};
It initially stores 0 for all available index of m3

Resources