Shift all non-null elements to the left - c

The elements must be shifted to the left if they are 0. I tried a loop that starts from the end of the 2D Matrix Array, but I can't seem to get my head around why it doesn't work.
The input must be in range -999 to 999.
I assign the element that is != 0 to the first index and afterwards if have to move that temporary integer one step forward. That is my main issue, since I can't get my head around it. Perhaps a different approach is wanted?
(I'm trying to solve it without Pointers)
int main()
{
int M[3][3];
int j = 0;
int i = 0;
for(i = 0; i < 3; ++i){
for(j = 0; j < 3; ++j){
printf("Give me the number for [%d][%d]: ", i, j);
scanf("%d", &M[i][j]);
if(-999 > M[i][j] || M[i][j] > 999) j--;
// a)
if((i + j) % 2 == 0) {
M[i][j] = 0;
}
}
}
// Print the result of a)
for(i = 0; i < 3; ++i){
for(j = 0; j < 3; ++j){
printf("%d ", M[i][j]);
}
printf("\n");
}
// Shifting the elements to the left b)
int temp = M[0][0];
for(i = 2; i >= 0; i--)
{
for(j = 2; j >= 0; j--){
if(M[i][j] != 0)
{
M[i][j] = temp;
}
// change the value of temp
}
}
// Print the array after a) and b)
for(i = 0; i < 3; ++i){
for(j = 0; j < 3; ++j){
printf("%d ", M[i][j]);
}
}
}
The result of the a) is just the matrix after the first step where if (i=j) converts the value at that place 0.
For example if you input: 1 2 3 4 5 6 7 8 9
The result would be: 0 2 0 4 0 6 0 8 0
The final result of b) is yet to be done, but should look like:
2 4 6 8 0 0 0 0 0.

Perhaps a different approach is wanted?
As a [3][3] array is in memory like a [1][3*3] one, simple shift M[0] as if it had 9 elements.
unsigned nonzero_index = 0;
for(i = 0; i < 3*3; ++i){
if (M[0][i]) {
M[0][nonzero_index++] = M[0][i];
}
}
while (nonzero_index < 3*3) { // zero fill the rest
M[0][nonzero_index++] = 0;
}

Related

Why is the multiplication doubling in this C loop?

The code is supposed to take inputs to form a 3x3 Matrix and then multiply each term by the diagonal element of that line, but, for some reason that i don't know, it multiplies two times by the diagonal when the column index is bigger than the row index.
#include <stdio.h>
#define R 3
int a[R][R], i, j;
int main(void) {
for (i = 0; i < R; i++) {
for (j = 0; j < R; j++) {
printf("\nInsira o n%i%i ", i, j);
scanf("%i", &a[i][j]);
}
}
for (i = 0; i < R; i++) {
for (j = 0; j < R; j++) {
a[i][j] = a[i][j] * a[i][i];
}
}
for (i = 0; i < R; i++) {
printf("\n");
for (j = 0; j < R; j++) {
printf("%i ", a[i][j]);
}
}
}
input:
9 8 7
6 5 4
3 2 1
output:
81 648 567
30 25 100
3 2 1
The diagonal value for a given row is being changed before that row has been fully multiplied, so once the column goes past the diagonal, the multiplies are using the new value of that diagonal rather than the old value.
You can fix it (and improve the speed) as follows:
for (i = 0; i < R; i++) {
int tmp = a[i][i];
for (j = 0; j < R; j++) {
a[i][j] *= tmp;
}
}
Also, as mentioned, both i and j should be local variables.

How to add values to the first row and the first column of two dimensional array in C?

I am trying to add numbers from 0 to 9 in the row and 0 to 11 in column of a two dimensional array in C. And as for the rest of the empty spaces, I would like to add 0.
The matrix size is 9 x 11. And this is what the output looks like with the empty blocks filled with 0:
And this is the code I have so far but it does not work:
int i;
int j;
int arr[i][j];
int value = 0;
for (i = 0; i < 9; i++){
for (j = 0; j < 11; j++){
arr[i][j] = value;
printf("%d\n", arr[i][j]);
value++;
}
printf("\n");
}
The screenshot that you've posted has 10 rows and 12 columns, so assuming that, here is the code:
int i;
int j;
int arr[10][12];
for (i = 0; i < 10; i++) {
for (j = 0; j < 12; j++) {
if (i == 0) {
arr[0][j] = j;
} else if (j == 0) {
arr[i][0] = i;
} else {
arr[i][j] = 0;
}
printf("%d", arr[i][j]);
}
printf("\n");
}

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.

Some numbers are incorrectly changed when i try to find prime numbers in matrix

