Finding Duplicate value in 2d array 3x3 magic Square - c

Im trying to create a 2D array 3x3 square.
Calculation and checking for it is done.
Right now, am trying to prevent repeated numbers from happening in the 2d array.
I tried using a for loop to brute force but cygwin compiles gives me error
Below is my code.
How do i go about checking 2d array?
#include <stdio.h> /* printf */
/*Preprocessor*/
/*set N constant 3*/
#define N 3
typedef enum {false,true}
bool;
int main()
{
/*initialize size to 3*/
int size =3;
int sum, sum1, sum2,array[N][N];
int row, col = 0;
int i, j, duplicate =0;
/* variable to
indicate process reached*/
int checkf =0;
/*input into the array of an array*/
for(row =0; row <size; row++)
{
for(col =0; col < size; col++)
{
scanf("%d", &array[row][col]);
}
}
**/*check for repeated values*/
for(row =0; row<9; row++)
{
for(col=0; col <9; col++)
{
if(array==array[row][col])
}
}**
/*Diagonal*/
/*sum of diagonal from the left
equals to sum of diagonal
from the right */
/*initialize sum2 to 0*/
sum2 =0;
/*check if row less than 3*/
for(row=0; row< size; row++)
{
/*check if col less than 3*/
for(col=0;col<size; col++)
{
/*number of row
equals number of col*/
if(row == col)
{
/*addition*/
sum2 = sum2 + array[row][col];
}
}
}
/*row*/
/*check if row less than 3*/
for(row=0; row < size; row++)
{
/*initialize sum */
sum = 0;
/*check if col less than 3*/
for(col=0; col <size; col++)
{
/*addition of numbers*/
sum = sum + array[row][col];
}
/*check if all additions
adds up to same sum*/
if(sum2 == sum)
{
/*a flag or check to print*/
checkf =1;
}
else
{
/*a flag or check to print*/
checkf =0;
break;
}
}
/*Columns*/
/*check if row less than 3*/
for(row = 0; row < size; row++)
{
/*initialize sum */
sum1 =0;
/*check if col less than 3*/
for(col = 0; col < size; col++)
{
/*addition*/
sum1 = sum1 + array[col][row];
}
/*sum of diagonal equals
sum of columns*/
if(sum == sum1)
{
/*a flag or check to print*/
checkf =1;
}
else
{
/*a flag or check to print*/
checkf =0;
break;
}
}
/*if statement is true
prints and display*/
if(checkf ==1)
{
printf("This is a magic square.\n");
}
else
{
/*print and display*/
printf("This is not a magic square.\n");
}
return 0;
}

If you had a flat, one-dimensional array (of fixed size N, say), you would check all elements against every element to its left:
int unique1d(int array[N])
{
int i, j;
for(i = 1; i < N*N; i++) {
for(j = 0; j < i; j++) {
if (array[i] == array[j]) return 0;
}
}
return 1;
}
You can do the same for a two-dimensional array, when you "flatten" the indices first. Say you enumerate the cells of your 3×3 grid with "flat" indices like so:
0 1 2
3 4 5
6 7 8
Then you get:
flat = row * N + col;
and, conversely:
row = flat / N; // truncating int division gives row
col = flat % N; // remainder gives column
So a function that tests whether there are duplicates in your N×N grid would look like this:
int unique(int array[N][N])
{
int i, j;
for(i = 1; i < N*N; i++) {
for(j = 0; j < i; j++) {
if (array[i / 3][i % 3] == array[j / 3][j % 3]) return 0;
}
}
return 1;
}
I've made that into a separate function, because it makes the code clearer. Not how you don't need a separate flag and a break. You can return the result explicitly as soon as you have found it. (Also, the break would have to break out of a nested loop, but the break keyword in C just jumps out of the inner loop.)
(The rest of your code that checks whether the square is magic or not looks a bit suspicious, too. For example, you should start with the assumption that the square is magic and then set your flag to false if one of the conditions for a magic square doesn't hold. You never have to set that flag back to true again. But that's a topic for another question.)
Edit: In order to explain the function better, here's example client code. This is essentially your program without the magic check. N must be a defined constant, as it is in your program.
int main()
{
int array[N][N];
int row, col;
for(row =0; row < N; row++) {
for(col =0; col < N; col++) {
scanf("%d", &array[row][col]);
}
}
if (unique(array)) {
puts("Values are unique");
} else {
puts("There are duplicate values.");
}
return 0;
}

