8Queen code not working - c

I have been trying to debug this code I made, it outputs only 1's in the first row of the array and all other elements are zero(from second row till the last element.), is it the problem of function calling of passing the array by value or something else. Help appreciated.
#include<stdio.h>
#include<stdlib.h>
int isSafe(int x, int y, int a[][8])
{ int i,j;
//for left check of the cols
for(i=0;i<y;i++)
{
if(a[x][i]==1)
return 0;
}
//for check of left upper diagonals
for (i = x, j = y; i >= 0 && j >= 0; i--, j--)
{
if(a[i][j]==1)
return 0;
}
//for check of left lower diagonals
for(i = x, j = y; i<=7 && j>=0; i++,j--)
{
if(a[i][j]==1)
return 0;
}
return 1;
}//close isSafe
int EQueen(int a[][8], int q)
{
int c=0;
if(q==8)
return 1;
else
{
while(c<=7)
{
if(isSafe(q,c,a)==1)
{
a[c][q] = 1;
if(EQueen(a,q+1)==1)
return 1;
else
a[c][q] = 0;
}//close if
c++;
}//close while
return 0;
}//close else
}//close EQueen
int main()
{
int i,j,chess[8][8] = {[0 ... 7][0 ... 7] = 0};
if(EQueen(chess,0)==1)
{
for(i=0;i<8;i++)
{
for(j=0;j<8;j++)
printf("%d ",chess[i][j]);
printf("\n");
}
}
return 0;
}//close main

Your code is good in principle. You just have to take care to use the same indexing for rows and cols throughout. The way you print the board, you use chess[row][col].
Choose a consistent nomenclature of x, i, c and so on, and you will see that you got your indexing wrong when you check the board. Change the call to IsSafe to
if (isSafe(c, q, a) == 1) ...
and it will work.
(By the way, the array is passed by reference, thus reflecting the changes you make. No problem here.)

I believe it is because your c variable is not incrementing. This is due to how you recursively call your EQueen function.
if(q==8)
return 1;
When your q variable is equal to 8, that specific call for that function call of EQueen will return 1. After that, all the preceding function calls of EQueen will then be true for the if statement because they will all backtrack and return the value 1 and exit that instance of the function call.
if(EQueen(a,q+1)==1)
return 1;
else ...
This makes it so your isSafe function only looks at the 0th row (c = 0) because your c variable does not increment to check all spaces within the 2x2 dimensional array due to EQueen exiting the function before it can loop.

Related

Learning C: if and functions not executing in loop

I have started relearning C (self study), and ran into a problem with an if statement not always executing inside of a loop. What's odd is that on it's own, the function executes correctly, but unless I add a printf() statement referencing the variable in the loop then it won't attempt to test the if statement.
Specifically, the line printf("%d ", aCounter); in the while loop in the main(void) function is what's required for it to attempt test the if statement. I had a similar problem using a for loop (as you can see it's commented out). I am confused as to why it doesn't test the if statement without the printf() mentioned. And yet it does successfully find: 1, 6, 24, 28, and 496 with the printf() statement. It only finds "1" without it.
#include <stdio.h>
int isPerfect(unsigned int n);
int main(void) {
/* for (unsigned int i = 1; i <= 1000; i++) {
if (isPerfect(i) == 1) {
printf("%d is perfect\n", i);
}
}
*/
int aCounter = 0;
while (aCounter < 1000) {
aCounter++;
if (isPerfect(aCounter) == 1 ) {
printf("%d is perfect\n", aCounter);
for (int aTemp = 1; aTemp < aCounter; aTemp++) {
if (aCounter % aTemp ==0) {
printf("%d is a factor of %d\n", aTemp, aCounter);
}
}
}
printf("%d ", aCounter);
//aCounter++;
}
int a = 6;
if (isPerfect(a) == 1 ) {
printf("%d is perfect\n", a);
}
printf("%d is perfect: %d\n", 6, isPerfect(6));
printf("%d is NOT perfect: %d\n", 8, isPerfect(8));
printf("%d is perfect: %d\n", 6, isPerfect(6));
}
int isPerfect(unsigned int n) {
int aNumber;
for (int i =1; i <= n; i++) {
if (n % i == 0) {
aNumber += i;
if (aNumber == n)
{
return 1;
}
}
}
return 0;
}
I'm not sure about the expected output of your program, but I can see that inside the isPerfect(unsigned int n) function, we have a statement aNumber += i; which basically does is aNumber = aNumber + 1;, i.e, update the value of aNumber by 1. But as we can see, in the very first statement inside this function where aNumber is defined, it isn't initialized, so updating its value to 1 seems pointless as it's previous value is unknown. Initializing its value , let's say int aNumber = 0;
will do the job.
But uninitialized variable in C need not always contain a garbage value.
automatic (local) variables are not guaranteed to be zero, can contain
garbage but global variables and static variables are guaranteed to be
zero
please refer to this post StackOverflow post for more details.
.

