knights tour code with recursion and backtracking - c

I was recently assigned the knight's tour problem.
Here is my try at it:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
int count = 1;
int movej[8] = {1, -1,-2, 2, -2, -1, 1, 2};
int movei[8] = {2, 2, 1, 1, -1, -2, -2, -1};
void boardprinter(int **board)
{
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
printf("%d ", board[i][j]);
}
printf("\n");
}
printf("\n");
}
_Bool safe(int **board, int i, int j)
{
if ((board[i][j] == (-1)) && i >= 0 && i < 8 && j >= 0 && j < 8)
{
return 1;
}
return 0;
}
_Bool solve(int **board, int si, int sj)
{
if (count == 64)
{
boardprinter(board);
return 1;
}
int i=0;
while(i<8)
{
if (safe(board, (si + movei[i]), (sj + movej[i])))
{
board[si + movei[i]][sj + movej[i]] = count++;
if (solve(board, (si + movei[i]), (sj + movej[i])))
{
return 1;
}
else
{
board[si + movei[i]][sj + movej[i]] = -1;
}
}
i++;
}
return 0;
}
int main()
{
int **board = (int **)malloc(8 * sizeof(int *));
for (int i = 0; i < 8; i++)
{
*(board + i) = (int *)malloc(8 * sizeof(int));
for (int j = 0; j < 8; j++)
{
board[i][j] = -1;
}
}
// board initiallized
int si, sj;
scanf("%d %d", &si, &sj);
board[si][sj] = 1;
count++;
_Bool c = solve(board, si, sj);
printf("%d",c);
return 0;
}
I applied recursion and backtracking in this but the code crashes after reaching (4,2),now I think this fails because the while loop doesn't seem to behave properly (it gets teminated somehow)But I dont know why..
I have been stuck over this and tried all sorts of things to debug this
Kindly help me out!!

Thanks to Mr Tom Karzes for pointing out the mistakes in my code.
Cause of Error
The Problem with my code was that I was indexing into my array before checking if it was out of bounds,i.e. This happened because I assumed that the condition :
(board[i][j] == (-1)) && i >= 0 && i < 8 && j >= 0 && j < 8 would automatically fail if the array was out of bounds, but it turns out that I forgot that the compiler first checks (board[i][j] == (-1)) before checking the next mentioned
conditions,Which was the cause of the undefined behavior of my program.
Fixed Code
Here is the fixed code:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
int count = 0;
int movej[8] = {1, -1,-2, 2, -2, -1, 1, 2};
int movei[8] = {2, 2, 1, 1, -1, -2, -2, -1};
void boardprinter(int **board)
{
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
printf("%d ", board[i][j]);
}
printf("\n");
}
printf("\n");
}
_Bool safe(int **board, int i, int j)
{
if (i >= 0 && i < 8 && j >= 0 && j < 8)
{
if((board[i][j] == (-1)))
{
return 1;
}
}
return 0;
}
_Bool solve(int **board, int si, int sj)
{
if (count == 64)
{
boardprinter(board);
return 1;
}
int i=0;
while(i<8)
{
if (safe(board, (si + movei[i]), (sj + movej[i])))
{
board[si + movei[i]][sj + movej[i]] = count++;
if (solve(board, (si + movei[i]), (sj + movej[i])))
{
return 1;
}
else
{
board[si + movei[i]][sj + movej[i]] = -1;
count--;
}
}
i++;
}
return 0;
}
int main()
{
int **board = (int **)malloc(8 * sizeof(int *));
for (int i = 0; i < 8; i++)
{
board[i] = (int *)malloc(8 * sizeof(int));
for (int j = 0; j < 8; j++)
{
board[i][j] = -1;
}
}
// board initiallized
int si, sj;
scanf("%d %d", &si, &sj);
board[si][sj] = 0;
count++;
_Bool c = solve(board, si, sj);
printf("%d",c);
return 0;
}

Related

the 8 in my 4*4 matrix gets turned to 0 automatically while executing this program