Related

PS command on this program

In an assignment, I wrote 2 programs that do the same thing, but one of them uses threads. What I'm asked to do is to stop the programs while they are running and use the ps command to compare the two programs, the problem is that I don't know how to do this, I wanted to try stopping the programs using ^z but the programs execute so fast that I can't even do it, is there a way to do what I'm asked to do? is using functions like sleep will help me? or does it affect the results of the ps command?
Here're the programs that I wrote in case it helps and I can modify them to do what I want.
without threads:
#include <stdio.h>
int main(void) {
int mat[100][100]; // Declare the array
// Generate the values for the array
for (int row = 0; row < 100; row++) {
for (int col = 0; col < 100; col++) {
mat[row][col] = row * 5 + col / 3 + col;
}
}
// Sum up the values in the array
int sum = 0;
for (int row = 0; row < 100; row++) {
for (int col = 0; col < 100; col++) {
sum += mat[row][col];
}
}
// Print the result
printf("Sum of all values in mat: %d\n", sum);
return 0;
}
with threads:
#include <stdio.h>
#include <pthread.h>
#define NUM_THREADS 100 // Number of threads (one for each column)
#define ROWS 100 // Number of rows in the array
#define COLS 100 // Number of columns in the array
int mat[ROWS][COLS]; // Array to store the values
int sums[COLS]; // Array to store the sums for each column
// Thread function to sum up a column of the array
void* sum_column(void* arg) {
int col = (int)arg; // Column to sum up
// Sum up the values in the column
int sum = 0;
for (int row = 0; row < ROWS; row++) {
sum += mat[row][col];
}
// Store the result in the sums array
sums[col] = sum;
return NULL;
}
int main(void) {
pthread_t threads[NUM_THREADS]; // Threads
// Generate the values for the array
for (int row = 0; row < ROWS; row++) {
for (int col = 0; col < COLS; col++) {
mat[row][col] = row * 5 + col / 3 + col;
}
}
// Create a thread for each column to sum it up
for (int col = 0; col < COLS; col++) {
pthread_create(&threads[col], NULL, sum_column, (void*)col);
}
// Wait for all threads to finish
for (int col = 0; col < COLS; col++) {
pthread_join(threads[col], NULL);
}
// Sum up the values in the sums array
int sum = 0;
for (int col = 0; col < COLS; col++) {
sum += sums[col];
}
// Print the result
printf("Sum of all values in mat: %d\n", sum);
return 0;
}

Delete duplicate rows and columns of matrix

