C programming - Sodoku solution (backtracking) - c

the Question is: to get from the user sodoku board and if there is a solution to print it, if not to print no solution!
the solution of the soduko: two identical numbers mmust not appear on the same line;
two identical numbers must not appear in the same colum.
I worte a program that works perfectly when I put the soduko board and the size (global parametes-as shown un my code) but when I tried to receive from the user it took so much time to run the solution and sometimes it didn't retun anything. I would like to understand why?!
#include <stdio.h>
#include <stdlib.h>
#define SIZE 5
int matrix[5][5] = {
{4,2,0,0,5},
{2,0,0,1,3},
{5,0,1,2,0},
{0,0,3,0,2},
{0,0,0,0,0},
};
void print_sudoku()
{
int i,j;
for(i=0;i<SIZE;i++)
{
for(j=0;j<SIZE;j++)
{
printf("%d ",matrix[i][j]);
}
printf("\n");
}
}
int number_unassigned(int *row, int *col)
{
int num_unassign = 0;
int i,j;
for(i=0;i<SIZE;i++)
{
for(j=0;j<SIZE;j++)
{
if(matrix[i][j] == 0)
{
*row = i;
*col = j;
num_unassign = 1;
return num_unassign;
}
}
}
return num_unassign;
}
int is_safe(int n, int r, int c)
{
int i;
for(i=0;i<SIZE;i++)
{
if(matrix[r][i] == n)
return 0;
}
for(i=0;i<SIZE;i++)
{
if(matrix[i][c] == n)
return 0;
}
return 1;
}
int solve_sudoku()
{
int row;
int col;
if(number_unassigned(&row, &col) == 0)
return 1;
int i;
for(i=1;i<=SIZE;i++)
{
if(is_safe(i, row, col))
{
matrix[row][col] = i;
if(solve_sudoku())
return 1;
matrix[row][col]=0;
}
}
return 0;
}
int main()
{
if (solve_sudoku())
print_sudoku();
else
printf("No solution!\n");
return 0;
}
and this is whe code that I used to ask the user to enter a sodoku board:
int** ReadSoduko(int n) {
int** matrix = (int**) malloc((sizeof(int*)) * n);
for(int i = 0; i < n; ++i) {
matrix[i] = malloc(sizeof(int) * n);
}
printf("\nEnter your soduko board:\n");
for(int i = 0; i < n; ++i) {
printf("Enter row [%d]: ", i);
for(int j = 0; j < n; ++j) {
scanf("%d", &matrix[i][j]);
}
}
return matrix;
}

I suspect your problem is related to one thing: #define SIZE that you are probably forgetting to update when reading dynamically. Since you use SIZE in your loops, if that is not the real size of your matrix, then it probably won't work. I've changed 2 lines and added 3 other (the lines with comments at the end). Try it now.
#include <stdio.h>
#include <stdlib.h>
int SIZE; //changed here
int** matrix; //changed here
void print_sudoku()
{
int i, j;
for (i = 0; i < SIZE; i++)
{
for (j = 0; j < SIZE; j++)
{
printf("%d ", matrix[i][j]);
}
printf("\n");
}
}
int number_unassigned(int* row, int* col)
{
int num_unassign = 0;
int i, j;
for (i = 0; i < SIZE; i++)
{
for (j = 0; j < SIZE; j++)
{
if (matrix[i][j] == 0)
{
*row = i;
*col = j;
num_unassign = 1;
return num_unassign;
}
}
}
return num_unassign;
}
int is_safe(int n, int r, int c)
{
int i;
for (i = 0; i < SIZE; i++)
{
if (matrix[r][i] == n)
return 0;
}
for (i = 0; i < SIZE; i++)
{
if (matrix[i][c] == n)
return 0;
}
return 1;
}
int solve_sudoku()
{
int row;
int col;
if (number_unassigned(&row, &col) == 0)
return 1;
int i;
for (i = 1; i <= SIZE; i++)
{
if (is_safe(i, row, col))
{
matrix[row][col] = i;
if (solve_sudoku())
return 1;
matrix[row][col] = 0;
}
}
return 0;
}
int** ReadSoduko(int n) {
int** matrix = (int**)malloc((sizeof(int*)) * n);
for (int i = 0; i < n; ++i) {
matrix[i] = (int*) malloc(sizeof(int) * n);
}
printf("\nEnter your soduko board:\n");
for (int i = 0; i < n; ++i) {
printf("Enter row [%d]: ", i);
for (int j = 0; j < n; ++j) {
scanf("%d", &matrix[i][j]);
}
}
return matrix;
}
int main()
{
printf("Size of matrix: "); //added this
scanf("%d", &SIZE); //added this
matrix = ReadSoduko(SIZE); //added this
if (solve_sudoku())
print_sudoku();
else
printf("No solution!\n");
return 0;
}
And don't forget that the matrix that you have declared statically doesn't have a solution! I have tested the same matrix, just replacing the 2 in first line by a 0 and it worked here.