Need to generate 4 random numbers without repetition in C programming. 1 to 4

I want to generate numbers 1 to 4 in a random fashion using C programming.
I have made provision to print a[0] directly in a while loop and for any further element the program checks whether the new number from a[1] to a[3] is same as any of the previous elements. A function has been created for the same. int checkarray(int *x, int y).
The function checks current element with previous elements one by one by reducing the passed address. If it matches the value it exits the loop by assigning value zero to the condition variable (int apply).
return apply;
In the main program it matches with the int check if check==1, the number is printed or else the loop is repeated.
Problem faced: The number of random numbers generated is varying between 2 and 4.
e.g
2 4
2 4 3
1 3 3 4
etc
Also repetition is there sometimes.
#include <stdio.h>
#include <conio.h>
int checkarray(int *x, int y);
void main() {
int a[4], i = 0, check;
srand(time(0));
while (i < 4) {
a[i] = rand() % 4 + 1;
if (i == 0) {
printf("%d ", a[i]);
i++;
continue;
} else {
check = checkarray(&a[i], i);
}
if (check == 1) {
printf("\n%d ", a[i]);
} else {
continue;
}
i++;
}
getch();
}
int checkarray(int *x, int y) {
int arrcnt = y, apply = 1, r = 1;
while (arrcnt > 0) {
if (*x == *(x - 2 * r)) {
apply = 0;
exit(0);
} else {
arrcnt--;
r++;
continue;
}
}
return apply;
}
Let's look at the checkarray function, which is supposed to check if a number is already present in the array.
It is called this way:
check = checkarray(&a[i], i);
Where a is an array of 4 integers and i is the actual index, so it tries to scan the array backwards looking for any occurrences of a[i]
int checkarray(int *x,int y)
{
int arrcnt=y,apply=1,r=1;
while(arrcnt>0)
{
if(*x==*(x-2*r))
// ^^^ Why? This will cause an out of bounds access.
{
apply = 0;
exit(0); // <-- This ends the program. It should be a 'break;'
}
else
{
arrcnt--;
r++;
continue;
}
}
return apply;
}
Without changing the interface (which is error prone, in my opinion) it could be rewritten as
int check_array(int *x, int y)
{
while ( y )
{
if ( *x == *(x - y) )
return 0;
--y;
}
return 1;
}
Testable here.
There are many other issues which should be addressed, though, so please, take a look to these Q&A too.
Does "n * (rand() / RAND_MAX)" make a skewed random number distribution?
Why do people say there is modulo bias when using a random number generator?
Fisher Yates shuffling algorithm in C
int main() vs void main() in C
Why can't I find <conio.h> on Linux?
Your approach is tedious but can be made to work:
there is no need to special case the first number, just make checkarray() return not found for an empty array.
you should pass different arguments to checkarray(): a pointer to the array, the number of entries to check and the value to search.
you should not use exit(0) to return 0 from checkarray(): it causes the program to terminate immediately.
Here is a modified version:
#include <stdio.h>
#include <conio.h>
int checkarray(int *array, int len, int value) {
int i;
for (i = 0; i < len; i++) {
if (array[i] == value)
return 0;
}
return 1;
}
int main() {
int a[4], i = 0, value;
srand(time(0));
while (i < 4) {
value = rand() % 4 + 1;
if (checkarray(a, i, value)) {
printf("%d ", value);
a[i++] = value;
}
}
printf("\n");
getch();
return 0;
}

Issue with returning an array of type int from function