I need to delete (not skip while printing) the rows and columns of a matrix that appear more than once in program, and I should print only first row from the top that appears more than once or the first column from the left that appears more than once.
Example input:
1 2 3 2
4 5 6 5
1 2 3 2
7 8 9 8
After deleting:
1 2 3
4 5 6
7 8 9
Here's my code:
#include <stdio.h>
int main() {
int i, j, m, n,row,col, mat[200][200];
scanf("%d %d", &m, &n);
row = m; col = n;
for (i = 0; i < m; i++)
for (j = 0; j < m; j++)
scanf("%d", &mat[i][j]);
for (i = 0; i < m; i++)
for (j = 0; j < m; j++) {
if (mat[i][j] == mat[i++][j++])
row--;
if (mat[j][i] == mat[j++][i++])
col--;
}
for (i = 0; i < row; i++) {
for (j = 0; j < col; j++) {
printf("%d ", mat[i][j]);
}
printf("\n");
}
return 0;
}
Do you have any idea how to make the algorithm work for this task? Mine has mistakes.
Would you please try the following:
#include <stdio.h>
#define ROWS 200
#define COLS 200
#define TRUE 1
#define FALSE 0
/*
* delete k'th row from the m x n matrix
*/
void deleterow(int mat[ROWS][COLS], int m, int n, int k)
{
int i, j;
for (i = k; i < m - 1; i++) {
for (j = 0; j < n; j++) {
mat[i][j] = mat[i + 1][j];
}
}
}
/*
* delete k'th columns from the m x n matrix
*/
void deletecol(int mat[ROWS][COLS], int m, int n, int k)
{
int i, j;
for (j = k; j < n - 1; j++) {
for (i = 0; i < m; i++) {
mat[i][j] = mat[i][j + 1];
}
}
}
int main() {
int i, j, m, n,row,col, mat[ROWS][COLS];
int iref, jref; // reference indexes to compare
int match; // flag to show if the row/col duplicates
// read input matrix
scanf("%d %d", &m, &n);
row = m; col = n;
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
scanf("%d", &mat[i][j]);
// examine row by row
for (iref = 0; iref < m; iref++) {
// compare rows below iref and remove the row if duplicates
for (i = iref + 1; i < m; i++) {
match = TRUE;
for (j = 0; j < n; j++) {
if (mat[i][j] != mat[iref][j]) {
match = FALSE;
break;
}
}
if (match) {
deleterow(mat, m, n, i);
m--;
}
}
}
// examine column by column
for (jref = 0; jref < n; jref++) {
// compare columns more right than jref and remove the col if duplicates
for (j = jref + 1; j < n; j++) {
match = TRUE;
for (i = 0; i < m; i++) {
if (mat[i][j] != mat[i][jref]) {
match = FALSE;
break;
}
}
if (match) {
deletecol(mat, m, n, j);
n--;
}
}
}
// see the result
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
printf("%2d%s", mat[i][j], j == n - 1 ? "\n" : " ");
}
}
return 0;
}
Output with the provided example:
1 2 3
4 5 6
7 8 9
[Explanation]
As for the operations of rows:
First, focus on the top row as a "reference". The row is indexed by
the variable iref which is assigned to 0 at first.
Then compare the remaining rows with the reference, changing
the row index i from iref+1 (just below the reference row) to n-1
(the bottom row).
If a row duplicates with the reference, remove the row with the
deleterow() function and decrement the row size m by one.
The modification of m affects the for loops which compare the
loop variables with m, meaning the matrix size is updated immediately.
This is a preferable nature of the for loop (IMHO).
If the comparizon reaches the bottom row, increment iref and repeat
the comparisons again.
Finally every row has been compared to each other and the duplicates have
been deleted.
Then perform the similar operations with columns.

C language how to remove or not show rows with 0 value column