Related

I want to show elements of a matrix that appear only once

I got this but it I can't seem to make it work, tried everything I could think of.
#include <stdio.h>
#include <stdlib.h>
void alocare_vector(int *v, int nr, int elem)
{
int *v1;
if ((v1 = realloc(v, nr * sizeof(int))) == NULL)
{
printf("Memorie insuficienta");
free(v);
exit(EXIT_FAILURE);
}
v = v1;
v[nr - 1] = elem;
}
int main()
{
int a[100][100];
int n, *v = NULL, i, j, k, l, ok = 0, nr = 0;
printf("Number de elements n:");
scanf("%d", &n);
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
scanf("%d", &a[i][j]);
for (k = 0; k < n; k++)
{
for (l = 0; l < n; l++)
{
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
if (a[k][l] == a[i][j] && (k != i && l != j))
ok = 1;
if (ok == 0)
{
nr++;
alocare_vector(v, nr, a[k][l]);
}
ok = 0;
}
}
if (nr > 0)
{
printf("Elements:");
for (i = 0; i < nr; i++)
{
printf("%d ", v[i]);
}
}
free(v);
}
Basically, I need to create a matrix, ans print the elements that appear only once using an array with dynamic memory allocation.
one simple fix is to declare the "int * v" as a global variable and modify the function as alocare_vector(int nr, int elem)
now using a hash table you can store the numbers in the array, below is the your implementation just a bit modified.
#include <stdio.h>
#include <stdlib.h>
int hash[1000]={0};
int * v=NULL;
void alocare_vector(int nr, int elem)
{
int *v1;
if ((v1 = (int*)realloc(v, nr * sizeof(int))) == NULL)
{
printf("Memorie insuficienta");
free(v);
exit(EXIT_FAILURE);
}
v = v1;
v[nr - 1] = elem;
}
int main()
{
int a[100][100];
int n, i, j, nr = 0;
printf("Number de elements n:");
scanf("%d", &n);
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
scanf("%d", &a[i][j]);
++hash[a[i][j]];
}
}
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
if(hash[a[i][j]]==1)
{
nr++;
alocare_vector(nr, a[i][j]);
}
}
}
if (nr > 0)
{
printf("Elements:");
for (i = 0; i < nr; i++)
{
printf("%d ", v[i]);
}
}
free(v);
}
When calling a your funtion you pass a copy of the pointer. Therfore any modifications to this local copy of the pointer will not affect the copy in main. Therfore you need a refrence or pointer to the pointer in main.
void alocare_vector(int **v, int nr, int elem)
{
...
*v = v1;
}
Here you have brut force example how to generate array of distinct elements of the 2D array:
typedef struct
{
size_t length;
int data[];
}data_t;
data_t *add_element(data_t *arr, int element)
{
size_t newsize = arr ? arr -> length : 0;
arr = realloc(arr, newsize * sizeof(arr -> data[0]) + sizeof(*arr));
if(arr)
{
arr -> length = newsize;
arr -> data[newsize - 1] = element;
}
return arr;
}
int isPresent(size_t rows, size_t cols, size_t vrow, size_t vcol, int (*array)[cols])
{
int val = array[vrow][vcol];
for(size_t row = 0; row < rows; row++)
for(size_t col = 0; col < cols; col++)
{
if(vcol == col && vrow == row) continue;
if(array[row][col] == val)
{
return 1;
}
}
return 0;
}
data_t *distinctElements(size_t rows, size_t cols, int (*array)[cols])
{
data_t *dist = NULL;
for(size_t row = 0; row < rows; row++)
{
for(size_t col = 0; col < cols; col++)
{
if(!isPresent(rows, cols, row, col, array))
{
data_t *tmp = add_element(dist, array[row][col]);
if(tmp) dist = tmp;
else { /* error handling */}
}
}
}
return dist;
}

