check column and row in sodoku- C programming - c

I'm trying to check if number (from 1 to n)
appears more than once in
row or column in sodoku board
I wrote a code that goes over each row and column and checks the numbers between 1 to n (every time checking number at a time after finishing with row 0 (for example) goes to the next one (if it wasn't true in the row before)
my code is working just if there is a number
appearing more than once
in row 0 (if there is in other rows it returns nothing!)
and for the column it doesn't return any thing
this is a matrix that I use for the test (matrix with solution and I change numbers in rows or columns):
7 1 0 0 0 0 6 0 9
2 0 0 0 0 3 0 0 0
0 0 0 1 5 0 0 0 8
0 0 7 0 0 0 0 9 0
0 0 6 0 0 0 7 0 0
0 2 0 0 0 0 4 0 0
1 0 0 0 2 9 0 0 0
0 0 0 3 0 0 0 0 4
9 0 5 0 0 0 0 8 6
and this is my code:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX4USED 10
int n; //size of the sodoku board
bool CheckAppearingInRow(int matrix [n][n]) {
int used[MAX4USED] = {0};
int index = 1;
int row = 0;
while (index <= n) {
for(int j = 0; j < n; j++) {
if(matrix[row][j] == index ) {
used[index] +=1;
}
}
for(int i = 0; i <= n ; i++) {
if (used[i] > 1) {
return true;
}
used[i] = 0;
}
index += 1;
}
row += 1;
while (row < n) {
CheckAppearingInRow(matrix);
}
return false;
}
bool CheckAppearingInColumn(int matrix [n][n]) {
int used[MAX4USED] = {0};
int index = 1;
int col = 0;
while (index <= n) {
for(int i = 0; i < n; i++) {
if(matrix[i][col] == index ) {
used[index] +=1;
}
}
for(int i = 0; i <= n ; i++) {
if (used[i] > 1) {
return true;
}
used[i] = 0;
}
index += 1;
}
col += 1;
while(col < n){
CheckAppearingInColumn(matrix);
}
return false;
}
int main() {
printf("Please enter your sodoku dimension:");
scanf("%d", &n);
int a[n][n];
printf("\nInsert your sodoku board\n");
printf("Instruction: Enter 0 for blank\n");
for(int i=0; i<n; i++){
for(int j=0; j<n; j++) {
scanf("%d", &a[i][j]);
}
}
if (CheckAppearingInRow(a)== true || CheckAppearingInColumn(a) == true) {
printf("\nNo solution!\n");
}
return 0;
}

Related

Saving of 2-D array to the binary file in C language

I'm trying to save a 2-D array of integers to a binary file. The problem is that only the first row of the 2-D array is ​​saved. Below I have attached the outputs from which you will better understand the problem. Thanks in advance for the help.
#include <stdio.h>
#include <stdlib.h>
#define N_MAX 100
// Declaration of functions
int readMatrix(FILE *fp, int matrix[N_MAX][N_MAX]);
void printMatrix(int matrix[N_MAX][N_MAX], int size);
void switchMax(int matrix[N_MAX][N_MAX], int size);
int avg(int matrix[N_MAX][N_MAX], int size);
int sumDown(int matrix[N_MAX][N_MAX], int size);
int sumUp(int matrix[N_MAX][N_MAX], int size);
void sortMainDiagonal(int matrix[N_MAX][N_MAX], int size);
int main()
{
int size, matrix[N_MAX][N_MAX], test[N_MAX][N_MAX];
FILE *fp;
fp = fopen("input.txt", "r");
if (fp != NULL)
{
size = readMatrix(fp, matrix);
fclose(fp);
switchMax(matrix, size);
avg(matrix, size);
sortMainDiagonal(matrix, size);
printf("\nOriginal matrix: \n");
printMatrix(matrix, size);
// SAVE ON BINARY FILE
fp = fopen("output.bin", "w");
if (fp != NULL)
{
fwrite(matrix, sizeof(int), size*size, fp);
fclose(fp);
} else {
printf("Error #e2");
}
// READ FROM BINARY FILE
fp = fopen("output.bin", "r");
if (fp != NULL)
{
fread(test, sizeof(int), size*size, fp);
fclose(fp);
printf("\nMatrix from file: \n");
printMatrix(test, size);
} else {
printf("Error #e3");
}
} else {
printf("Errore #e1");
}
}
// Definition of functions
int readMatrix(FILE *fp, int matrix[N_MAX][N_MAX])
{
int size = 0;
fscanf(fp, "%d", &size);
for (int i = 0; i < size; i++)
for (int j = 0; j < size; j++)
fscanf(fp, "%d", &matrix[i][j]);
return size;
}
void printMatrix(int matrix[N_MAX][N_MAX], int size)
{
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
printf("%d ", matrix[i][j]);
}
printf("\n");
}
}
void switchMax(int matrix[N_MAX][N_MAX], int size)
{
int max = 0, row = 0;
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
if (matrix[j][i] > max)
{
max = matrix[j][i];
row = j;
}
}
matrix[row][i] = matrix[i][i];
matrix[i][i] = max;
max = 0;
}
}
int avg(int matrix[N_MAX][N_MAX], int size)
{
int avg;
avg = (sumDown(matrix, size) + sumUp(matrix, size)) / 2;
matrix[size-1][size-1] = avg;
return avg;
}
int sumDown(int matrix[N_MAX][N_MAX], int size)
{
int sum = 0;
for (int i = 1; i < size; i++)
for (int j = 0; j < i; j++)
sum += matrix[i][j];
return sum;
}
int sumUp(int matrix[N_MAX][N_MAX], int size)
{
int sum = 0;
for (int i = 0; i < size-1; i++)
for (int j = i+1; j < size; j++)
sum += matrix[i][j];
return sum;
}
void sortMainDiagonal(int matrix[N_MAX][N_MAX], int size)
{
int temp;
for (int i = 0; i < size-1; i++)
{
for (int j = 0; j < (size-1-i); j++)
{
if (matrix[j][j] > matrix[j+1][j+1])
{
temp = matrix[j][j];
matrix[j][j] = matrix[j+1][j+1];
matrix[j+1][j+1] = temp;
}
}
}
}
Screenshot of outputs from 'printMatrix' function:
click
File 'input.txt':
4
5 6 1 8
1 20 3 4
9 0 11 12
13 4 15 1
You don't show the value for N_MAX, but your image (which should be text in the question!) shows a 4x4 matrix. In future, please create an MCVE (Minimal, Complete, Verifiable Example).
However, let's suppose N_MAX is 16 or more (but that dim is 4). Then your code to write the matrix is writing a lot of zeroes. And skipping the other data.
Your matrix looks like:
13 6 1 8 0 0 0 0 0 0 0 0 0 0 0 0
1 15 3 4 0 0 0 0 0 0 0 0 0 0 0 0
9 0 20 1 0 0 0 0 0 0 0 0 0 0 0 0
5 4 11 26 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
And the fwrite() writes the first 16 integer values reading across. As you demonstrated, 12 of those are zeros.
To write a sub-array, you'll have to write the dim entries of each of the matrix's first dim rows separately.
for (size_t i = 0; i < dim; i++)
{
if (fwrite(matrix[i], sizeof(int), dim, fp) != dim)
err_syserr("short write on row %zu of matrix\n", i);
}
And similarly with the fread() code.
The function `err_syserr()` formats and prints the given error message and the system error message associated with `errno` before exiting with a non-zero (failure) status. A comprehensive suite of error reporting functions is available in my [SOQ](https://github.com/jleffler/soq) (Stack Overflow Questions) repository on GitHub as files `stderr.c` and `stderr.h` in the [src/libsoq](https://github.com/jleffler/soq/tree/master/src/libsoq) sub-directory.*\

Function. 2 2D arrays, the second is full of 0's, after applying condition,copy the whole row from first 2D array to the second 2D array

So, for example I have 2 Arrays, one is
0 -1 1 0 1
0 -1 0 0 0
0 1 1 -1 0
0 0 0 -1 0
0 -1 0 1 0
the second is full of 0's.
After I meet the condition a[i][j] == -1 && a[i][k] == 1, where k=j+1, I need to copy the whole row and put it into the second array, so the result should be:
0 -1 1 0 1
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 -1 0 1 0
I've already alloced the memory for both arrays, and here's the part of the code that I've tried but it doesnt work, it copies the whole array
void copy_row(int **a, int **b, int m){
for(int i=0; i<m; i++){
b[i]=a[i];
}
}
int main(){
...
for(int i=0 ; i<n ; i++){
for(int j=0 ; j<m ; j++){
for(int k=j+1; k<m ; k++){
if (a[i][j]==-1 && a[i][k]==1){
copy_row(a,b,n);
}
}
}
}
If you want to copy a row, you would need to pass the index of the current row to copy_row, plus the number of columns.
The call from main could be
// Notice that we pass index i and not n
copy_row(m, a, b, i);
The copy_row could be:
void copy_row(int numOfColumns, int a[][numOfColumns], int b[][numOfColumns], int rowIndex) {
for (int ii = 0, ii < numOfColumns, ++ii) {
b[rowIndex][ii] = a[rowIndex][ii];
}
}
You could add a break after the call to copy_row in the if statement. Once a row is copied, there is no need to keep checking the rest of the columns for -1.
E.g., you might reduce the checks made by using
for(int j = 0 ; j < m ; ++j) {
if (a[i][j] == -1) {
for(int k = j + 1; k < m ; ++k) {
if (a[i][k] == 1) {
copy_row(m, a, b, i);
break;
}
}
break;
}
}

Transpose of sparse matrix in C

I've been trying to write a program that displays the sparse matrix and also finds the transpose of the matrix, but while transposing only the elements of the first row of the original matrix are getting transposed and all the other elements from other rows are getting ignored. I need some help.
Here's the code I've written
#include <stdio.h>
#include <stdlib.h>
struct Element{
int i;
int j;
int x;
};
struct Sparse{
int m;
int n;
int num;
struct Element *ele;
};
void create(struct Sparse *s){
printf("Enter the dimensions ");
scanf("%d%d",&s->m, &s->n );
printf("Number of non-zero elements");
scanf("%d",&s->num);
s-> ele= (struct Element*) malloc(s->num * sizeof(struct Element));
printf("Enter all non-zero elements\n");
for (int i = 0; i< s->num; i++)
{
scanf("%d%d%d",&s->ele[i].i,&s->ele[i].j,&s->ele[i].x);
}
}
void display(struct Sparse s){
int i,j,k=0;
for (i = 0; i < s.m; i++)
{
for (j = 0; j < s.n; j++)
{
if(i==s.ele[k].i && j== s.ele[k].j)
printf("%d ",s.ele[k++].x);
else
printf("0 ");
}
printf(" \n");
}
}
void createTranspose(struct Sparse *t, struct Sparse s){
t->m = s.n;
t->n = s.m;
t->num = s.num;
t-> ele= (struct Element*) malloc(t->num * sizeof(struct Element));
printf("Enter all non-zero elements\n");
for (int i = 0; i< t->num; i++)
{
t->ele[i].i= s.ele[i].j;
t->ele[i].j= s.ele[i].i;
t->ele[i].x= s.ele[i].x;
}
}
int main(){
struct Sparse s, t;
create(&s);
display(s);
createTranspose(&t,s);
printf("Transpose of the matrix is \n");
display(t);
return 0;
}
Output
Enter the dimensions 6 6
Number of non-zero elements6
Enter all non-zero elements
0 0 1
0 2 2
0 4 3
2 3 4
4 1 5
5 5 6
1 0 2 0 3 0
0 0 0 0 0 0
0 0 0 4 0 0
0 0 0 0 0 0
0 5 0 0 0 0
0 0 0 0 0 6
Enter all non-zero elements
Transpose of the matrix is
1 0 0 0 0 0
0 0 0 0 0 0
2 0 0 0 0 0
0 0 0 0 0 0
3 0 0 0 0 0
0 0 0 0 0 0
Some help to get a proper output would be highly appreciated.
Your display function assumes that the sparse elements are in row-major order, but after simple transpose they're now in column-major order.
Either you need to re-sort the sparse elements that they retain the row-major ordering, or you need an inner loop in your display routine:
for (k = 0; k < s.num; k++) {
if (i == s.ele[k].i && j == s.ele[k].j) {
printf("%d ", s.ele[k].x);
break;
}
}
// not found among the sparse elements
if (k == s.num) {
printf("0 ");
}

Convert decimal values in 1D array to 2D array with bit values, transpose the 2D bit array and convert to 1D decimal array again

My problem is part of a larger communication algorithm I'm trying to implement. The point is to generate packets from messages, to send over the network. You fetch a batch of messages (decimal values), and form the packets from the bits from each message that are in the same column. The following figure illustrates this.
Packet formation from messages
My problem is the 'transpose' operation. How I'm trying to approach this is by transposing the bits of this 1D decimal value array of messages. Maximum decimal value of each message is 255, so 8 bits in length each.
I want to convert all decimal values to bits in a 2D array, where each column is a bit from the decimal value in that row. Finally I want to convert this 2D bit array to a 1D array with decimal values again.
Example:
Input is a decimal 1D array
decimal[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
Convert this 1D array to a 2D array representing the bits
bits[16][8] = { 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1
0 0 0 0 0 0 1 0
0 0 0 0 0 0 1 1
....
0 0 0 0 1 1 1 1 };
Transpose this bit array
bits2[8][16] = {
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1
0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1
0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 };
Convert it back to a decimal value 1D array
result[8] = { 0, 0, 0, 0, 255, 3855, 13107, 21845}
The code I have so far:
#define n 8 // COLUMNS
#define m 16 // ROWS
int data[m];
int result[n];
int i,j;
int counter = 0;
memset(data, 0, sizeof(data));
memset(result, 0, sizeof(result));
for ( i = 0; i < m; ++i) {
data[i] = counter;
++counter;
}
int a[m][n], b[n][m], x;
// Convert decimal array to 2D bit array
for(i=0; i<m; i++)
{
x = data[i];
for(j=0; j<n; j++)
{
a[i][j] = (x & 0x8000) >> 8;
x <<= 1;
}
}
// Transpose bit array
for(i=0; i<m; i++)
{
for(j=0; j<n; j++)
{
b[j][i] = a[i][j];
}
}
// Convert back to decimal
for(i=0; i<n; i++)
{
for(j=0; j<m; j++)
{
if (b[i][j] == 1) result[i] = result[i] * 2 + 1;
else if (b[i][j] == 0) result[i] *= 2;
}
}
I hope my explanation is clear! If not, I'll gladly explain some more. I've searched endlessly for ways to do this but I'm still not getting up with a solid solution.
PS: Apologies for the bad code formatting of the arrays, didn't find a proper way to visualize it without linking an image.
This should provide the desired output.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define n 8 // COLUMNS
#define m 16 // ROWS
int main(void)
{
int data[m];
int result[n];
int i, j;
int counter = 0;
memset(data, 0, sizeof(data));
memset(result, 0, sizeof(result));
for (i = 0; i < m; ++i) // print initial data
{
data[i] = counter;
printf("%d ", data[i]);
++counter;
}
putchar('\n');
char a[m][n], b[n][m];
int x;
// Convert decimal array to 2D bit array
for (i = 0; i < m; i++)
{
x = data[i];
for (j = n - 1; j >= 0; j--)
{
a[i][j] = x & 1;
x >>= 1;
}
}
// Transpose bit array
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
b[j][i] = a[i][j];
}
}
// Convert back to decimal
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
if (b[i][j] == 1)
result[i] = result[i] * 2 + 1;
else if (b[i][j] == 0)
result[i] *= 2;
}
}
for (i = 0; i < n; ++i) // print result
{
printf("%d ", result[i]);
}
putchar('\n');
return 0;
}
What you were doing wrong was the conversion to the 2d bit array , it was all filled with 0's.
You were doing (x&0x8000) >> 8;
0x8000 = 1000 0000 0000 0000 (grouped in nibbles to see clearly)
so (x&0x8000) will always be 0 considering that x will in your case take values <=255 .
I also changed the int arrays which were using way too much space than needed to char arrays.

