Reputation: 121
I need to make a matrix that would print number X between two diagonals, and the rest is number Y.
Right diagonal is: 'i==j' Left diagonal is: 'i+j==n-1'
The problem here is to select elements that are between them.
Picture of matrix:
Code:
#include <stdio.h>
int main() {
int i, j, n = 5, x = 4, y = 6;
int mat[100][100];
for (i = 0; i < n; i++)
for (j = 0; j < n; j++) {
if (i == j || i + j >= n - 1 || j < i) mat[i][j] = y;
else mat[i][j] = x;
}
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++)
printf("%d ", mat[i][j]);
printf("\n");
}
return 0;
}
OUTPUT:
6 4 4 4 6
6 6 4 6 6
6 6 6 6 6
6 6 6 6 6
6 6 6 6 6
Could you please help me to fix the remaining part of matrix? I just need to make number X between the main diagonals in the lower part of matrix.
Upvotes: 1
Views: 109
Reputation: 8344
Simply count inward from the left and right margin, appropriate to the row. When you reach the centre, reverse the direction of counting. Simple.
int main() {
int i, j, n = 11, x = 4, y = 6;
int cnt = 0;
int mat[100][100];
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++)
mat[i][j] = ( j>cnt && j<(n-cnt-1) ) ? x : y;
cnt += i < n/2 ? 1 : -1;
}
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++)
printf("%d ", mat[i][j]);
printf("\n");
}
return 0;
}
Since the pattern is symmetric both horizontally and vertically, why not populate more cells at the same time:
int main() {
int i, j, n = 11, x = 4, y = 6;
int mat[100][100];
for (i = 0; i < (n+1)/2; i++)
for (j = 0; j < (n+1)/2; j++)
mat[i ][j ] =
mat[n-1-i][j ] =
mat[i ][n-1-j] =
mat[n-1-i][n-1-j] =
( j>i && j<(n-1-i) ) ? x : y;
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++)
printf("%d ", mat[i][j]);
printf("\n");
}
return 0;
}
Since the stated objective is to print the pattern, there's no need for the matrix and separate operations:
int main() {
int cnt = 0, n = 11;
for( int i = 0; i < n; i++ ) {
for ( int j = 0; j < n; j++ )
putchar( "64"[ j>cnt && j<(n-cnt-1) ] );
cnt += i < n/2 ? 1 : -1;
puts( "" );
}
return 0;
}
And, a final version that "works outward from the centre" (with the proviso that the values are all small):
#include <string.h>
int main() {
const uint8_t n = 11, x = 4, y = 6;
uint8_t mat[n][n];
memset( mat, y, sizeof mat );
for( int r = 1, w = 1, c = n>>1; r < (n+1)/2; r++, w += 2 ) {
memset( &mat[c-r][c-r+1], x, w );
memset( &mat[c+r][c-r+1], x, w );
}
// Alternatively as a single statement without needing braces:
// for( int r = 1, w = 1, c = n>>1; r < (n+1)/2; r++, w += 2 )
// memcpy( &mat[c+r][c-r+1], memset( &mat[c-r][c-r+1], x, w ), w );
for( int i = 0; i < n; i++ ) {
for( int j = 0; j < n; j++ )
printf("%d ", mat[i][j]);
puts( "" );
}
return 0;
}
So many ways to skin a cat...
Upvotes: 1
Reputation: 144685
The upper and lower triangles can be isolated with separate tests:
#include <stdio.h>
int main() {
int i, j, n = 5, x = 4, y = 6;
int mat[n][n];
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
if (j > i && j < n - i - 1) {
/* upper triangle */
mat[i][j] = x;
} else
if (j < i && j > n - i - 1) {
/* lower triangle */
mat[i][j] = x;
} else {
/* everywhere else */
mat[i][j] = y;
}
}
}
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++)
printf("%d ", mat[i][j]);
printf("\n");
}
return 0;
}
Since you set the same value in both triangles, you can combine the tests as a single expression:
#include <stdio.h>
int main() {
int i, j, n = 5, x = 4, y = 6;
int mat[n][n];
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
if ((j > i && j < n - i - 1) || (j < i && j > n - i - 1))
mat[i][j] = x;
else
mat[i][j] = y;
}
}
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++)
printf("%d ", mat[i][j]);
printf("\n");
}
return 0;
}
Upvotes: 1
Reputation: 1835
You can express the diagonals in terms of i
and n
, like you did. Just instead, bring j
to the left of the expression. I have written them out as d1
and d2
:
#include <stdio.h>
#include <sys/param.h>
int main() {
int i, j, n = 5, x = 4, y = 6;
int mat[n][n];
for (i = 0; i < n; i++)
for (j = 0; j < n; j++) {
int d1 = i;
int d2 = n - i - 1;
if (j > MIN(d1, d2) && j < MAX(d1, d2)) mat[i][j] = x;
else mat[i][j] = y;
}
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++)
printf("%d ", mat[i][j]);
printf("\n");
}
return 0;
}
I have taken MIN
and MAX
from sys/param.h
, but you might want to define those yourself, whatever suits your needs.
Note that I have also inverted the assignment of x
and y
to make it easier to explain from the picture:
If j
on line i
is between d1
and d2
, then make it x
, otherwise make it y
.
Upvotes: 1