Code not running fully in VsCode but working in online compilers

This is the code i am talking about. It checks if a matrix is sparse or not . If it is then it changes it to sparse form and transposes it. When I run it with Vscode it runs and displays till it is sparse matrix but doesn't show its sparse form and transpose form but on online compiler it runs successfully till the end.
#include <stdio.h>
int checksparse();
int changematrix();
int main()
{
int a[100][100];
int i, j, r, c;
printf("Enter number of rows and columns in the matrix\n");
scanf("%d%d", &r, &c);
printf("\nEnter the elements in the matrix");
for (i = 0; i < r; i++)
{
for (j = 0; j < c; j++)
{
printf("\na[%d][%d] = ", i, j);
scanf("%d", &a[i][j]);
}
}
int check = checksparse(a, r, c);
if (check == 1)
{
printf("\nIts a sparse matrix\n");
changematrix(a, r, c);
}
else if (check == 0)
{
printf("\nIts not a sparse matrix");
}
return 0;
}
int checksparse(int array[100][100], int r, int c)
{
int counter = 0, flag = 1;
for (int i = 0; i < r; i++)
{
for (int j = 0; j < c; j++)
{
if (array[i][j] == 0)
counter++;
}
}
if (counter > ((r * c) / 2))
{
return flag;
}
else
{
flag = 0;
return flag;
}
}
int changematrix(int array[100][100], int r, int c)
{
int b[100][100], temp, counter = 0;
for (int i = 0; i < r; i++)
{
for (int j = 0; j < c; j++)
{
if (array[i][j] != 0)
{
b[temp][0] = i;
b[temp][1] = j;
b[temp][2] = array[i][j];
temp++;
counter++;
}
}
}
printf("\nSparse Matrix : \n");
for (int i = 0; i < counter; i++)
{
for (int j = 0; j < 3; j++)
{
printf("%d ", b[i][j]);
printf("\t");
}
printf("\n");
}
printf("\nTranspose of Sparse Matrix : \n");
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < counter; j++)
{
printf("%d ", b[j][i]);
printf("\t");
}
printf("\n");
}
return 0;
}

Problem adding two 4x4 matrices and printing the sum result in a new matrix in C