I have read through a lot of posts giving ways in which you can return an array of type int from a function. I have attempted to follow the approach of dynamically allocating the memory inside of the function using the malloc() function.
In the example code, I am using a function foo which calculates peaks in an array which are greater than a specified value.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* function declaration */
int *foo(int arr[],int size);
int main()
{
int test[] = {1,2,1,4,5,2,7,8,9,1}; //array of test data.
int *p;
p = foo(test,10);
int w;
for(w=0;w<5;w++)
{
printf(" Peak %d\t",p[w]); // This line is giving a non sensible answer.
}
free(p); // free the memory
return 0;
}
int *foo(int arr[],int size) {
int j;
int Peak_min = 3; // Minimum peak height
int *ret = malloc(size * sizeof(*ret));
if(!ret) return 1;
for (j = 0; j < size -1; ++j)
{
if ( (arr[j] < arr[j+1]) && (arr[j+1] > arr[j+2]) && (arr[j+1] > Peak_min))// Peak criteria
{
ret[j] = arr[j+1];
printf(" Peak_No %d",ret[j]); // This line is giving the correct output.
}
}
return ret;
}
The output printed in the function gives 5 and 9, as expected. However, the output when I call the function in int main() gives non-sensible values. I am struggling to find the error with my code, any suggestions on how I can debug/fix this?
Update
I edited the for loop in the fucntion foo to
for (j = 0; j < size -2; ++j)
{
if ( (arr[j] < arr[j+1]) && (arr[j+1] > arr[j+2]) && (arr[j+1] > Peak_min))// Peak criteria
{
ret[j] = arr[j+1];
printf(" Peak_No %d",ret[j]); // This line is giving the correct output.
}
else
{
ret[j] = 0;
}
}
I am now getting the output I wanted.
malloc() returns unitialized memory.
Inside the function, the assignment of ret[j] is conditional. You never know for sure that which or any index element is actually initialized. After returning the pointer, you unconditionally index into the pointer any to read the values which may be very well unitialized.
In case, you are returning the pointer with the same assignment condition, you can at least use calloc() which returns 0-filled memory, so at least, you have a deterministic value. However, this will fail to differentiate between a left-over index element and an element actually having a value of 0. For better precision, you can memset() the malloc()-ed memory to some guard value which indicates that those node values are not assigned.
Also, another quickfix would be, add one else condition which basically helps to unconditionally assign a value to each element.
Seems the loop must be:
int k= 0;
for (j = 0; j < size -2; ++j)
{
if ( (arr[j] < arr[j+1]) && (arr[j+1] > arr[j+2]) && (arr[j+1] > Peak_min))// Peak criteria
{
ret[k++] = arr[j+1];
}
}
ret[k]= 0;
return ret;
}
and in main:
int w= 0;
while (p[w]) printf(" Peak %d\t",p[w++]);
This creates a list of peaks, terminated with a null entry.

Nested for loops in C

I'm try to complete a task set by a lecturer and I have the following code:
#include <stdio.h>
#define N 100
int main(void)
{
int i, a, cnt = 1;
for (a = 1; a < 6; a++){
for (i = 0; i < N; i++, cnt++) {
if (a%2 > 0){
a = 3*a + 1;
}
else{
a = (a/2);
}
printf("%3d\n", a);
if (a == 1){
printf("Count: %d\n", cnt);
return 0;
}
}
}
return 0;
}
The point of this code is to run a hailstone sequence on each integer, a. For now I have it to start at a = 1, then adding 1 to a, and running the sequence again up until a = 5.
This code runs it for the initial value of a but doesn't then add one to a to run it again. I really can't see why it won't do the outer loop again, please help!
A hailstone sequence is where it takes the integer before it in the sequence, if this integer is odd it computes 3*a +1, and if the integer is even it computes a/2. I've told the sequence to stop once a = 1.
Thanks in advance!!
Instead of return 0; in second loop add break; to move out of the inner loop and continue with outer loop.
If you don't want to add break this is another way and there are minor changes in your code which I have highlighted below.
1. You will have to reinititlize cnt for every new value of a.
2. You will have to take a new variable instead of a for calculations
3. For moving out of loop you can increase value of i.
#include<stdio.h>
int main()
{
int i, a, cnt=1, b;
for(a=1; a<6; a++){
cnt = 1;
b = a;
for(i=0; i<100; i++, cnt++){
if(b%2 > 0){
b = 3*b + 1;
}
else{
b = b/2;
}
printf("%d ", b);
if(b==1){
printf("\nCount %d\n", cnt);
i = 100;
}
}
}
return 0;
}
I'm only a student too, but try removing the first "return 0;", I think that's what is ending the code early.
return will end the function. I think what you are looking for is break