Median windows in C

I wrote a code to find median filtering (median window). But, I can't make scannig to every number. What can I use instead of size in the for loops. When I use size it ensures just 5 Also, what about boundries ? What can I do for boundries ? Thank you for all appreciated answers. (I've opened new topic because users said that every topic is based on one question.If I did mistake,please delete the question, I will suffix the current question)
<size of array>
<size filter>
<data>
8
3
0 0 0 0 0 0 0 0
0 5 0 0 6 0 0 0
0 0 0 0 0 7 0 0
0 0 0 0 5 0 0 0
0 0 0 5 6 0 0 0
0 0 8 5 5 0 0 0
0 0 0 7 0 0 9 0
0 0 0 0 0 0 0 0
Output:
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 5 5 0 0 0
0 0 0 5 5 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
#include <stdio.h>
int median(int a[100],int n);
int main()
{
int a[100][100];
int temp[100];
int i,j,k,count=0;
int sizefilter;
int sizearray;
scanf("%d", &sizearray);
scanf("%d", &sizefilter);
for(i = 0; i < sizearray; i++)
for(j = 0; j < sizearray; j++)
scanf("%d", &a[i][j]);
for(k = 0; k < sizearray; k++)
for(i = 0; i < sizefilter; i++)
for(j = 0; j < sizefilter; j++)
{
temp[count] = a[i][j];
count++;
a[i][j] = median(temp, count);
}
printf("\n");
printf("\n");
for(i = 0; i < sizearray; i++)
for(j = 0; j < sizearray; j++)
{
printf("%d ", a[i][j]);
if(j == sizearray-1)
printf("\n");
}
return 0;
}
int median(int a[100],int n)
{
int i,j,t;
int result;
/* Sorting begins */
for (i = 1 ; i <= n-1 ; i++)
{ /* Trip-i begins */
for (j = 1 ; j <= n-i ; j++)
{
if (a[j] <= a[j+1])
{ /* Interchanging values */
t = a[j];
a[j] = a[j+1];
a[j+1] = t;
}
else continue ;
}
} /* sorting ends */
/* calculation of median */
if ( n % 2 == 0)
return result = (a[n/2] + a[n/2+1])/2 ;
else
return result = a[n/2 + 1];
}
There are some logical errors in your code:
When you filter, you need four nested loops: The outer two iterate over columns and rows of the matrix, the inner two iterate over columns and rows of the filter area. (That shouldn't be news to you; you have already been told that in an answer to your previous question.)
The constraints of the filter area are simple: The left and top indices must not fall below zero and the right and bottom indicies must be smaller than sizearray. If they are not, adjust them.
You need two arrays, the original array a and a second array that contains the filtered values. You cannot filter in-place, because if you look upwards and to the left, you'll see only filtered values, whereas your filter should always look at the original values.
Your wrong filtering loops apart: You never reset count, which you should reset, of course, for every median value you calculate. You also calculate the median in the inner loop, which is too often. A solution to this is to make count local to the loop that accumulates filter values and determines the median.
Your sorting has index errors. Instead of comparing i with i + 1, compare with ´i - 1. Your indices start from 1, soi - 1` will always yield a valid index.
You buble-sort the array, which is fine for small arrays, but slow in general. The <stdlib.h> has qsort, which may be useful to you for general sorting.
Your median indices are also off by one towards the right.
There are also some stylistic issues:
Please make a habit of using braces for code blocks for for, while and if. Only very trivial code blocks in the innermost scope can be written without braces. In your case, a lot has to be done "between" the loops, and having braces there makes it easy to add stuff.
Yor variable result in median is superfluous. You assign it and then immediately lose the variable itself, because you return. Just returning is enough.
Below is a version of your code that gives the desired output:
#include <stdint.h>
#include <stdio.h>
int min(int a, int b)
{
return a < b ? a : b;
}
int max(int a, int b)
{
return a > b ? a : b;
}
int median(int a[], int n)
{
int i, j;
for (i = 1 ; i < n ; i++) {
for (j = 1 ; j < n ; j++) {
if (a[j] < a[j - 1]) {
int t = a[j];
a[j] = a[j - 1];
a[j - 1] = t;
}
}
}
if (n % 2) return a[n / 2];
return (a[n / 2 - 1] + a[n / 2]) / 2 ;
}
int main()
{
int a[100][100];
int b[100][100];
int temp[100];
int i, j, ii, jj;
int sizefilter;
int sizearray;
scanf("%d", &sizearray);
scanf("%d", &sizefilter);
for(i = 0; i < sizearray; i++) {
for(j = 0; j < sizearray; j++) {
scanf("%d", &a[i][j]);
}
}
for(i = 0; i < sizearray; i++) {
for(j = 0; j < sizearray; j++) {
int imin = max(0, i - sizefilter / 2);
int imax = min(sizearray, i + sizefilter / 2 + 1);
int jmin = max(0, j - sizefilter / 2);
int jmax = min(sizearray, j + sizefilter / 2 + 1);
int count = 0;
for (ii = imin; ii < imax; ii++) {
for (jj = jmin; jj < jmax; jj++) {
temp[count] = a[ii][jj];
count++;
}
}
b[i][j] = median(temp, count);
}
}
for(i = 0; i < sizearray; i++) {
for(j = 0; j < sizearray; j++) {
printf("%3d", b[i][j]);
}
printf("\n");
}
return 0;
}

Resources