Returning array in C, Sudoku Solver - c

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;
}

Related

How to find out the inverse of an NXN matrix in C

Hi everyone I made some changes in the code so that it's easy to understand, looks what I have so far, I kept the function's prototype at the beginning of the code and it works fine, but it just works fine just when I try a 2x2 matrix because if I try a 3x3, 4x4 or 6x6 matrix it does not works fine the determinant is not calculated right, I guess that's the problem the determinant but I don't know how to solve it. Here is the code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<math.h>
float determinant(int tam,float [][tam]);
void cofactor(int tam,float [][tam]);
void transpose(int tam,float [][tam],float [][tam]);
int validate(){
int val;
char *buf = (char *) malloc(10);
memset(buf,0,10);
while(fgets(buf, 10, stdin) != NULL ){
if(buf[0]!='\n') {
val = atoi(buf);
break;
}
}
free(buf);
return val;
}
float determinant(int tam, float matrix[][tam])
{
float s = 1, det = 0, b[tam][tam];
int i, j, m, n, c;
if (tam == 1)
{
return (matrix[0][0]);
}
else
{
det = 0;
for (c = 0; c < tam; c++)
{
m = 0;
n = 0;
for (i = 0;i < tam; i++)
{
for (j = 0 ;j < tam; j++)
{
b[i][j] = 0;
if (i != 0 && j != c)
{
b[m][n] = matrix[i][j];
if (n < (tam - 2))
n++;
else
{
n = 0;
m++;
}
}
}
}
det = det + s * (matrix[0][c] * determinant( tam - 1,b));
s = -1 * s;
}
}
return (det);
}
void cofactor( int tam,float num[][tam])
{
float b[tam][tam], fac[tam][tam];
int p, q, m, n, i, j;
float x = 0;
for (q = 0;q < tam; q++)
{
for (p = 0;p < tam; p++)
{
m = 0;
n = 0;
for (i = 0;i < tam; i++)
{
for (j = 0;j < tam; j++)
{
if (i != q && j != p)
{
b[m][n] = num[i][j];
if (n < (tam - 2))
n++;
else
{
n = 0;
m++;
}
}
}
}
x = pow(-1, q + p) * determinant( tam - 1,b);
fac[p][q] = x;
}
}
transpose(tam,num, fac);
}
void transpose(int tam,float num[][tam], float fac[][tam])
{
int i, j;
float b[tam][tam], inverse[tam][tam], d;
for (i = 0;i < tam; i++)
{
for (j = 0;j < tam; j++)
{
b[i][j] = fac[j][i];
}
}
d = determinant(tam,num);
for (i = 0;i < tam; i++)
{
for (j = 0;j < tam; j++)
{
inverse[i][j] = b[i][j] / d;
}
}
printf("\n\n\nThe inverse of matrix is : \n");
for (i = 0;i < tam; i++)
{
for (j = 0;j < tam; j++)
{
printf("\t%f", inverse[i][j]);
}
printf("\n");
}
}
int verify_Size(int line){
if((line > 0) && (line <= 6))
{
return 1;
}
return 0;
}
int create_Matrix(int LINE){
int matrix[LINE][LINE];
float aux[LINE][LINE];
printf("\n\n\nPle:", (LINE * LINE));
printf("\n--------------------------------\n");
for(int i=0;i<LINE;i++)
{
for(int j=0;j<LINE;j++)
{
printf("Value[%d][%d]: ",i,j);
matrix[i][j] = validate();
}
}
printf("\n\nYour Bidimensional Matrix is:");
printf("\n--------------------------------\n");
for(int i=0;i < LINE;i++)
{
for(int j=0; j< LINE;j++)
{
printf("\t%2d",matrix[i][j]);
aux[i][j] = (float) matrix[i][j];
}
printf("\n");
}
float d = determinant(LINE,aux);
printf("\n\nDeterminante Main: %f \n",d);
if (d == 0)
printf("\nInverse of Entered Matrix is not possible\n");
else
cofactor(LINE,aux);
return 0;
}
int main(){
int flag,line;
do{
printf("Enter the order of the Matrix:\n");
printf("-------------------------------\n");
printf("Lines: ");
line = validate();
if(verify_Size(line)== 1)
{
create_Matrix(line);
}else{
printf("\nMatrix must to be till 6 X 6!\n");
flag = 0;
}
}while(flag != 1);
return 0;
}
It looks like you are finding the inverse matrix by Cramer's rule. While it works Ok for 2x2 or 3x3 matrix sizes, the hard part about implementing Cramer's rule generally is evaluating determinants. If you compute an NxN determinant following the definition, the computation is recursive and has factorial O(N!) computational complexity (Wikipedia).
I suggest switching to another algorithm. LUP factorization is fast and relatively simple, and Wikipedia has an example implementation.

