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.
Related
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;
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.
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;
}
I am writing 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:
The Code that I've tried so far with help of Rizier123 is in horizontal zigzag pattern:
#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
I want the same zigzag pattern output but vertically..
EDIT
Expected output:
1 10 11 20 21 30
2 9 12 19 22 29
3 8 13 18 23 28
4 7 14 17 24 27
5 6 15 16 25 26
This should work for you:
#include <stdio.h>
int main() {
int rows, columns;
int rowCount, columnCount;
printf("Please enter rows and columns:\n>");
scanf("%d %d", &rows, &columns);
for(rowCount = 0; rowCount < rows; rowCount++) {
for(columnCount = 0; columnCount < columns; columnCount++) {
if(columnCount % 2 == 0)
printf("%4d " , rows*(columnCount)+rowCount+1);
else
printf("%4d " , (rows*(columnCount+1))-rowCount);
}
printf("\n");
}
return 0;
}
Input:
5 5
Output:
1 10 11 20 21
2 9 12 19 22
3 8 13 18 23
4 7 14 17 24
5 6 15 16 25
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