C Program- How to find sum of middle elements in a matrix? - c

Given a 2-Dimensional Array, sum up all the numbers that are not on the edges of the 2-D array.
Example 2-D Array:
5 7 1 6
2 6 1 8
1 5 4 7
5 8 9 1
4 4 5 1
The numbers added should only be 6+1+5+4+8+9.
int rows, cols,s1=0,s2=0;
printf("Enter number of rows: ");
scanf("%d", &rows);
printf("Enter number of columns: ");
scanf("%d", &cols);
int matrix[rows][cols];
printf("Elements:\n");
for(int row = 0; row < rows; row++){
for(int col = 0; col < cols; col++){
scanf("%d", &matrix[row][col]);
}
}
printf(Sum: %d", __);
......

Write a function:
static int sum_middle(int rows, int cols, int matrix[rows][cols])
{
int sum = 0;
for (int r = 1; r < rows - 1; r++)
{
for (int c = 1; c < cols - 1; c++)
sum += matrix[r][c];
}
return sum;
}
Then call it after your input loops:
int sum = sum_middle(rows, cols, matrix);

You could change your input functionality to calculate the sum as you go along:
int sum = 0;
for(int row = 0; row < rows; row++){
for(int col = 0; col < cols; col++){
scanf("%d", &matrix[row][col]);
if(
row && (rows > 2) && (row + 1) != rows &&
col && (cols > 2) && (col + 1) != cols
)
sum += matrix[row][col];
}
}
Or you could do this in a 2nd loop (see #JonathanLeffler's answer). This would allow you to do the rows and cols check only once instead of per iteration (i.e. if rows = INT_MAX and cols is 0, 1 or 2).

Let me explain you how to do this in pseudo-code:
You need to sum all numbers which don't pass a certain criteria. There are two ways to do this:
Sum all number which don't pass a certain criteria. This can be done if the criteria is not too difficult.
Sum all numbers. Sum all numbers who pass a certain criteria and subtract that from the first sum.
Let's see if we can accomplish in the first way: we start by summing all numbers:
sum = 0
for i = 0 to a-1:
for j = 0 to b-1:
sum += matrix[i,j];
next j
next i
Now we need to add the criteria:
sum = 0
for i = 0 to a-1:
for j = 0 to b-1:
if not(criteria(i,j))
then sum += matrix[i,j];
next j
next i
But what is the criteria: how to you say (i,j) belongs to an edge?
Well, that's quite simple: the edges mean that i equals either 0 or a, and j equals 0 or b:
So you write a function criteria(i,j) as follows:
boolean criteria(i,j):
return ((i == 0) OR (i == a)) AND
((j == 0) OR (j == b));
Or, as the criteria is so simple, you don't even need a function for this:
sum = 0
for i = 0 to a-1:
for j = 0 to b-1:
if not(((i == 0) OR (i == a)) AND
((j == 0) OR (j == b)))
then sum += matrix[i,j];
next j
next i
But as you might expect, there's an easier way to write the criteria, using not(x AND y) = not(x) OR not(y) and not (x OR y) = not(x) AND not(y), but this one I leave to you :-)

Related

Adding only row values of a matrix

int a[3][4], i, j;
int row_total;
printf("Enter matrix values : \n");
for (i = 1; i <= 3; i++) {
for (j = 1; j <= 4; j++)
scanf("%d", &a[i][j]);
}
row_total *= a[i][j];
if (row_total > 0) {
printf("%d\n", row_total);
}
The matrix in the example has 3 rows and 4 columns. The values of this matrix are determined by the user. There are examples everywhere in the form of the product of 2 matrices. But I couldn't find how to process the values in rows of a single matrix. I need to multiply the values that the user enters for the row. How can I find the product of the values written in the rows of the matrix?
In the last part, I just tried to print the values to see if I could read the matrix multiplication of the code. But I could not read the values and get any multiplication result.
initialization
Always initialize your variables
because when you don't initialize it, it will have a "garbage" value.
You had problems reading the values because of the garbage value in row_total.
https://stackoverflow.com/a/1597426/17652416
Arrays
Pay attention that arrays start from 0 not 1 so if the amount of rows is 4 for
example, the rows will be - 0, 1, 2, 3 and not 1, 2, 3, 4.
So the iterations should start from i = 0; i < 4 and not i = 1; i <= 4.
More about arrays in C
Fixed initialization
Defines
#define ROWS 3
#define COLS 4
int a[ROWS][COLS] = { 0 };
int row = 0, col = 0;
int row_total = 1;
printf("Enter matrix values : \n");
//Get the values for the matrix from the user
for (row = 0; row < ROWS; row++)
{
for (col = 0; col < COLS; col++)
{
scanf("%d", &a[row][col]);
}
}
Iterating on the rows - the answer
//Print the product of every row
for (row = 0; row < ROWS; row++)
{
row_total = 1;
for (col = 0; col < COLS; col++)
{
row_total *= a[row][col];
}
printf("The product of row %d is: %d\n", row, row_total);
}

Check if an array is mirrored in C

I'm trying to check if the inputted array of the user is mirrored or not
Users input:
//for the rows and column
3 3
//elements inside array
1 0 1
2 0 3
4 0 4
the output should tell if the first index and the last index of the array is the same, but the only thing that i have done is mirror it and print mirror even if its not the same
int main()
{
int arr[10][10];
int col,row;
scanf("%d %d", &col, &row);
for (int i = 0; i < col; i++) {
for (int j = 0; j < row; j++) {
scanf("%d", &arr[i][j]);
}
}
for (int i = 0; i < col; i++) {
for(int j = row - 1; j >= 0; j--) {
printf("Mirror");
}
}
}
the size of the array and the elements depends on the user, thank youuu
This is my solution for your problem, this code can have some isuess but in general do what you ask for. Adapt for your particular needs.
OUTPUT:
This program will check if an array is mirrored. Press enter to proceed!
Insert row*col -> 3*3
Insert row 1 elements, one by one!
Element 1 -> 1
Element 2 -> 0
Element 3 -> 1
Insert row 2 elements, one by one!
Element 1 -> 2
Element 2 -> 0
Element 3 -> 3
Insert row 3 elements, one by one!
Element 1 -> 4
Element 2 -> 0
Element 3 -> 4
Mirror found at row 1!
1 0 1
Mirror found at row 3!
4 0 4
CODE:
#include <stdio.h>
#define MAXCOLUMN 10
#define MAXROW 10
void clean(){
int temp;
while ((temp = getchar()) != '\n' && temp != EOF);
}
void print(int dim,int r, int row[][MAXCOLUMN]){
for(int index = 0; index < dim; index++)
printf("%d ",row[r][index]);
putchar('\n');
}
int main(void){
int arr[MAXROW][MAXCOLUMN];
int col,row,mirror;
puts("This program will check if an array is mirrored. Press enter to proceed!");
do{
clean();
printf("Insert row*col -> ");
}
while(scanf("%d*%d", &row, &col)!=2);
for(int r = 0; r < row; r++){
printf("Insert row %d elements, one by one!\n",r+1);
for(int c = 0; c < col; c++){
do{
clean();
printf("Element %d -> ", c+1);
}while(!scanf("%d",&arr[r][c]));
}
}
for(int r = 0; r < row; r++){
mirror = 1;
for(int cFH = 0, cSH = col-1; cFH < col/2; cFH++, cSH--)//cFH -> column index first half | cSH -> column index second half
if(arr[r][cFH] != arr[r][cSH]){
mirror = 0;
break;
}
if(mirror){
printf("Mirror found at row %d!\n",r+1);
print(col,r,arr);
}
}
return 0;
}
Usually you iterate through the columns of each row, that means that usually i (the outer loop) represents the rows and j the columns.
This piece of code shows a way to check if a 2D array is mirrored horizontally:
int mirror = 1;
for(int i = 0; i < row; i++) {
for(int j = 0; j < col/2; j++) {
// comparing first element with last element of row `i`
// than comparing the second element with the second last
// and so on, till you reach the center of the row, `j==col/2`
// if the comparison is true just one time, the array is not mirrored
if( array[i][j] != array[i][col-j-1] ) {
mirror = 0;
i = row; // to break the outer loop
break;
}
}
}
mirror ? puts("Mirror!") : puts("No mirror.");
At the end of the program if the variable mirror still have a value of 1, you got a mirror array.

Create a matrix with elements taken by another matrix

I have to implement a function which, given a matrix of 0s and 1s, returns a new matrix that contains the coordinates of the 1s. For example: if matrix is 3x3 and the output is:
1 0 1
0 1 1
0 0 1
New matrix will be 5x2 and the output will be:
0 0
0 2
1 1
1 2
2 2
Some advice? My method would be this:
int matrix[3][3];
for (int i = 0; i < 3; i++){
for (int j = 0; j < 3; j++){
if (matrix[i][i] == 1){
//Code i need
}
}
}
The solution really depends on the requirement:
Is it allowed to allocate result matrix with the maximum size possible (in this case 9 x 2).
If point 1 is not allowed, is it strictly required to use fixed size array (no dynamic allocation). If this is the case then may need to pass the matrix twice to allocate the right size of array.
Other solution is of course by using dynamic allocation (using malloc etc).
The simplified version of option 1 & 2 is shown below:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int matrix[3][3];
matrix[0][0] = 1;
matrix[0][1] = 0;
matrix[0][2] = 1;
matrix[1][0] = 0;
matrix[1][1] = 1;
matrix[1][2] = 1;
matrix[2][0] = 0;
matrix[2][1] = 0;
matrix[2][2] = 1;
//Solution 1 - If allowed to allocate matrix with size more than the result,
//i.e. if input is 3x3 matrix, then the maximum size of result matrix is 9 x 2
int resultMatrix1[9][2];
int usedCount1=0;
for (int i = 0; i < 3; i++){
for (int j = 0; j < 3; j++) {
if (matrix[i][j] == 1) {
resultMatrix1[usedCount1][0] = i;
resultMatrix1[usedCount1][1] = j;
usedCount1++;
} //end if
} //end for
} //end for
//Print the result
printf("\nSolution 1\n");
for (int i = 0; i < usedCount1; i++){
printf("%d %d\n", resultMatrix1[i][0], resultMatrix1[i][1]);
} //end for
//Solution 2 - strictly allocate matrix with size equal to the result.
//Without using dynamic allocation, meaning we need to have two passes.
//1st pass is to count the element which satisfy the criteria
int usedCount2=0;
for (int i = 0; i < 3; i++){
for (int j = 0; j < 3; j++) {
if (matrix[i][j] == 1) {
usedCount2++;
} //end if
} //end for
} //end for
int resultMatrix2[usedCount2][2]; //allocate the right size
int idx=0;
//2nd pass is to fill in the result matrix
for (int i = 0; i < 3; i++){
for (int j = 0; j < 3; j++) {
if (matrix[i][j] == 1) {
resultMatrix2[idx][0] = i;
resultMatrix2[idx][1] = j;
idx++;
} //end if
} //end for
} //end for
//Print the result
printf("\nSolution 2\n");
for (int i = 0; i < usedCount2; i++){
printf("%d %d\n", resultMatrix2[i][0], resultMatrix2[i][1]);
} //end for
return 0;
}
Results are the same for both solution:
Solution 1
0 0
0 2
1 1
1 2
2 2
Solution 2
0 0
0 2
1 1
1 2
2 2
If matrix[i][j] == 1 what do you know about the coordinates [i,j] ? That they are the coordinates of a 1 :)
Secondly, will the input matrix always be 3x3? If not, you'll want to store the dimensions of the matrix in variables, and use theses variables for your for loops.