I try to find prime numbers in a matrix and replace then with 1 and 0 respectively. For some the output is correct but for some it isn't and it doesn't change the last element. Can't figure out what's causing this. Looked up formulas for finding prime numbers they use the same loop as i do.
int main() {
int m, n;
scanf("%d %d", &m, &n);
int a[m][n];
for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
scanf("%d", &a[i][j]);
}
}
for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
for(int k = 2; k < a[i][j]; k++) {
if(a[i][j] % k == 0) {
a[i][j] = 0;
} else if(a[i][j] % k != 0){
a[i][j] = 1;
}
}
}
}
Input:
15 23 7 10
6 18 5 31
31 14 1 2
Output im getting:
1 1 1 0
0 0 1 1
1 0 1 2
Output i need to get:
0 1 1 0
0 0 1 1
1 0 0 1
As part of a prime test stop iterating after the number is noted as not prime.
int p = a[i][j];
a[i][j] = p > 1;
for(int k = 2; k < p; k++) {
if(p % k == 0) {
a[i][j] = 0;
break;
}
}
Even better, no need to iterate until k < p. Code can stop sooner with k*k <= p or better as k <= p/k. Consider if p was near 1,000,000. Rather than 1,000,000 loops, code does as most 1,000 loops - much faster.
// for(int k = 2; k < p; k++) {
for(int k = 2; k <= p/k; k++) {

Transforming a 3x3 two-dimensional array in a 6x6 symmetrical two-dimensional array

I'm trying to solve an exercise that requires:
- fill randomly a 3x3 two-dimensional array
- transform the array in a second one with dimension 6x6:
1&nbsp 2&nbsp 3&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp1&nbsp 2&nbsp 3 &nbsp3 &nbsp2&nbsp 1&nbsp
4&nbsp 5&nbsp 6&nbsp&nbsp&nbsp&nbsp&nbsp-> 4&nbsp 5&nbsp 6 &nbsp 6 &nbsp5 4&nbsp
7 &nbsp8&nbsp 9&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp7&nbsp 8&nbsp 9 &nbsp 9 &nbsp8&nbsp 7
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp7&nbsp 8&nbsp 9 &nbsp 9 &nbsp8 &nbsp7
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp 4&nbsp 5 &nbsp6 &nbsp 6&nbsp 5&nbsp 4
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp1&nbsp 2&nbsp 3 &nbsp 3&nbsp 2&nbsp 1
I can't get it working tho' I think the logic must be right.
#include <stdio.h>
#include <stdlib.h>
#define DIM 3
int main()
{
int i, j, a[DIM][DIM],a1[DIM][DIM], a2[DIM][DIM], a3[DIM][DIM], b[2*DIM][2*DIM];
srand(time(NULL));
for (i = 0; i < DIM; i++)
{
for (j = 0; j < DIM; j++)
{
a[i][j] = rand() % 10;
}
}
for (i = 0; i < DIM; i++)
{
for (j = 0; j < DIM; j++)
{
printf("%d ", a[i][j]);
}
printf("\n");
}
for (i = 0; i < DIM; i++)
{
for (j = 0; j < DIM; j++)
{
a1[i][j] = a[i][DIM - 1 - j];
a2[i][j] = a[DIM - 1 -j][j];
a3[i][j] = a2[i][DIM - 1 - j];
if(i < DIM && j < DIM)
b[i][j] = a[i][j];
if(i < DIM && j >= DIM)
b[i][j] = a1[i][j];
if(i >= DIM && j < DIM)
b[i][j] = a2[i][j];
if(i >= DIM && j >= DIM)
b[i][j] = a3[i][j];
}
}
for (i = 0; i < 2*DIM; i++)
{
for (j = 0; j < 2*DIM; j++)
{
printf("%d ", b[i][j]);
}
printf("\n");
}
return 0;
}
Here are a few points that should help you to get where you want to go:
You are making four copies of a three by three array.
You need a nested for loop to iterate over the original array
Inside the for loop you will be making four assignments, one for each copy
Each copy has a different location
When you make the copies you will need to add an offset to each index
This is best done by just using the index of what was the value in the upper left corner
Each copy goes in different directions
Whenever a dimension is going in the wrong dimension, you can simply subtract the index
Anything else?
If you always fill the 6 X 6 matrix in the same way shown in the example, then you can use the following code,
m=0;
fl1=0;
for (i = 0; i < 6; i++)
{
n=0;
fl2=0;
for (j = 0; j < 6; j++)
{
b[i][j] = a[m][n];
if(n==3)
{
fl2=1;
}
if(fl2==0)
{
n++;
}
else
{
n--;
}
}
if(m==3)
{
fl1=1;
}
if(fl1==0)
{
m++;
}
else
{
m--;
}
}
for (i = 0; i < DIM*2; i++){
for (j = 0; j < DIM*2; j++){
b[i][j]=a[i-(i>=DIM)*((i-DIM)*2+1)][j-(j>=DIM)*((j-DIM)*2+1)];
}
}

Resources