Could someone help me please?
I need to perform the sum of two matrices that the data will be sent by the user and print the result in a new matrix.
I managed to capture the data from the two arrays, but when I try to add the two, the code does not print the sum, where is the error?
Thanks
#include <stdio.h>
#include <stdlib.h>
void sum(int *mat_A, int *mat_B, int *mat_C);
int main() {
int mat_A[4][4];
int mat_B[4][4];
int mat_C[4][4];
int i, j, value;
printf("\nEnter integer values ​​for the elements of matrix A: \n");
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
printf("\nElement[%d][%d] = ", i, j);
scanf_s("%d", &value);
mat_A[i][j] = value;
}
}
printf("\nEnter integer values ​​for the elements of matrix B: \n");
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
printf("\nElement[%d][%d] = ", i, j);
scanf_s("%d", &value);
mat_B[i][j] = value;
}
}
calc_soma(*mat_A, *mat_B, *mat_C);
printf("\nSum of matrices A with B: \n\n");
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
value = mat_C[i][j];
printf("%d", value);
}
printf("\n");
}
return 0;
}
void sum(int *mat_A, int *mat_B, int *mat_C) {
int i, j;
int value;
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
value = *mat_A + *mat_B;
*mat_C = value;
}
}
}
You need to declare the parameters to sum() as 2-dimensional arrays, not int *, which is a pointer to a 1-dimensional array. Then use i and j as array indexes.
You're also calling the function with the wrong name calc_soma.
#include <stdio.h>
#include <stdlib.h>
void sum(int mat_A[4][4], int mat_B[4][4], int mat_C[4][4]);
int main() {
int mat_A[4][4];
int mat_B[4][4];
int mat_C[4][4];
int i, j, value;
printf("\nEnter integer values for the elements of matrix A: \n");
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
printf("\nElement[%d][%d] = ", i, j);
scanf_s("%d", &value);
mat_A[i][j] = value;
}
}
printf("\nEnter integer values for the elements of matrix B: \n");
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
printf("\nElement[%d][%d] = ", i, j);
scanf_s("%d", &value);
mat_B[i][j] = value;
}
}
sum(mat_A, mat_B, mat_C);
printf("\nSum of matrices A with B: \n\n");
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
value = mat_C[i][j];
printf("%d", value);
}
printf("\n");
}
return 0;
}
void sum(int mat_A[4][4], int mat_B[4][4], int mat_C[4][4]) {
int i, j;
int value;
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
value = mat_A[i][j] + mat_B[i][j];
mat_C[i][j] = value;
}
}
}

Array stores same number form a list of numbers twice

What my program does is that it takes an array of numbers that were read in from a file and sorts them with the selection sort and bubble sort methods. When it's sorted via the bubble sort method, the array lists one number twice in a row. It's also always the second number that gets copied. I checked to see if for whatever reason the number was actually getting passed to the new array twice, but it isn't. I also tried a different input file, same thing happens in the same place.This also cuts off the last number in the list. I don't see anything obvious in my code that's causing that to happen.
The list that the program calls is as follows:
10
50
78
83
92
100
0
4
72
3
19
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int findMin(int arr[], int start, int size);
void printArr(int arr[], int size);
void selectionSort(int arr[], int size);
void bubbleSort(int arr[], int size);
int main(int argc, char *argv[])
{
if(argc != 2)
{
printf("Syntax Error: ./<exec> <infile>\n");
exit(1);
}
FILE *ifp = NULL;
ifp = fopen(argv[1], "r");
if(ifp == NULL)
{
printf("Could not open %s for reading\n", argv[1]);
exit(1);
}
int counter;
int j = 0;
fscanf(ifp, "%d", &counter);
int array[counter];
int arrB[counter];
for(j = 0; j < counter; ++j)
{
fscanf(ifp, "%d", &array[j]);
}
for(j = 0; j < counter; j++)
{
arrB[j] = array[j];
}
int size = sizeof(array) / sizeof(int);
printf("Before: ");
printArr(array, size);
selectionSort(array, size);
bubbleSort(arrB, size);
fclose(ifp);
return 0;
}
int findMin(int arr[], int start, int size)
{
int i = 0;
int minLoc = start;
int minVal = arr[minLoc];
for ( i = start + 1; i < size; ++i)
{
if (arr[i] < minVal)
{
minVal = arr[i];
minLoc = i;
}
}
return minLoc;
}
void printArr(int arr[], int size)
{
int i = 0;
for(i = 0; i < size; ++i)
printf("%3d ", arr[i]);
printf("\n");
}
void selectionSort(int arr[], int size)
{
int i = 0;
int minLoc = 0;
int tmp = 0;
for(i = 0; i < size; ++i)
{
minLoc = findMin(arr, i, size);
tmp = arr[i];
arr[i] = arr[minLoc];
arr[minLoc] = tmp;
}
printf("** Selection Sort **\n After: ");
printArr(arr, size);
}
void bubbleSort(int arr[], int size)
{
int i = 0;
int j = 0;
int tmp = 0;
for(j = 0; j < size; j++)
{
for(i = 0; i < size; ++i)
{
if(arr[i] > arr[i+1])
{
tmp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = tmp;
}
}
}
printf("** Bubble Sort **\n After: ");
printArr(arr, size);
}
bubbleSort() accesses outside array bounds. Thus undefined behavior (UB).
for(j = 0; j < size; j++) {
for(i = 0; i < size; ++i) {
if(arr[i] > arr[i+1]) { // Here code access outside bounds when i = size - 1
... Code swaps arr[i], arr[i+1];
}
}
}
Instead
for(j = 0; j < size; j++) {
for(i = 1; i < size; ++i) {
if(arr[i-1] > arr[i]) {
... Code swaps arr[i-1], arr[i];
}
}
}