This is the 15 puzzle that I'm programming with the initial configuration already given to us.
Here, I have considered the hole as the number 0.
Note: I have done the changes given in the comments but still this problem of printing twice exists.
I corrected the bounds of the array, and replaced the ASCII values with their corresponding character, and made functions to make it more compact, but I don't get why is it printing twice..
Thanks for the help again.
#include <stdio.h>
#include <stdlib.h>
void print(int x[][4], int, int);
void func(int z[][4], int*, int, int*, int);
void main() {
int a[4][4] = { 1, 4, 15, 7,
8, 10, 2, 11,
14, 3, 6, 13,
12, 9, 5, 0 };
int b[4][4];
int n, temp, i, j, x_coord = 3, y_coord = 3, count = 0;
while (count != 15) {
print(a, 4, 4);
count = 0;
n = getch();
if (n == 'H') {
if (x_coord != 3)
func(a, &x_coord, 1, &y_coord, 0);
else
printf("\nWrong move!\n");
}
if (n == 'P') {
if (x_coord != 0)
func(a, &x_coord, -1, &y_coord, 0);
else
printf("\nWrong move!\n");
}
if (n == 'K') {
if (y_coord != 3)
func(a, &x_coord, 0, &y_coord, 1);
else
printf("\nWrong move!\n");
}
if (n == 'M') {
if (y_coord != 0)
func(a, &x_coord, 0, &y_coord, -1);
else
printf("\nWrong move!\n");
}
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
b[i][j] = a[i][j];
}
}
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
if (b[i][j] == 0) {
temp = b[i][j];
b[i][j] = b[3][3];
b[3][3] = temp;
}
}
}
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
if (i == 4 && j == 4)
continue;
if (b[i][j] == 4 * i + j + 1)
count++;
}
}
}
}
void print(int x[][4], int r, int c) {
int i, j;
for (i = 0; i < r; i++) {
for (j = 0; j < c; j++)
printf("%d ", x[i][j]);
printf("\n\n");
}
}
void func(int z[][4], int *x, int x1, int *y, int y1) {
z[*x][*y] = z[*x + x1][*y + y1];
z[*x + x1][*y + y1] = 0;
*x = *x + x1;
*y = *y + y1;
}

Returning array in C, Sudoku Solver

