Matrix and swapping rows - arrays

My task is to find min and max value in matrix, and print that they are in the same row if they are in the same row, and swap their rows if they are not equal. My program worked when they are not equal, but it crashed in line where a = [imin1][j] when they were equal, and I don't know why. I hope you could help me.
#include <stdio.h>
int main() {
int m[10][10], i, j, min, max, imin1, imax1, imin2, imax2, a;
printf ("Elements of matrix: ");
for (i = 0; i < 10; i++) {
for (j = 0; j < 10; j++) {
scanf("%d", &m[i][j]);
}
}
min = m[0][0];
max = m[0][0];
for (i = 0; i < 10; i++) {
for (j = 0; j < 10; j++) {
if (m[i][j] < min) {
min = m[i][j];
imin1 = i;
imin2 = j;
}
if (m[i][j] > max) {
max = m[i][j];
imax1 = i;
imax2 = j;
}
}
}
if (imin1 == imax1)
printf ("Same row");
else {
for (j = 0; j < 10; j++) {
a = m[imin1][j];
m[imin1][j] = m[imax1][j];
m[imax1][j] = a;
}
printf ("New matrix: \n");
for (i = 0; i < 10; i++) {
for (j = 0; j < 10; j++) {
printf ("%d ", m[i][j]);
}
printf("\n");
}
}
}

Your problem in the case where max and min are the same is due to imax1 and imnin1 being Uninitialized. The problem surfaces here:
if(imin1==imax1) /* <== here */
printf("Same row");
else {
for(j=0;j<10;j++){
a=m[imin1][j];
m[imin1][j]=m[imax1][j]; /* <=== and here */
m[imax1][j]=a;
}
printf("New matrix: \n");
for(i=0;i<10;i++){
for(j=0;j<10;j++){
printf("%d ", m[i][j]);
}
printf("\n");
}
}
Since you have set min and max to the same first element. If all elements are the same, if(m[i][j]<min) and if(m[i][j]>max) are always false and imax1 and imnin1 are never assigned values.
For variables with automatic storage duration, attempt to access the value of a variable while it value is indeterminate results in Undefined Behavior (bad JuJu)
C11 Standard - 6.7.9 Initialization(p10) "If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate." and C11 Standard - J.2 Undefined Behavior "The value of an object with automatic storage duration is used while it is indeterminate (6.2.4, 6.7.9, 6.8)."
You can eliminate the problem by always initializing min to the maximum value for the type and initializing max to the minimum value for the type, e.g.
#include <limits.h>
...
min = INT_MAX,
max = INT_MIN,
Putting it altogether and eliminating the use of the Magic-Numbers, you can do:
#include <stdio.h>
#include <limits.h>
#define ROWS 10 /* if you need a constant, #define one (or more) */
#define COLS ROWS
int main() {
int m[ROWS][COLS] = {{0}},
min = INT_MAX,
max = INT_MIN,
iminx = 0, iminy = 0, imaxx = 0, imaxy = 0;
puts ("Original matrix:");
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
if (scanf("%d", &m[i][j]) != 1) { /* validate EVERY input */
fputs ("error: invalid integer input.\n", stderr);
return 1;
}
printf (" %2d", m[i][j]);
}
putchar ('\n');
}
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
if (m[i][j] < min){
min = m[i][j];
iminx = i;
iminy = j;
}
if (m[i][j] > max) {
max = m[i][j];
imaxx = i;
imaxy = j;
}
}
}
printf ("\nmin: %2d (%d,%d)\nmax: %2d (%d,%d)\n\n",
min, iminx, iminy, max, imaxx, imaxy);
if (iminx == imaxx)
puts ("Same row\n");
else {
int a = m[iminx][iminy];
m[iminx][iminy] = m[imaxx][imaxy];
m[imaxx][imaxy] = a;
printf("New matrix: \n");
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
printf(" %2d", m[i][j]);
}
putchar ('\n');
}
}
}
(note: the variable names for e.g. imin1, imin2 were changed to iminx and iminy, the same for imax., just for the simplified thought of x, y as coordinate indexes instead of 1, 2 -- entirely up to you)
Example Use/Output
$ ./bin/arr_max_min_swap < dat/arr_int_10x10.txt
Original matrix:
41 48 2 35 6 74 92 89 70 14
32 85 74 78 37 25 49 36 93 17
79 73 23 88 22 83 21 42 85 86
67 26 66 2 62 72 76 86 94 78
32 26 63 7 37 1 64 86 69 57
36 81 62 59 1 84 42 23 27 59
41 26 86 39 60 80 11 68 98 37
47 30 64 10 69 33 43 33 51 45
90 87 26 52 46 27 69 21 82 28
80 23 86 98 62 47 10 6 15 8
min: 1 (4,5)
max: 98 (6,8)
New matrix:
41 48 2 35 6 74 92 89 70 14
32 85 74 78 37 25 49 36 93 17
79 73 23 88 22 83 21 42 85 86
67 26 66 2 62 72 76 86 94 78
32 26 63 7 37 98 64 86 69 57
36 81 62 59 1 84 42 23 27 59
41 26 86 39 60 80 11 68 1 37
47 30 64 10 69 33 43 33 51 45
90 87 26 52 46 27 69 21 82 28
80 23 86 98 62 47 10 6 15 8
Same value:
$ ./bin/arr_max_min_swap < dat/arr_int_10x10_7.txt
Original matrix:
7 7 7 7 7 7 7 7 7 7
7 7 7 7 7 7 7 7 7 7
7 7 7 7 7 7 7 7 7 7
7 7 7 7 7 7 7 7 7 7
7 7 7 7 7 7 7 7 7 7
7 7 7 7 7 7 7 7 7 7
7 7 7 7 7 7 7 7 7 7
7 7 7 7 7 7 7 7 7 7
7 7 7 7 7 7 7 7 7 7
7 7 7 7 7 7 7 7 7 7
min: 7 (0,0)
max: 7 (0,0)
Same row
Let me know if you have further questions.