for example, we have this
0 1 0 1
0 3 1 0
0 1 5 0
0 0 0 0
matrix I want to show just rows and columns with non zero elements
the final matrix view should be this
1 0 1
3 1 0
1 5 0
how can I remove the row and the columns with zero elements
my code
#include <stdio.h>
int main()
{
int a[100],row,col,i,j,count=0,k=0;
scanf("%d %d", &row, &col);
int matrix[row][col];
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
scanf("%d", &matrix[i][j]);
}
}
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if(matrix[i][j]==0)
{
count++;
}
}
}
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
printf("%d ", matrix[i][j]);
}
printf("\n");
}
}
return 0;
}
what condition should I set for count++ I'm new in c developing staff.
Judge if each rows and columns should be shown.
Print only rows and columns that should be shown.
#include <stdio.h>
int main(void)
{
int row,col,i,j;
// read the matrix
if (scanf("%d %d", &row, &col) != 2)
{
fputs("read error\n", stderr);
return 1;
}
int matrix[row][col];
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (scanf("%d", &matrix[i][j]) != 1)
{
fputs("read error\n", stderr);
return 1;
}
}
}
// judge if each rows should be shown
int show_row[row];
for (i = 0; i < row; i++)
{
show_row[i] = 0;
for (j = 0; j < col; j++)
{
if(matrix[i][j]!=0)
{
// non-zero element found, so this row should be shown
show_row[i] = 1;
}
}
}
// judge if each columns should be shown
int show_col[col];
for (j = 0; j < col; j++)
{
show_col[j] = 0;
for (i = 0; i < row; i++)
{
if(matrix[i][j]!=0)
{
// non-zero element found, so this column should be shown
show_col[j] = 1;
}
}
}
// show rows and columns that should be shown
for (i = 0; i < row; i++)
{
if (show_row[i])
{
for (j = 0; j < col; j++)
{
if (show_col[j])
{
printf("%d ", matrix[i][j]);
}
}
printf("\n");
}
}
return 0;
}
Transpose the matrix ignoring rows with all zeros into a new matrix.
Transpose the new matrix ignoring all-zero rows into a second new matrix.
Print the second matrix.
int m1[4][4], m2[4][4], m[4][4] = {
{0, 1, 0, 1},
{0, 3, 1, 0},
{0, 1, 5, 0},
{0, 0, 0, 0},
};
transpose_notzero(m1, m); // m1 = T(m); ignore all-zero rows
transpose_notzero(m2, m1); // m2 = T(m1); ignore all-zero rows
mat_print(m2);
Instead of the loop where you count the number of elements being equal to zero, you could register which rows/columns that contains non-zero values.
Like:
int non_zero_row[row];
int non_zero_col[col];
memset(non_zero_row, 0, row * sizeof non_zero_row[0]); // Set to zero, i.e. expect
memset(non_zero_col, 0, col * sizeof non_zero_col[0]); // that the row/col is all-zero
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if(matrix[i][j] != 0)
{
non_zero_row[i] = 1; // Mark row as containing a non-zero value
non_zero_col[j] = 1; // Mark row as containing a non-zero value
}
}
}
Later in the code you can use the two "boolean" arrays to determine what to do with the element. Something like:
if (non_zero_row[i] && non_zero_col[j])
{
// Do something with element [i][j], e.g. print it
}
In principle you don't need to calculate the "boolean" arrays in a separate loop. You could update the "boolean" arrays just after scanf("%d", &matrix[i][j]) and thereby avoid an extra loop.
BTW: Be careful with VLAs. Your current code doesn't check the array dimensions before creating the matrix. Users of your program can enter big values which may result in stack overflow.

2d array and for loops