Printing a single dimension array in user specified columns in C language

I am trying to display the elements of an array in the number of columns that the user specifies. They decide how large the array is and how many columns it will be displayed in. Right now, I am printing the elements of the array in columns but, I have extra rows and columns with numbers that are not in the array. Thus if I select array size and column number as 5 3, I would hope to see:
1 3 5
2 4
Instead, I get something like:
1 3 5
2 4 107863456
128976543 58764 896543221
5643217 90876543456 8976543
I am getting 3 columns with 4 rows. I do not know why this is happening. Here is the portion of my code that deals with creating columns, let me know if more code is needed (x is variable that holds array size, y holds number of columns):
void colDisplay(int *aPtr, int x, int y) {
int i, j;
srand(time(NULL));
for(i = 0; i < x; i++) {
aPtr[i] = rand()%5+1;
}
/*Trying to format display for number of columns used*/
printf("Unsorted columns\n");
for(i = 0; i < x; i++) {
for(j = 0; j < y; j++) {
//printf("%d = %d ", (i*y)+j, aPtr[(i*y)+j]);
printf("%d ", aPtr[(i*y)+j]);
}
printf("\n");
}
}
The inner loop is counting the columns correctly, but the outer loop is using x as a row count, instead of an item count. To fix the problem you can use a single loop that counts items, and outputs newlines at the correct times.
j = 0;
for ( i = 0; i < x; i++ )
{
printf("%d ", aPtr[i] );
j++;
if ( j == y || i == x-1 )
{
printf( "\n" );
j = 0;
}
}
I agree with the solution by #user3386109.
Also, the following change will help:
Original 'for' loop with j:
for(j = 0; j < y; j++)
Modified code:
for (j = 0; (j < y) && (i*y+j < x); j++)
Reason: index = i*y+j may exceed x if (x % y != 0) i.e. if x (array size) is not integral multiple of y (display column size).
Because of arrays index out of bound.
You should do the following:
for(i = 0; i >= 0; i++) {
boolean isContinue = true;
for(j = 0; j < y; j++) {
int index = i*y+j;
if(index==x){
isContinue = false;
break;
}
printf("%d ", aPtr[(i*y)+j]);
}
if(!isContinue){
break;
}
printf("\n");
}

