Why is following code throwing runtime error, even when it shows desired output?

62 views Asked by At

I am solving the 8 queen problem using backtracking. When I compiled the following code in codechef IDE, it showed correct output, but still it shows runtime error.

#include <stdio.h>
#include <math.h>
int board[8][8] = { { 0 } };
int demi[8][8] = { { 0 } };
int queen(int a, int b, int c);
void mark(int a, int b);
int main()
{
    int i;
    int b = queen(3, 0, 0);
    for (i = 0; i < 64; i++)
    {
        int x = board[i / 8][i % 8];
        if (x == 1)
            printf(" %d ", x);
        else
        {
            printf(" 0 ");
        }
        if ((i + 1) % 8 == 0)
            printf("\n");
    }
}
int queen(int a, int b, int c)
{
    int t;
    if (c == 8)
        return 1;
    if (a < 0 || a > 7 || b < 0 || b > 7)
        return 0;
    if (!(board[a][b] == 0))
        return 0;
    for (t = 0; t < 64; t++)
    {
        demi[t / 8][t % 8] = board[t / 8][t % 8];
    }
    mark(a, b);
    board[a][b] = 1;
    /*  for(t = 2; t<8; t++)
     {
     if(queen(a+(9-t), b+1, c+1))
     return 1;
     if(queen(a-t, b+1, c+1))
     return 1;
     }*/
    if (queen(a + 7, b + 1, c + 1))
        return 1;
    if (queen(a + 6, b + 1, c + 1))
        return 1;
    if (queen(a + 5, b + 1, c + 1))
        return 1;
    if (queen(a + 4, b + 1, c + 1))
        return 1;
    if (queen(a + 3, b + 1, c + 1))
        return 1;
    if (queen(a + 2, b + 1, c + 1))
        return 1;
    if (queen(a - 2, b + 1, c + 1))
        return 1;
    if (queen(a - 3, b + 1, c + 1))
        return 1;
    if (queen(a - 4, b + 1, c + 1))
        return 1;
    if (queen(a - 5, b + 1, c + 1))
        return 1;
    if (queen(a - 6, b + 1, c + 1))
        return 1;
    if (queen(a - 7, b + 1, c + 1))
        return 1;
    board[a][b] = 0;
    for (t = 0; t < 64; t++) {
        board[t / 8][t % 8] = demi[t / 8][t % 8];
    }
    return 0;
}
void mark(int a, int b)
{
    int i;
    for (i = 0; i < 64; i++)
    {
        int row = i / 8;
        int col = i % 8;
        if (row == a || col == b && !(row == a && col == b))
            board[row][col] = 2;
        if (abs(row - a) == abs(col - b))
            board[row][col] = 2;
    }
}

Output :

enter image description here

Moreover, if I change the driver statement to "queen(0,0,0) or queen(1,0,0)", The result is well correct upto 4-5 columns, but is full of 0s in the remaining ones.

enter image description here

Where am I going wrong?

2

There are 2 answers

5
Jean-François Fabre On

just look at your main routine:

int main()
{
    ...
    if((i+1)%8==0)
    printf("\n");
}

it is supposed to return 0 on successful completion, but you don't return anything: so even if your program does what you want, since your return code is undefined.

Not likely to be 0 in that case => seen as wrong execution by the engine executing it, which doesn't even try to go further into analysing program output.

Fix (even if C99 makes it default, compiling with old C89 could yield undefined results):

    if((i+1)%8==0)
    printf("\n");
    return 0;
}

As several people commented, the return 0 statement is not mandatory in C99. But I suppose that your on-line platform enforces strict C89 rules so you have to add it.

0
Armali On

Moreover, if I change the driver statement to "queen(0,0,0) or queen(1,0,0)", The result is well correct upto 4-5 columns, but is full of 0s in the remaining ones.

There's a small, but impactful oversight: The array demi to store the board state of a previous instance in the recursion chain of queen() is defined globally; hence, recursive calls of queen() overwrite the saved state of former invocations, foiling the backtracking. Your program works if demi is defined locally in queen().


Regarding the program's exit status, the value of b at the end of main() lends itself to be used in return !b;, since the value 1 returned from queen() denotes success.