So I'm creating a sudoku solver in C. Here's my full code as of now, I've mostly been using python and just got into C, I basically converted a lot of python functions to C to get this but I think it'll work:
#include <stdio.h>
#include <stdlib.h>
int is_empty();
int possible_v();
int solver();
int main(){
int s_array[9][9];
FILE * fpointer;
int i;
int j;
fpointer = fopen("sudoku001.txt", "r");
for (i=0; i<9; i++){
for(j = 0; j<9; j++){
fscanf(fpointer, "%d", &s_array[i][j]);
}
}
for (i=0; i<9; i++) {
if (i % 3 == 0) {
printf("------------------------------\n");
}
for (j = 0; j < 9; j++) {
printf(" %d ", s_array[i][j]);
if ((j + 1) % 3 == 0) {
printf("|");
}
}
printf("\n");
}
solver(s_array);
for (i=0; i<9; i++) {
if (i % 3 == 0) {
printf("------------------------------\n");
}
for (j = 0; j < 9; j++) {
printf(" %d ", s_array[i][j]);
if ((j + 1) % 3 == 0) {
printf("|");
}
}
printf("\n");
}
return 0;
}
int is_empty(int board[9][9]){
int i;
int j;
int is_empty= 0;
for (i=0; i<9; i++){
for(j = 0; j<9; j++){
if (board[i][j] == 0) {
is_empty = 1;
break;
}
}
if (is_empty == 1){
break;
}
}
return is_empty;
}
int possible_v(int board[9][9], int i, int j) {
int p_array[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
int x;
int y;
int temp;
for (x = 0; x < 9; x++) {
if (board[x][j] != 0) {
temp = board[x][j];
p_array[temp - 1] = temp;
}
}
for (y = 0; y < 9; y++) {
if (board[i][y] != 0) {
temp = board[i][y];
p_array[temp - 1] = temp;
}
}
int m;
int n;
int temp1;
int temp2;
if (i>= 0 && i <= 2) {
m = 0;
}
else if (i>= 3 && i<=5) {
m = 3;
}
else{
m = 6;
}
if (j>= 0 && j <= 2) {
n = 0;
}
else if (j>= 3 && j<=5) {
n = 3;
}
else{
n = 6;
}
temp1 = m;
temp2 = n;
for (temp1; temp1<temp1+3; temp1++){
for (temp2; temp2<temp2+3; temp2++){
if (board[temp1][temp2] != 0){
p_array[board[temp1][temp2]] = 1;
}
}
}
temp1 = 1;
for (temp1; temp1<10){
if (p_array[temp1] == 0){
p_array[temp1] = temp1;
}
else{
p_array[temp1] = 0;
}
}
return p_array;
}
int solver(int board[9][9]){
int i;
int j;
int x;
int y;
int empty_check;
int p_values;
int temp;
if (is_empty(board) == 0){
printf("Board Completed");
empty_check = 0;
return empty_check;
}
else{
for (x = 0; x < 9; x++){
for (y = 0; y< 9; y++){
if (board[x][y] == 0){
i = x;
j = y;
break;
}
}
}
p_values = possible_v(board, i, j);
for (temp = 1; temp <10; temp++){
if (p_values[temp] != 0){
board[i][j] = p_values[temp];
solver(board);
}
}
board[i][j] = 0;
}
}
My main issue when compiling is getting the last two functions work with each other.
Function 'solver' calls and binds function 'possible_v'. Possible_V returns an array which I need to solve the puzzle. How can I make this work? .
You have the array locally declared, hence it cannot be passed back since it is destroyed once the function is exited. The workaround to this is to dynamically declare the array using malloc int *parray = (int*)malloc(9*sizeof(int)); and using the return type int* instead of int. But do not forget to free the allocated memory, else you will just keep allocating new memory from heap for every call you make.
As a side note, your implementation of Sudoku solver is a bit complex, and there is no need to return an array. You need to pass only the board. Here is an implementation of Sudoku Solver. This works both for 9x9 and 6X6 boards.
Edit : As advised by David Rankin, I have converted the C++ code to C.
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int n;
int issafe(int **board,int i,int j,int num){
for(int k=0;k<n;k++)
if(board[i][k] == num || board[k][j] == num)
return 0;
int cellx,celly;
if(n==6){
cellx = (i/2)*2;
celly = (j/3)*3;
for(int l=cellx;l<cellx+2;l++)
for(int m=celly;m<celly+3;m++)
if(board[l][m] == num){
return 0;
}
return 1;
}
int root = sqrt(n);
cellx = (i/(root))*root;
celly = (j/(root))*root;
for(int l=cellx;l<cellx+root;l++)
for(int m=celly;m<celly+root;m++)
if(board[l][m] == num)
return 0;
return 1;
}
int solve(int **board,int i,int j){
if(i == n)
return 1;
if(j == n){
return solve(board,i+1,0);
}
if(board[i][j] != 0)
return solve(board,i,j+1);
for(int k=1;k<n+1;k++)
if(issafe(board,i,j,k)){
board[i][j] = k;
if(solve(board,i,j+1))
return 1;
//backtrack
board[i][j] = 0;
}
return 0;
}
int main(){
do{
printf("Enter size of board(9 or 6): ");
scanf("%d",&n);
}while(n != 9 && n != 6);
int **board;
board = malloc(sizeof *board * n);
for(int i=0;i<n;i++)
board[i] = malloc(sizeof *board * n);
// input
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
scanf("%d",&board[i][j]);
if(solve(board,0,0))
for(int i=0;i<n;i++){
for(int j=0;j<n;j++)
printf("%d ",board[i][j]);
printf("\n");
}
return 0;
}

Count alternating up / down sequences

Description of the problem :
Compute the number of all the sequences which go up down from some input n.
So the user input n; with that n then I create an array of numbers 1..n and then number the sequences with that property
Example: n = 4
1 3 2 4
1 4 2 3
2 3 1 4
2 4 1 3
3 4 1 2
Answer: 5
My program works but for some reason I sometimes get 0 instead of the answer.
#include <stdio.h>
#include <stdlib.h>
void *safeMalloc(int n) {
void *p = malloc(n);
if (p == NULL) {
printf("Error: malloc(%d) failed. Out of memory?\n", n);
exit(EXIT_FAILURE);
}
return p;
}
void swap(int *fir, int *sec) {
int temp = *fir;
*fir = *sec;
*sec = temp;
}
void permute(int *array, int i, int length, int *count) {
if (length == 2) {
*count = 1;
return;
}
if (length == i) {
int v = 0, flag = 1;
while (v < length) {
if (v % 2 == 0) {
if (array[v] < array[v + 1]) {
v++;
} else {
flag = 0;
return;
}
}
if (v % 2 != 0) {
if (array[v] > array[v + 1]) {
v++;
} else {
flag = 0;
return;
}
}
}
if (flag == 1) {
/*
int a;
for (a = 0; a < length; a++)
printf("%d", array[a]);
printf("\n");
*/
*count = *count + 1;
}
}
int j = i;
for (j = i; j < length; j++) {
swap(array + i, array + j);
permute(array, i + 1, length, count);
swap(array + i, array + j);
}
return;
}
int main(int argc, char **argv) {
int n;
scanf("%d", &n);
int *arr = safeMalloc(n * sizeof(int));
int i;
for (i = 0; i < n; i++) {
arr[i] = i + 1;
}
int count = 0;
permute(arr, 0, n, &count);
printf("%d\n", count);
return 0;
}
You basically generate all permutations of the array elements and count the valid ones.
Your code has a minor flaw:
the loop while (v < length) { goes one step too far: you access tab[v + 1] so the loop should stop at v < length - 1. As currently coded, it has undefined behavior.
You can further simply the code:
there should be no need to special case length == 2.
flag useless as you always return when you clear it.
if (v % 2 != 0) is redundant: else would suffice.
Here is a fixed and simplified version:
#include <stdio.h>
#include <stdlib.h>
void *safeMalloc(int n) {
void *p = malloc(n);
if (p == NULL) {
printf("Error: malloc(%d) failed. Out of memory?\n", n);
exit(EXIT_FAILURE);
}
return p;
}
void swap(int *fir, int *sec) {
int temp = *fir;
*fir = *sec;
*sec = temp;
}
void permutate(int *array, int i, int length, int *count) {
if (i == length) {
for (int v = 0; v < length - 1; v++) {
if (v % 2 == 0) {
if (array[v] >= array[v + 1]) {
return;
}
} else {
if (array[v] <= array[v + 1]) {
return;
}
}
}
*count = *count + 1;
} else {
for (int j = i; j < length; j++) {
swap(array + i, array + j);
permutate(array, i + 1, length, count);
swap(array + i, array + j);
}
}
}
int main(int argc, char **argv) {
int n;
if (scanf("%d", &n) == 1 && n > 0) {
int *arr = safeMalloc(n * sizeof(int));
for (int i = 0; i < n; i++) {
arr[i] = i + 1;
}
int count = 0;
permutate(arr, 0, n, &count);
printf("%d\n", count);
}
return 0;
}
if you call tab(n,k) the number of updown sequence of length n with k being the last number in your sequence, you can write a recursive formula and implement it like that:
int N = 5+1;
int** tab = new int*[N];
for (int n = 0; n < N; n++) {
tab[n] = new int[N];
for (int k = 0; k < N; k++) {
tab[n][k] = 0;
}
}
tab[1][1] = 1;
for (int n = 2; n < N; n++) {
for (int k = 1; k <= n; k++) {
if (n % 2 == 0) {
for (int j = 0; j < k; j++) {
tab[n][k] += tab[n-1][j];
}
}
else {
for (int j = k; j < n; j++) {
tab[n][k] += tab[n-1][j];
}
}
}
}
int res = 0;
for (int j = 0; j < N; j++) {
res += tab[N - 1][j];
}
You can solve this without iterating through the permutations. Say you're trying to calculate f(n). Where can the new, high number go? It has to go in an 'up' position, which is an even position. You can have any valid sequence of odd length preceding it, and any valid sequence following it.
Let's say we're calculating f(n,k) where the highest val is in position k, zero indexed. This is zero for k even. For odd k we get:
f(n,k) = choose(n-1, k) * f(k) * f(n - k - 1)
To get f(n), sum f(n,k) over odd k < n.
We have to calculate the first few by hand.
f(0) = 1
f(1) = 1
f(2) = 1
f(3) = f(3,1) = choose(2,1) * f(1) * f(1) = 2 * 1 *1 = 2
f(4) = f(4,1) + f(4,3) = choose(3,1) * f(1) * f(2) + choose(3,3) * f(3) * f(0) = 3*1*1 + 1*2*1 = 5
f(5) = f(5,1) + f(5,3) = choose(4,1) * f(1) * f(3) + choose(4,3) * f(3) * f(1) = 4*1*2 + 4*2*1 = 16

Sorting integer array to avoid repeating consecutive values in C

I'm using Linux to implement this sorting. If I have a array arr[] ={1, 1, 1, 2, 2, 3, 3}, how to sort it by this:
arr[0] = 1
arr[1] = 2
arr[2] = 3
arr[3] = 1
arr[4] = 2
arr[5] = 3
arr[6] = 1
I Tried to do something like this:
for (int i = 0; i < size; i++)
{
if (arr[i] < arr[i+1])
{
}
}
Please give me some suggestions, thank you so much!
a hint
first you have to sort the array, then starting from 1 to (end-1) if active item equals to the last item move it to the end.
#include <stdio.h>
#include <stdlib.h>
/*__________________________________________________
*/
static int __cdecl sortCallback(int *i1,int *i2){
return (*i1<*i2)?-1:(*i1>*i2)?1:0;
}
/*__________________________________________________
*/
void printArr(char* Title,int *arr,int n){
int i;
if(Title)
printf("%s:\n\t",Title);
for (i=0;i<n;i++)
printf("%d ",arr[i]);
printf("\n");
return;
}
/*__________________________________________________
*/
void arrange(int *arr,int n){
int i=1,j;
int a;
while(i<(n-1)){
if(arr[i]==arr[i-1]){
a=arr[i];
for(j=i;j<(n+1);j++){
arr[j]=arr[j+1];
}
arr[n-1]=a;
}else
i++;
}
}
/*__________________________________________________
*/
int main(void){
int arr[7];
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
arr[3] = 1;
arr[4] = 2;
arr[5] = 3;
arr[6] = 1;
printArr("Initial",arr,7);
qsort(arr,7,sizeof(int),sortCallback);
printArr("Sorted",arr,7);
arrange(arr,7);
printArr("Rearranged",arr,7);
return 0;
}
#include <stdio.h>
void cnv(int n, int arr[n]){//arr is sorted
struct {
int value;
int occurs;
} tmp[n];
//make distinct array
int k = 0;
tmp[k].value = arr[0];
tmp[k].occurs = 1;
for(int i = 1; i < n; ++i){
if(arr[i] != arr[i-1]){
tmp[++k].value = arr[i];
tmp[k].occurs = 1;
} else {
++tmp[k].occurs;
}
}
//Written back
for(int i = 0, j = 0; i < n; ++i){
while(tmp[j].occurs == 0){
j = (j == k) ? 0 : j + 1;
}
arr[i] = tmp[j].value;
--tmp[j].occurs;
j = (j == k) ? 0 : j + 1;
}
}
int main(void){
int arr[] ={1, 1, 1, 2, 2, 3, 3};
int n = sizeof(arr)/sizeof(*arr);
cnv(n, arr);
for(int i = 0; i < n; ++i) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}

Getting a SIGSEGV error in my C program

This is my code for the problem.
I used a dynamic programming approach, and my answer is coming out to be correct. But I am getting a Runtime Error of SIGSEGV, may be because of array index and I am unable to figure out how and where?
If you can figure out what and where is the problem, please let me know.
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
int dynp(int i, int j);
int v[] = {-1, 0, 1, 0};
int h[] = {0, 1, 0, -1};
int ROW, COL;
#define INF 1000000
int minOfTwo(int one, int two){
if (one<two) {
return one;
}else{
return two;
}
}
int matrix[190][190];
int dp[190][190];
int main(int argc, const char * argv[]) {
int t;
scanf("%d", &t);
int i,j;
char s[190];
while (t--) {
scanf("%d %d", &ROW, &COL);
for (i = 0; i<ROW; i++) {
scanf("%s", s);
for (j = 0; j<COL; j++) {
matrix[i][j] = s[j] - 48;
dp[i][j] = INF;
}
}
for (i = 0; i<ROW; i++) {
for (j = 0; j<COL; j++) {
if (dp[i][j] == INF) {
if (matrix[i][j] == 1) {
dp[i][j] = 0;
}
else{
dp[i][j] = dynp(i, j);
}
}
}
}
for (i = 0; i<ROW; i++) {
for (j = 0; j<COL; j++) {
printf("%d ", dp[i][j]);
}
printf("\n");
}
}
return 0;
}
int dynp(int i, int j)
{
if (dp[i][j] != INF) {
return dp[i][j];
}
else{
if (matrix[i][j] == 1) {
dp[i][j] = 0;
return dp[i][j];
}
else{
int k;
for (k = 0; k<4; k++) {
int newi = i + v[k], newj = j + h[k];
if (newi < ROW && newj < COL && newi>=0 && newj>=0) {
dp[i][j] = minOfTwo(dp[i][j], 1 + dynp(newi, newj));
}
}
return dp[i][j];
}
}
}
At the first look, in your code,
scanf("%s", s);
for (j = 0; j<COL; j++) {
matrix[i][j] = s[j] - 48;
looks problematic. With the length of s lesser than the value of COL and s being an automatic local variable not initialized explicitly, you'll be accessing allocated but uninitialized memory location.
You should change the looping condition to something like
scanf("%189s", s); //to avoid overflow
int len = strlen(s);
for (j = 0; (j<COL) && (j < len); j++, len--) {
matrix[i][j] = s[j] - 48;

Resources