How to find the biggest sum of a given scope in a 2D array?

I need to know how to find the biggest sum of a given scope in a 2D array, preferably in C to improve the efficiency of the code give below and solve the problem.
To understand this better, read the problem I need to solve below.
Problem
The great city X is a grid of N rows and M columns. There are given
number of people living in each cell. You are asked to position the
telecommunication tower so that as many as people are satisfied. The
cellular tower can cover a rectangular area of Y rows and X columns.
Find the maximum number of people you can satisfy.
Constrains
1 <= N, M <= 1000
1 <= Y <= N, 1 <= X <= M
1 <= number of people in a cell <= 1000
Rectangular area covered by the celluar tower should not cover any cell partially.
Input
First line of the input will contain 4 digits N, M, Y and X respectively separated by spaces. Each of next N lines with contains integers of row 1 to N. Each row will M integers giving the number of people living in each cell separated by spaces.
Output
Output should contain only one integer, the maximum number of people you can satisfy.
Sample Input
4 5 2 3
3 1 1 1 2
2 5 6 7 1
1 2 9 9 1
1 1 1 1 1
Sample Output
38
Explanation
Maximum number of people can be satisfied by placing the tower covering 2x3 area that consists of 5, 6, 7, 2, 9 and 9 cells.
5 + 6 + 7 + 2 + 9 + 9 = 38
My code
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
int main() {
int N, M, Y, X;
scanf("%d %d %d %d", &N, &M, &Y, &X);
int max = 0;
int total = 0;
int data[N][M];
for(int i = 0; i < N; i++)
for(int j = 0; j < M; j++)
scanf("%d",&(data[i][j]));
for(int i = 0; i < N; i++)
{
for(int j = 0; j < M; j++)
{
total = 0;
for(int l = 0; (l < Y) && (i + Y) <= N; l++)
{
for(int k = 0; (k < X) && (j + X <= M); k++)
{
total += data[i+l][j+k];
}
if(total > max)
max = total;
}
}
}
printf("%d",max);
return 0;
}
This code fails because it's too linear and takes a lot of time when a larger input is used.
You can try out the problem yourself, here
I suppose the main problem in your solution of Number Grid problem is nested for loops. The simplest optimization is to minimaze number of recalculations for each move of the scope.
I tryed the following changes in the original code:
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
int main() {
int N, M, Y, X;
scanf("%d %d %d %d", &N, &M, &Y, &X);
int max = 0;
int total = 0;
int data[N][M];
for(int i = 0; i < N; i++)
for(int j = 0; j < M; j++)
scanf("%d",&(data[i][j]));
////////////////////////////////////////////////////////////
// calculation of the first total and initial max
int startTotal = 0;
int r, c;
for(r = 0; r < Y-1; r++)
{
for(c = 0; c < X-1; c++)
{
startTotal += data[r][c];
}
}
max = startTotal;
for(int i = 0; i+Y <= N; i++)
{
// add next line
for(int c = 0; c < X-1; c++)
{
startTotal += data[i+Y-1][c];
}
total = startTotal;
for(int j = 0; j+X <= M; j++)
{
// add next column
for(int r = i; r < i+Y; r++)
total += data[r][j+X-1];
// compare
if(total > max)
{
max = total;
}
// subtract the first column
for(int r = i; r < i+Y; r++)
total -= data[r][j];
}
// subtract the first line
for(int c = 0; c < X-1; c++)
{
startTotal -= data[i][c];
}
}
////////////////////////////////////////////////////////
printf("%d",max);
return 0;
}
I have tryed to run the program at hackerrank.com, and received

Resources