I did this code to try the basic operations on bidimensional arrays (2d arrays), but it doesn't print
on screen the letter 'A'.
Can someone help me figure this out?
Thanks
#include <stdio.h>
#define ROWS 2
#define COLS 3
int main()
{
int x;
int y;
int i;
int j;
int Field[ROWS][COLS];
printf("Enter two values: ");
scanf("%d %d", &x, &y);
Field[y][x] = 1;
for(i = ROWS - 1; i > 0; i--){
for(j = 0; j < COLS; j++){
if(Field[i][j] == 1){
printf("A");
}
}
}
return 0;
}
In the outer loop
for(i = ROWS - 1; i > 0; i--){
the range of indices is (in the descending order) [ROWS-1, 1], So the index 0 is not processed in this loop.
It is better such a loop to write the following way
for ( i = ROWS; i != 0; i-- ){
for(j = 0; j < COLS; j++){
if(Field[i-1][j] == 1){
printf("A");
}
}
}
In this case the variable i can have even an unsigned integer type as for example size_t and the code will be valid even when ROWS is equal to 0.
Otherwise the expression ROWS - 1 can yield the maximum value of the unsigned type when ROWS is equal to 0.
as mentioned i>0 should be i>=0 other wise you won't traverse the array completely.
also note that even after you you corrected that statement , it's better to check input x and y , because if they are greater or equal to ROWS and COLS , than by passing boundaries of your array here Field[y][x] = 1; your program will lead to undefined behavior.
so I suggest this
scanf("%d %d", &x, &y);
if (x < ROWS && y < COLS)
Field[y][x] = 1;
else
return 0;
//rest of your code with i>=0 in this loop for(i = ROWS - 1; i >= 0; i--)
This: for(i = ROWS - 1; i > 0; i--){ fails to traverse the necessary array location, and does not clearly convey to future maintainers of your software what exactly the intent is.
However, to do what you have described in your problem description, unless there is a compelling reason to set up a decrementing index (--), a normal incrementing (++) set of for loops is adequate and more idiomatic :)
for(i = 0; i < ROWS; i++)
{
for(j = 0; j < COLS; j++)
{
if(Field[i][j] == 1)
{
printf("A");
}
}
}
This code adds some protections to out of bounds arrays and prints 'A'. Should be a good starting point for you.
#include <stdio.h>
#define ROWS 2
#define COLS 3
int main()
{
int x,y,i,j = 0;
int Field[ROWS][COLS]; // 2 Rows 3 Column array
printf("\nEnter row value less than %i: ",ROWS);
scanf("%d", &y);
printf("\nEnter column value less than %i: ",COLS);
scanf("%d", &x);
if(x >= COLS || y>= ROWS)
{
printf("\nOut of bounds inputs!");
return 0;
}
Field[y][x] = 1;
for(i = ROWS - 1; i > 0; i--)
{
for(j = 0; j < COLS; j++)
{
if(Field[i][j] == 1)
{
printf("A");
}
}
}
return 0;
}

How can I keep my program from getting this segmentation fault (core dumped)?

I have a program that is getting a segmentation fault. The program is a magic square program and asks users for the size of a square (a matrix) and then for the numbers of the square by row. I am using a pointer to point to the array in the declareArray function to reference where it is declared in the main function. I want to keep the pointer in order to practice using them, even though I know I can make the program work without pointers. I think the pointer is the problem here but I cant find what I am doing wrong with it.
here is the code:
int main(void)
{
int *arr[SIZE][SIZE] = "\0";
declareArray(&arr);
declareArray();
return 0;
}
//main logic
int declareArray(int *arr[SIZE][SIZE])
{
//variables
int rowNumber = 0;
int dimension = 0;
//int arr[SIZE][SIZE] = {0};
int row, col;
int sum, sum1, sum2;
int flag = 0;
//ask for input of squares
printf("Please enter the dimension of the square: ");
//makes sure the size is between 1 and 15 for the dimension of the square
if(scanf("%d", &dimension) != 1 || dimension >= 15 || dimension < 1)
{
printf("invalid input\n");
return 1;
}
//enter the data
//array rows
for(row = 0; row < dimension; ++row)
{
printf("Please enter the data for row %d: ", ++rowNumber);
//array columns
for(col = 0; col < dimension; ++col)
{
//store the user input
scanf("%2d", &*arr[row][col]);
}
}
printf("\n");
printf("Here is the square");
printf("\n");
//print the square
//array rows
for(row = 0; row < dimension; ++row)
{
//array columns
for(col = 0; col < dimension; ++col)
{
printf("%d", *arr[row][col]);
}
printf("\n");
}
//Checks Sum of diagonal elements
sum = 0;
for (row = 0; row < dimension; row++) {
for (col = 0; col < dimension; col++) {
if (row == col)
sum = sum + *arr[row][col];
}
}
//Checks Sum of Rows
for (row = 0; row < dimension; row++) {
sum1 = 0;
for (col = 0; col < dimension; col++) {
sum1 = sum1 + *arr[row][col];
}
if (sum == sum1)
flag = 1;
else {
flag = 0;
break;
}
}
//Checks sum of Columns
for (row = 0; row < dimension; row++) {
sum2 = 0;
for (col = 0; col < dimension; col++) {
sum2 = sum2 + *arr[col][row];
}
if (sum == sum2)
flag = 1;
else {
flag = 0;
break;
}
}
//if the sums match, it will print a success message with the constant
//if the sums dont match, a fail message will appear
if (flag == 1)
printf("\nTHE SQUARE IS A MAGIC SQUARE WITH A CONSTANT OF %d \n", sum);
else
printf("\nThe Square is not a magic square \n");
return 0;
}
I can see few issues here
int *arr[SIZE][SIZE] = "\0"; // this wont compile
declareArray(&arr); // needless
declareArray();
---
int arr[SIZE][SIZE] = {};
declareArray(arr);
//declareArray();
Declare function
int declareArray(int *arr[SIZE][SIZE]) // because function call changed
---
int declareArray(int arr[SIZE][SIZE])
finally in printf and scanf remove the * operator not needed anymore
as in
scanf("%2d", &*arr[row][col]); // remove *
---
scanf("%2d", &arr[row][col]);
printf("%d", *arr[row][col]); // remove *
---
printf("%d", arr[row][col]);
sum = sum + *arr[row][col]; // remove *
---
sum = sum + arr[row][col];
Note that when you declare an array, the name of the array is a pointer to the first element of the array:
&arr[0] == arr.
The argument passed to the declareArray function is an array of pointers to integers, therefore the space needed for the pointers was allocated yet the space for the actual ints was not, so when you are trying to scan an integer to the address pointed to by arr[row][col], you are trying to write to the address that it holds, 0 in your case , and address 0 is most likely out of the data segment, hence the segment_fault.
What should you do then?
Allocate the space needed with malloc(), assign the address returned to arr[row][col] and then scanf() as shown below, or alternatively, and quite simpler and better use an int array and simply assign the integer to arr[row][col] as shown in the answer above
#include <stdio.h>
#include <stdlib.h>
#define SIZE 15
int declareArray(int * arr[SIZE][SIZE]);
int main(void)
{
int * arr[SIZE][SIZE] = {0};
declareArray(arr);
return 0;
}
//main logic
int declareArray(int * arr[SIZE][SIZE])
{
//variables
int rowNumber = 0;
int dimension = 0;
int row, col;
int sum, sum1, sum2;
int flag = 0;
int * myVal;
//ask for input of squares
printf("Please enter the dimension of the square: ");
//makes sure the size is between 1 and 15 for the dimension of the square
if(scanf("%d", &dimension) != 1 || dimension >= 15 || dimension < 1)
{
printf("invalid input\n");
return 1;
}
//enter the data
//array rows
for(row = 0; row < dimension; ++row)
{
printf("Please enter the data for row %d: ", ++rowNumber);
//array columns
for(col = 0; col < dimension; ++col)
{
printf("insert data to row %d col %d: ", rowNumber, col+1);
arr[row][col] = (int *) malloc(sizeof(int));
scanf("%2d", arr[row][col] );
}
}
printf("\n");
printf("Here is the square");
printf("\n");
//print the square
//array rows
for(row = 0; row < dimension; ++row)
{
//array columns
for(col = 0; col < dimension; ++col)
{
printf("%d", *arr[row][col]);
}
printf("\n");
}
//Checks Sum of diagonal elements
sum = 0;
for (row = 0; row < dimension; row++) {
for (col = 0; col < dimension; col++) {
if (row == col)
sum = sum + *arr[row][col];
}
}
//Checks Sum of Rows
for (row = 0; row < dimension; row++) {
sum1 = 0;
for (col = 0; col < dimension; col++) {
sum1 = sum1 + *arr[row][col];
}
if (sum == sum1)
flag = 1;
else {
flag = 0;
break;
}
}
//Checks sum of Columns
for (row = 0; row < dimension; row++) {
sum2 = 0;
for (col = 0; col < dimension; col++) {
sum2 = sum2 + *arr[col][row];
}
if (sum == sum2)
flag = 1;
else {
flag = 0;
break;
}
}
//if the sums match, it will print a success message with the constant
//if the sums dont match, a fail message will appear
if (flag == 1)
printf("\nTHE SQUARE IS A MAGIC SQUARE WITH A CONSTANT OF %d \n", sum);
else
printf("\nThe Square is not a magic square \n");
return 0;
}

Resources