Unhandled exception in c

my code is compiled well, and executed. But I get this error after I enter the sortType value: "Unhandled exception at 0x52a56af2 (msvcr90d.dll) in ALINUR_CAGLAYAN_LAB6.exe: 0xC0000005: Access violation writing location 0x00000000."
Here's my code:
#include <stdio.h>
int sorting(int *liverpool8, int *besiktas0, int *hahaha);
void main()
{
int *numbers;
int length;
int sortType=0;
int i;
printf("Enter the length of array:");
scanf("%d",&length);
numbers = (int*)malloc(length*sizeof(int));
for (i = 0; i < length; ++i)
{
printf("%d. element: ", i+1);
scanf("%d", &numbers[i]);
}
printf("\nPlease select one of the following functions:\n1)Ascending order\n0)Descending order");
scanf("%d", sortType);
sorting(*numbers, &length, &sortType);
printf("The numbers arranged in the order as you entered are given below\n");
for (i = 0; i < length; ++i)
{
printf("%d\n", numbers[i]);
}
system("pause");
}
int sorting(int *numbers, int *length, int *sortType)
{
int j, i, a;
if(sortType == 1)
{
for (i = 0; i < length; ++i)
{
for (j = i + 1; j < length; ++j)
{
if (numbers[i] > numbers[j])
{
a = numbers[i];
numbers[i] = numbers[j];
numbers[j] = a;
}
}
}
}
else if(sortType == 0)
{
for (i = 0; i < length; ++i)
{
for (j = i + 1; j < length; ++j)
{
if (numbers[i] < numbers[j])
{
a = numbers[i];
numbers[i] = numbers[j];
numbers[j] = a;
}
}
}
return *numbers;
}
}
There are multiple errors in your code.
The header file for using malloc is not defines.
scanf needs to access addresses and not variables.
The array name decays to a pointer so using * for an array is double dereferencing
To access value in pointer you have to use *, the dereferencing pointer.
I have attached the corrected code.
#include <stdio.h>
#include <stdlib.h>
int sorting(int *liverpool8, int *besiktas0, int *hahaha);
void main()
{
int *numbers;
int length;
int sortType=0;
int i;
printf("Enter the length of array:");
scanf("%d",&length);
numbers = (int*)malloc(length*sizeof(int));
for (i = 0; i < length; ++i)
{
printf("%d. element: ", i+1);
scanf("%d", &numbers[i]);
}
printf("\nPlease select one of the following functions:\n1)Ascending order\n0)Descending order");
scanf("%d", &sortType);
sorting(numbers, &length, &sortType);
printf("The numbers arranged in the order as you entered are given below\n");
for (i = 0; i < length; ++i)
{
printf("%d\n", numbers[i]);
}
system("pause");
}
int sorting(int *numbers, int *length, int *sortType)
{
int j, i, a;
if(*sortType == 1)
{
for (i = 0; i < *length; ++i)
{
for (j = i + 1; j < *length; ++j)
{
if (numbers[i] > numbers[j])
{
a = numbers[i];
numbers[i] = numbers[j];
numbers[j] = a;
}
}
}
}
else if(sortType == 0)
{
for (i = 0; i < *length; ++i)
{
for (j = i + 1; j < *length; ++j)
{
if (numbers[i] < numbers[j])
{
a = numbers[i];
numbers[i] = numbers[j];
numbers[j] = a;
}
}
}
return *numbers;
}}

Resources