You need to initialize the values of imin1, imax1, imin2, imax2 to be zero as you used the first element as initial value of max and min, like this:
min = m[0][0];
max = m[0][0];
imin1 = imax1 = imin2 = imax2 = 0;

Related

Eratosthenes prime numbers

I have created a program to search for prime numbers. It works without problems until the entered number is smaller than 52, when it is bigger output prints out some blank (0) numbers and I don't know why. Also other numbers have blank output.
My code is:
#include <stdio.h> //Prime numbers
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <unistd.h>
int c[100], n, a[50], d, e, b = 1;
void sort() {
for (int i = 1; i < n; i++) {
if (c[i] > 1) {
a[b] = c[i];
printf("%d %d %d\n", a[1], b, i);
b++;
e = 2;
d = 0;
while (d <= n) {
d = c[i] * e;
c[d - 1] = 0;
e++;
}
}
}
}
int main() {
printf("Enter number as an limit:\n");
scanf("%d", &n);
for (int i = 0; i < n; i++) {
c[i] = i + 1;
}
sort();
printf("Prime numbers between 1 and %d are:\n", n);
for (int i = 1; i < b; i++) {
printf("%d ", a[i]);
}
return 0;
}
Here is output for 25:
Enter number as an limit:
25
2 1 1
2 2 2
2 3 4
2 4 6
2 5 10
2 6 12
2 7 16
2 8 18
2 9 22
Prime numbers between 1 and 25 are:
2 3 5 7 11 13 17 19 23
But for 83 is:
Enter number as an limit:
83
2 1 1
2 2 2
2 3 4
2 4 6
2 5 10
2 6 12
2 7 16
2 8 18
2 9 22
2 10 28
2 11 30
2 12 36
2 13 40
2 14 42
2 15 46
2 16 52
0 17 58
0 18 60
0 19 66
0 20 70
0 21 72
0 22 78
0 23 82
Prime numbers between 1 and 83 are:
0 3 5 7 11 0 17 19 23 29 31 37 0 43 47 53 0 61 67 71 73 79 83
Blank spots always spots after 17th prime number. And always the blank numbers are the same. Can you help me please what is the problem?
The loop setting entries in c for multiples of c[i] runs too far: you should compute the next d before comparing against n:
for (d = c[i] * 2; d <= n; d += c[i]) {
c[d - 1] = 0;
}
As a matter of fact you could start at d = c[i] * c[i] because all lower multiples have already been seen during the previous iterations of the outer loop.
Also note that it is confusing to store i + 1 into c[i]: the code would be simpler with an array of booleans holding 1 for prime numbers and 0 for composite.
Here is a modified version:
#include <stdio.h>
int main() {
unsigned char c[101];
int a[50];
int n, b = 0;
printf("Enter number as a limit:\n");
if (scanf("%d", &n) != 1 || n < 0 || n > 100) {
printf("invalid input\n");
return 1;
}
for (int i = 0; i < n; i++) {
c[i] = 1;
}
for (int i = 2; i < n; i++) {
if (c[i] != 0) {
a[b] = i;
//printf("%d %d %d\n", a[0], b, i);
b++;
for (int d = i * i; d <= n; d += i) {
c[d] = 0;
}
}
}
printf("Prime numbers between 1 and %d are:\n", n);
for (int i = 0; i < b; i++) {
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
Output:
chqrlie$ ./sieve4780
Enter number as a limit:
25
Prime numbers between 1 and 25 are:
2 3 5 7 11 13 17 19 23
chqrlie$ ./sieve4780
Enter number as a limit:
83
Prime numbers between 1 and 83 are:
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79
Your problem seems to be caused by the fact that you have declared an array with size 50, but in fact it goes further than that: imagine you want to use Eratosthenes' procedure to find the first 10,000 prime numbers. Does this mean that you need to declare an array of size 10,000 first (or even bigger), risking to blow up your memory?
No: best thing to do is to work with collections where you don't need to set the maximum size at declaration time, like a linked list, a vector, ..., like that you can make your list grow as much as you like during runtime.

Trying to get a user input to make a 2-D array multiplication table

int main (void)
{
int range, i, j;
printf("Input size of multiplication table: ");
scanf("%i", &range);
int output[range][range];
for (i = 0; i<=range; ++i)
{
for (j=0; j<=range; ++j)
{
output[i][j] = i * j;
if(j!=range && output[i][j] != 0)
{
printf("%3i ", output[i][j]);
}
else if (j==range)
{
printf("%3i", output[i][j]);
}
else if (output[i][j] == 0)
{
printf("%3i "), i+2;
}
else
{
printf("%3i", j + i - range);
}
}
printf("\n");
}
return 0;
}
I am having it output:
0 1 2 3 4 0
5 1 2 3 4 5
10 2 4 6 8 10
15 3 6 9 12 15
20 4 8 12 16 20
25 5 10 15 20 25
and I need the 0 on the end to be a five and the first column to be 0,1,2,3,4,5 instead of 0,5,10,15,20,25.
If anyone could help I would appreciate it.
You have two primary problems, (1) you fail to validate your user input, and (2) your loop bounds are incorrect, e.g.
Any time you take user input, you must validate that you actually received what you expected and that any conversion required, was completed successfully. Failure to validate will lead to Undefined Behavior it invalid (or no) input is provide. (e.g. What if the user enters foo instead of 10?) When using scanf, you must validate the return which provides the count of the number of conversions that successfully took place, e.g.
printf ("Input size of multiplication table: ");
if (scanf("%i", &range) != 1) { /* VALIDATE ALL USER INPUT */
fprintf (stderr, "error: invalid input.\n");
return 1;
}
That is bare minimum. You can also check if the return is EOF to indicate the user canceled input with a [Ctrl+D] (or [Ctrl+Z] on windoze -- must be explicitly enabled on Win10).
Next, your loop bound are for (i = 0; i < range; i++) not i <= range, that invokes Undefined Behavior by attempting to access memory outside your array bounds. Simply fix the loop condition, e.g.
for (i = 0; i< range; i++) { /* fill multiplication table */
for (j = 0; j< range; j++) {
output[i][j] = (i + 1) * (j + 1); /* i+1 * j+1 */
}
}
Putting it altogether, you could do something similar to:
#include <stdio.h>
int main (void) {
int range, i, j;
printf ("Input size of multiplication table: ");
if (scanf("%i", &range) != 1) { /* VALIDATE ALL USER INPUT */
fprintf (stderr, "error: invalid input.\n");
return 1;
}
int output[range][range]; /* variable length array */
for (i = 0; i< range; i++) { /* fill multiplication table */
for (j = 0; j< range; j++) {
output[i][j] = (i + 1) * (j + 1); /* i+1 * j+1 */
}
}
for (i = 0; i< range; i++) { /* output table */
for (j = 0; j< range; j++)
printf (" %3d", output[i][j]);
putchar ('\n');
}
return 0;
}
note: the trivial parts of the table is omitted (e.g. 0 * anything), and duplicated rows of 1 * anything are also not shown. If you need to additional rows, you can add them back.
Example Use/Output
$ ./bin/multable
Input size of multiplication table: 10
1 2 3 4 5 6 7 8 9 10
2 4 6 8 10 12 14 16 18 20
3 6 9 12 15 18 21 24 27 30
4 8 12 16 20 24 28 32 36 40
5 10 15 20 25 30 35 40 45 50
6 12 18 24 30 36 42 48 54 60
7 14 21 28 35 42 49 56 63 70
8 16 24 32 40 48 56 64 72 80
9 18 27 36 45 54 63 72 81 90
10 20 30 40 50 60 70 80 90 100
Look things over and let me know if you have further questions.
To Show the 1X Rows
You simply update your print routine as follows:
for (i = 0; i< range; i++) { /* output table */
if (!i) {
printf (" ");
for (j = 0; j< range; j++)
printf (" %3d", output[i][j]);
putchar ('\n');
}
printf (" %3d", i + 1);
for (j = 0; j< range; j++)
printf (" %3d", output[i][j]);
putchar ('\n');
}
Example Use/Output
$ ./bin/multable1
Input size of multiplication table: 10
1 2 3 4 5 6 7 8 9 10
1 1 2 3 4 5 6 7 8 9 10
2 2 4 6 8 10 12 14 16 18 20
3 3 6 9 12 15 18 21 24 27 30
4 4 8 12 16 20 24 28 32 36 40
5 5 10 15 20 25 30 35 40 45 50
6 6 12 18 24 30 36 42 48 54 60
7 7 14 21 28 35 42 49 56 63 70
8 8 16 24 32 40 48 56 64 72 80
9 9 18 27 36 45 54 63 72 81 90
10 10 20 30 40 50 60 70 80 90 100
Check the solution below. It's all about properly managing iterators (note the less-equal sign in the ranges and the subtraction of indexes by 1 in the assignment). You can do it very concisely by assigning to output inside the printf and using a ternary-if. (I also used dynamic allocation in order to comply with ISO standards.)
#include <stdio.h>
#include <stdlib.h>
int main()
{
int range, i, j;
printf("Enter the size of the multiplication table:\n");
scanf("%d", &range);
int ** output = (int **) malloc(sizeof(int *) * (long unsigned int) range);
for(i = 0; i <= range; ++i)
{
output[i] = (int *) malloc(sizeof(int) * (long unsigned int) range);
for(j = 0; j <= range; ++j)
printf("%3d ", !i ? j : !j ? i : (output[i - 1][j - 1] = i * j));
printf("\n");
}
return 0;
}

What's wrong with the matrix?

What's wrong with this code?
My task is: Create a square matrix of integers with a size of 9x9. Fill the matrix with random numbers. Display the main and side diagonal symmetrically with respect to the vertical axis. The example of expected result is here: matrix
Matrix :
20 20 76 65 93 76 16 2 85
6 87 78 43 48 81 71 90 38
10 12 35 77 48 88 24 53 7
12 66 51 35 74 7 30 22 49
58 14 71 46 68 68 10 81 51
98 16 74 47 64 25 17 30 37
2 44 44 74 34 54 86 73 28
85 4 57 75 18 28 51 76 2
35 17 53 76 15 91 83 85 72
The main and side diagonal:
85 20 76 65 93 76 16 2 20
6 90 78 43 48 81 71 87 38
10 12 24 77 48 88 35 53 7
12 66 51 7 74 35 30 22 49
58 14 71 46 68 68 10 81 51
98 16 74 25 64 47 17 30 37
2 44 86 74 34 54 44 73 28
85 76 57 75 18 29 51 4 2
72 17 53 76 15 91 83 85 35
But in fact the program prints only the main matrix with random numbers and after that stops.
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <Windows.h>
int main()
{
int a = 9;
int matrix[a][a];
int temp;
int i, j, n;
srand((unsigned)time(NULL));
printf("Matrix : \n\n");
for (i = 0; i < a; ++i) {
for (j = 0; j < a; ++j) {
matrix[i][j] = rand() % 100;
printf("%d\t", matrix[i][j]);
}
printf("\n\n");
}
printf("The main and side diagonal:\n\n");
for (i = 0; i < a; ++i) {
temp = matrix[i][i];
matrix[i][i] = matrix[i][(a - 1) - i];
matrix[i][(a - 1) - i] = temp;
}
for (i = 0; i < a; ++i) {
for (j = 0; j < a; ++j) {
printf("Result:", matrix[i][j]);
printf("\n\n\n");
system("pause");
return 0;
}
}
}
You are returning where you are not supposed to. (in middle of the calculation). You should return after you end up working on the for loops.
for (i = 0; i < a; ++i) {
for (j = 0; j < a; ++j) {
printf("Result:", matrix[i][j]); <--- Not printing element
printf("\n\n\n");
system("pause");
return 0; <-----
}
}
It should be
for (i = 0; i < a; ++i) {
for (j = 0; j < a; ++j) {
printf("Result: %d ", matrix[i][j]); <----You forgot the
//format specifier
printf("\n\n\n");
system("pause");
}
}
return 0;<-----
Readability is hampered when the indentation is like this. You implemented wrong logic out of it.
OP asks that it stops after printing "Result" that is because you forgot to put the format specifier in the code. That's why none of the element is printed.
Op wants to print the main and side diagonal symmetrically with respect to the vertical axis.
Now this is everything to with the print part.
Now we have to find a way that will let us distinguish which one is diagonal element and which one is not.
Suprisingly the answer should be known to someone who is writing the previous swapping logic. (Though it is not clear why OP swapped it).
Now all element matrix[p][q] will be from either diagonal if p=q or p+q=a-1. (Note that matrix is a square matrix).
But OP meant to print the matrix
for (i = 0; i < a; ++i) {
if( i == 0) printf("The main and side diagonal : \n");
for (j = 0; j < a; ++j) {
printf("%d\t", matrix[i][j]);
}
printf("\n");
}
}
Use functions. You print the matrix twice; you should have a function to print the matrix which you call twice.
With such a function, you'd not make the mistakes in the tail end of your code. For example, you could use this:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
static void print_matrix(const char *tag, int size, int matrix[size][size])
{
printf("%s (%dx%d):\n\n", tag, size, size);
for (int i = 0; i < size; ++i)
{
const char *pad = "";
for (int j = 0; j < size; ++j)
{
printf("%s%-2d", pad, matrix[i][j]);
pad = " ";
}
printf("\n\n");
}
}
int main(int argc, char **argv)
{
unsigned seed = time(0);
int a = 9;
int matrix[a][a];
if (argc == 2)
seed = atoi(argv[1]);
srand(seed);
printf("Seed: %u\n", seed);
for (int i = 0; i < a; ++i)
{
for (int j = 0; j < a; ++j)
matrix[i][j] = rand() % 100;
}
print_matrix("Matrix", a, matrix);
for (int i = 0, j = a - 1; i < a; ++i, --j)
{
int temp = matrix[i][i];
matrix[i][i] = matrix[i][j];
matrix[i][j] = temp;
}
print_matrix("The main and side diagonal", a, matrix);
return 0;
}
The code reports the seed it uses; that allows you to reproduce any run by specifying the seed to use as a command line argument.
Example output:
Seed: 1511470282
Matrix (9x9):
11 39 3 88 98 63 75 81 76
93 9 60 22 45 50 46 58 65
13 99 25 43 14 57 44 70 65
30 57 55 0 37 84 47 49 40
60 28 46 1 96 78 33 20 9
93 61 11 38 84 16 91 26 15
43 85 66 72 85 39 96 45 45
45 25 33 3 78 90 61 65 62
88 84 56 34 74 8 78 57 74
The main and side diagonal (9x9):
76 39 3 88 98 63 75 81 11
93 58 60 22 45 50 46 9 65
13 99 44 43 14 57 25 70 65
30 57 55 84 37 0 47 49 40
60 28 46 1 96 78 33 20 9
93 61 11 16 84 38 91 26 15
43 85 96 72 85 39 66 45 45
45 65 33 3 78 90 61 25 62
74 84 56 34 74 8 78 57 88
The swapping process, in case it isn't obvious, swaps the first and last elements of the first row, the second and last but one element in the second row, and so on, forming an X of swapped elements.

Program to code zigzag matrix

Recently, I encountered with a problem that asked me to write a dynamic code that print n x n matrix in a zigzag pattern. Please help me with the code to get the output stated below.
Output:
rows: 5
cols: 5
1 2 3 4 5
10 9 8 7 6
11 12 13 14 15
20 19 18 17 16
21 22 23 24 25
The Code that I've tried so far is in static:
#include <stdio.h>
int main(){
int arr[3][3]={1,2,3,
4,5,6,
7,8,9};
int i, j, k;
for(i=0; i<3; i++){
printf("%d",arr[0][i]);
}
printf("\n");
for(j=2; j>=0; j--){
printf("%d",arr[1][j]);
}
printf("\n");
for(k=0; k<3; k++){
printf("%d",arr[2][k]);
}
printf("\n");
return 0;
}
Now I want the same thing to be done with the user stating rows and columns of an array..
This should work for you:
#include <stdio.h>
int main() {
int rows, columns;
int rowCount, columnCount, count = 0;
printf("Please enter rows and columns:\n>");
scanf("%d %d", &rows, &columns);
for(rowCount = 0; rowCount < rows; rowCount++) {
for(columnCount = 1; columnCount <= columns; columnCount++) {
if(count % 2 == 0)
printf("%4d " , (columnCount+(rowCount*columns)));
else
printf("%4d " , ((rowCount+1)*columns)-columnCount+1);
}
count++;
printf("\n");
}
return 0;
}
Input:
5 5
Output:
1 2 3 4 5
10 9 8 7 6
11 12 13 14 15
20 19 18 17 16
21 22 23 24 25
Simple dynamic logic with k variable
#include <stdio.h>
int main() {
int i,j,k=1,row,col;
printf("Enter row and col \n>");
scanf("%d %d", &row, &col);
for (i = 1; i <=row; i++)
{
for (j = 1; j <=col; j++)
{
if(i%2==0) k--;
printf("%4d",k); // it have to be in center of both condition
if(i%2!=0) k++;
}
k=k+col;
printf("\n");
}
return 0;
}
Input :
7 7
Output :
1 2 3 4 5 6 7
14 13 12 11 10 9 8
15 16 17 18 19 20 21
28 27 26 25 24 23 22
29 30 31 32 33 34 35
42 41 40 39 38 37 36
43 44 45 46 47 48 49

Issue with printf precision control

I need to print out a multiplication table that looks like this in C:
1 2 3 4 5 6 7 8 9 10
1 1 2 3 4 5 6 7 8 9 10
2 4 6 8 10 12 14 16 18 20
3 9 12 15 18 21 24 27 30
4 16 20 24 28 32 36 40
5 25 30 35 40 45 50
6 36 42 48 54 60
7 49 56 63 70
8 64 72 80
9 81 90
10 100
My loop to print the numbers in the correct format is a bit tedious right now:
printf(" 1 2 3 4 5 6 7 8 9 10\n");
for(i=1; i<=10; i++)
{
printf("%4d", i);
for (j=i; j<=10; j++)
{
result = i*j;
if (i == 2 && j == 2)
{
printf("%8d", result);
}
else if (i == 3 && j == 3)
{
printf("%12d", result);
}
else if (i == 4 && j == 4)
{
printf("%16d", result);
}
else if (i == 5 && j == 5)
{
printf("%20d", result);
}
else if (i == 6 && j == 6)
{
printf("%24d", result);
}
else if (i == 7 && j == 7)
{
printf("%28d", result);
}
else if (i == 8 && j == 8)
{
printf("%32d", result);
}
else if (i == 9 && j == 9)
{
printf("%36d", result);
}
else if (i == 10 && j == 10)
{
printf("%40d", result);
}
else
{
printf("%4d", result);
}
}
printf("\n");
}
I was thinking there has to be a way to make this easier, to somehow concat an int variable into the precision of the number, like this:
if (i == j)
{
printf("%(4 * i)d", result);
}
else
{
printf("%4d", result);
}
This code obviously won't work, but is there a way I can achieve something like this so I can avoid all the if/else statements in my current loop?
This may not be exactly what you want but it should help you:
#include <stdio.h>
int main() {
int i, j, result;
printf(" 1 2 3 4 5 6 7 8 9 10\n");
for(i=1; i<=10; i++) {
printf("%3d %*s", i, i * 4, " ");
for (j=i; j<=10; j++) {
printf("%3d ", i * j);
}
printf("\n");
}
return 0;
}
Output:
1 2 3 4 5 6 7 8 9 10
1 1 2 3 4 5 6 7 8 9 10
2 4 6 8 10 12 14 16 18 20
3 9 12 15 18 21 24 27 30
4 16 20 24 28 32 36 40
5 25 30 35 40 45 50
6 36 42 48 54 60
7 49 56 63 70
8 64 72 80
9 81 90
10 100
Here is code that implements almost what you have as the desired output:
#include <stdio.h>
int main(void)
{
printf("%4s", " ");
for (int i = 1; i <= 10; i++)
printf("%4d", i);
putchar('\n');
for (int i = 1; i <= 10; i++)
{
printf("%-*d", 4 * i, i);
for (int j = i; j <= 10; j++)
printf("%4d", i * j);
putchar('\n');
}
return 0;
}
Output:
1 2 3 4 5 6 7 8 9 10
1 1 2 3 4 5 6 7 8 9 10
2 4 6 8 10 12 14 16 18 20
3 9 12 15 18 21 24 27 30
4 16 20 24 28 32 36 40
5 25 30 35 40 45 50
6 36 42 48 54 60
7 49 56 63 70
8 64 72 80
9 81 90
10 100
The difference is in the space at the start of the lines. Your desired output has 2 spaces for the row number, followed by 2 spaces for the 1 in the row labelled 1, followed by 4 spaces for each other entry. Mimicking that exactly is a little fiddly — doable, but fiddly:
#include <stdio.h>
int main(void)
{
for (int i = 1; i <= 10; i++)
printf("%4d", i);
putchar('\n');
for (int i = 1; i <= 10; i++)
{
printf("%-*d", 4 * i - ((i == 1) ? 2 : 4), i);
for (int j = i; j <= 10; j++)
printf("%*d", (j == 1) ? 2 : 4, i * j);
putchar('\n');
}
return 0;
}
The conditional expressions are not very elegant.

Resources