Controlled nested looping

I have the nested loops that nested (r=) 3 times. Each loop running for (n=) 5 times.
for (i=0; i<n; i++)
{
for (j=0; j<n; j++)
{
for (k=0; k<n; k++)
//
}
}
But how do we do the nesting dynamically at run time. Say we know it should be nested r times. Each loop running n times. I thought something like recursion but it goes indefinitely.
funloop (int r)
{
for (int i = 0; i < n; i++)
{
//
if (r < 3)
funloop (r++);
else
return;
}
}
Please let me know how this could be done? I couldn't find a sources online.
If you don't know the depth of the recursion statically, the most common approach is to use recursion to represent the looping. For example, suppose that you need to have d levels of nesting of loops that all need to iterate k times. Then you could implement that using recursion of this form:
void RecursivelyNestIterations(unsigned d, unsigned k) {
/* Base case: If the depth is zero, we don't need to iterate. */
if (d == 0) return;
/* Recursive step: If we need to loop d times, loop once, calling the
* function recursively to have it loop d - 1 times.
*/
for (unsigned i = 0; i < k; ++i) {
/* Recurse by looping d - 1 times using the same number of iterations. */
RecursivelyNestIterations(d - 1, k);
}
}
Hope this helps!
The simplest method is just to collapse it to one for loop:
for(i=0; i<pow(n, r); i++) {
}
That can however make it difficult to access the loop counters, if you need them, but that can be done mathematically. For example, the innermost loop counter variable value is given by :
int c = i % n;
You could have an array of such counters and determine the values with similar equations, or you can just increment them, when required, e.g.:
void iterate(int r, int n) {
int i, rc, *c = malloc(sizeof(int) * r);
memset(c, 0, sizeof(int) * r);
for(i = 0; i < pow(n, r); i++) {
// code here, using loop counters in the 'c' array, where c[0] is counter
// for the outer loop, and c[r - 1] is the counter for the innermost loop
// update the counters
rc = r;
while(rc > 0) {
rc--;
c[rc]++;
if(c[rc] == n) {
c[rc] = 0;
} else {
break;
}
}
}
free(c);
}
Just call if (r) funloop(r-1); in the loop body.
#include <stdlib.h>
#include <stdio.h>
static int n = 3;
void _funloop(int cur,int total)
{
if(cur!=total)
{
for(int cnt=0;cnt!=n;++cnt)
{
fprintf(stdout,"%d::%d\n",cur,cnt);
}
_funloop(cur+1,total);
}
}
void funloop(int total)
{
_funloop(0,total);
}
int main()
{
funloop(10);
return 0;
}
A solution that doesn't use recursion is discussed in this Tip
[link]http://www.codeproject.com/Tips/759707/Generating-dynamically-nested-loops
The code is in C++ and require # for the include and define statements
include <iostream>
define MAXROWS 9
define MAXVALUES 9
using namespace std;
char display[] = {'1','2','3','4','5','6','7','8','9'};
int main() {
int arrs[MAXROWS]; // represent the different variables in the for loops
bool status = false;
for (int r=0;r<MAXROWS;r++)
arrs[r] = 0; // Initialize values
while (!status) {
int total = 0;
// calculate total for exit condition
for (int r=0;r<MAXROWS;r++)
total +=arrs[r];
// test for exit condition
if (total == (MAXVALUES-1)*MAXROWS)
status = true;
// printing
for (int r=0;r<MAXROWS;r++)
cout << display[arrs[r]]; // print(arrs[r])
cout << endl; // print(endline)
// increment loop variables
bool change = true;
int r = MAXROWS-1; // start from innermost loop
while (change && r>=0) {
// increment the innermost variable and check if spill overs
if (++arrs[r] > MAXVALUES-1) {
arrs[r] = 0; // reintialize loop variable
// Change the upper variable by one
// We need to increment the immediate upper level loop by one
change = true;
}
else
change = false; // Stop as there the upper levels of the loop are unaffected
// We can perform any inner loop calculation here arrs[r]
r=r-1; // move to upper level of the loop
}
}

Resources