Runtime error in a C program to find an index of an element

This program prints the index of element after sorted. Here is the code:
#include<stdio.h>
#include<limits.h>
int n;
int value[10000];
int index[10000];
int enable[10000];
//return the element which is smallest and never selected
int min() {
int i, tmp=INT_MAX;
for (i = 0; i < n; i++) {
if (enable[i] == 0 && tmp > value[i] )
tmp = value[i];
}
return tmp;
}
void solve() {
int i,j;
int tmp;
for (i= 0; i < n; i++) {
tmp = min();
for (j = 0; j < n; j++) {
if (enable[j] == 0 && tmp == value[j] ) {
index[j] = i + 1;
enable[j] = 1;
}
}
}
}
void print() {
int i = 0;
for (; i < n-1; i++)
printf("%d ", index[i]);
printf("%d\n", index[i]);
}
int main() {
int i;
while (scanf("%d", &n) != EOF) {
for (i = 0; i < n; i++) {
scanf("%d", &value[i]);
}
solve();
print();
}
return 0;
}
It worked well on my computer, but the online judge shows runtime error. I could not figure it out where it went wrong, maybe my test is not enough.

Splitting array into two parts, sorting each part, and recombining into single array

I've been working on a program that generates an array of random numbers, splits the array into two equal parts, sorts each part, and then recombines the two parts back into a singular sorted array. When attempting an insert sort I get the following:
http://i.imgur.com/70J4eLG.png
Can you guys see a reason why the first half array is sorted correctly but the second half is not?
int cmpfunc (const void *a, const void *b) {
return ( *(int*)a - *(int*)b );
}
void insertion_sort (int ar[], int size) {
int c, d, t;
for (c = 1; c <= size - 1; c++){
d = c;
while(d > 0 && ar[d] < ar[d - 1]) {
t = ar[d];
ar[d] = ar[d - 1];
ar[d - 1] = t;
d--;
}
}
}
void check_sort (int ara[], int size_t) {
int b;
int c_i;
c_i = 0;
for (b = 1; b < size_t; b++) {
if (ara[b - 1] > ara[b]) {
printf("Array is not sorted correctly\n");
break;
} else {
c_i++;
}
}
if (c_i == size_t - 1) {
printf("Array is sorted correctly\n");
}
}
void combine_array(int a_ar[], int b_ar[], int c_ar[], int size_1, int size_2) {
int i, j, k;
i, j, k = 0;
while (i < size_1 && j < size_2) {
if (a_ar[i] < b_ar[j]) {
c_ar[k] = a_ar[i];
i++;
} else {
c_ar[k] = b_ar[j];
j++;
}
k++;
}
if (i >= size_1) {
while (j < size_2) {
c_ar[k] = b_ar[j];
j++;
k++;
}
}
if (j >= size_2) {
while (i < size_1) {
c_ar[k] = a_ar[i];
i++;
k++;
}
}
}
int main (int argc, char *argv[]) {
int a_size, t_num;
char s_type;
int i, j, k;
int two_s[1];
a_size = atoi(argv[1]);
t_num = atoi(argv[2]);
s_type = argv[3][0];
int array_m[a_size];
for (i = 0; i < a_size; i++) {
array_m[i] = rand();
}
for (i = 0; i < a_size; i++) {
printf("%d \n", array_m[i]);
}
printf("\n");
if (t_num == 2) {
two_s[0] = ((a_size/2));
two_s[1] = (a_size);
int array_s1[two_s[0]];
int array_s2[two_s[0]];
printf("First half \n");
for (j = 0; j < two_s[0]; j ++) {
array_s1[j] = array_m[j];
printf("%d \n", array_s1[j]);
}
printf("Second half \n");
for (k = two_s[0]; k < two_s[1]; k++) {
array_s2[k] = array_m[k];
printf("%d \n", array_s2[k]);
}
printf("Size of second array: %d", (two_s[1] - two_s[0]));
printf("\n");
check_sort(array_m, a_size);
if (s_type == 'I') { //Insertion sort
insertion_sort(array_s1, two_s[0]);
insertion_sort(array_s2, two_s[0]);
printf("Sorted first half \n");
for (i = 0; i < two_s[0]; i++) {
printf("%d \n", array_s1[i]);
}
printf("Sorted second half \n");
for (i = 0; i < two_s[0]; i++) {
printf("%d \n", array_s2[i]);
}
//combine_array(array_s1, array_s2, array_m, two_s[0], two_s[0]);
printf("\n");
printf("Combined and sorted \n");
for (i = 0; i < a_size; i++) {
printf("%d \n", array_m[i]);
}
check_sort(array_m, a_size);
}
if (s_type == 'Q') { //Quick sort
qsort(array_m, a_size, sizeof(int), cmpfunc);
printf("\n");
for (i = 0; i < a_size; i++) {
printf("%d \n", array_m[i]);
}
}
}
}
In your example, array_s2 is an array with 5 elements. In the following for loop, you're writing to memory outside the bounds of the array:
for (k = two_s[0]; k < two_s[1]; k++) {
array_s2[k] = array_m[k];
printf("%d \n", array_s2[k]);
}
k has an initial value of 5 and a final value of 9, which is outside the bounds of array_s2. Try the following to correctly index the array:
for (k = two_s[0]; k < two_s[1]; k++) {
array_s2[k - two_s[0]] = array_m[k];
printf("%d \n", array_s2[k - two_s[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;

In an array how can one check if any two of its content numbers can add up to a certain value x or not?

What command could one use to check if the sum of any two numbers within an array add up to a certain value of x.
The following solution should help you:
int TestArray (int array[], int count, int targetSum)
{
int i,j;
for (i=0; i<count-1; i++)
{
for (j=i+1; j<count; j++)
{
if (array[i] + array[j] == targetSum)
{
return 1;
}
}
}
return 0;
}
This function takes as arguments the array, the number of array elements (3 in your example), and the target sum to check for (5 in your case).
Usage is like this (sample main):
int main(int argc, char *argv[])
{
int numbers1[] = {1,2,3,4};
int numbers2[] = {1,1,3,3};
int result;
result = TestArray(numbers1, 4, 5);
if (result == 1)
{
printf("True");
}
else
{
printf("False");
}
result = TestArray(numbers2, 4, 5);
if (result == 1)
{
printf("True\n");
}
else
{
printf("False");
}
return 0;
}
The output is:
True
False
according to your example
Beginners practice..
int arr[3] = {1,2,3}; //array has 3 numbers
int i,j,x,k;
int res = 0;
scanf("%d",&x);
for(i=0; i< size; i++){
j = i+1;
if(j >= size){
j = 0;
}
k = arr[i] + arr[j];
if(k == x){
res = 1;
break;
}
}
if(res == 1)
printf("True\n");
else
printf("false\n");
How about this:
int i;
int j;
int x;
int [size] TheArray;
printf("Enter value of x: ");
scanf("%d", &x);
for(i = 0; i < size; i++)
{
for(j = 0; j < size; j++)
{
if(TheArray[j]+TheArray[i] == x)
{
printf("true");
break;
}
else printf("false");
}
}
You need to include the array in your code, he is the main actor in your problem.

Resources