Home > Enterprise >  How to print a pattern using nested for loops?
How to print a pattern using nested for loops?

Time:10-07

How do I make my code have an output like this:

Enter your number: 4
1 1 1 2
2 2 2 3
3 3 3 4
4 4 4 5

I can't seem to figure out how to make it so the last digit prints the next value iteration.

#include <stdio.h>

int main(){

    int num;
    int i = 1;

    printf("Enter your number: ");
    scanf("%d", &num);

    for(i = 1; i<=num; i  ){
        for(int j = 0; j<num;   j)
        {
           printf("%d ",i);
        }
        printf("\n");
    }     

CodePudding user response:

All of these kinds of assignments are to try to get you to recognize a pattern.

The pattern you are given

1 1 1 2
2 2 2 3
3 3 3 4
4 4 4 5

is very close to

1 1 1 1
2 2 2 2
3 3 3 3
4 4 4 4

which is an easy nested loop. Write a solution to the easier pattern. Once you have that you can then you can fix it.

Hint: Notice that the only thing that changes is the last item of the inner loop.

Edit

This totally breaks the spirit of the assignment, and if you, dear student, ever try to submit something like this your professor will... probably not care, but also know full well that you didn’t do it. If I were your professor you’d lose marks, even if I knew you weren’t cheating and had written something this awesome yourself.

Single loop. Stuff added to pretty print numbers wider than one digit (except the very last). Maths, yo.

#include <stdio.h>
#include <math.h>

void print_off_by_one_square( int n )
{
  int width = (int)log10( n )   1;
  for (int k = 0;  k   < n*n ;)
    printf( "%*d%c", width, (k n)/n, (k%n) ? ' ' : '\n' );
}

int main(void)
{
  int n;
  printf( "n? " );
  fflush( stdout );
  if ((scanf( "%d", &n ) != 1) || (n < 0))
    fprintf( stderr, "%s\n", "Not cool, man, not cool at all." );
  else
    print_off_by_one_square( n );
  return 0;
}

The way it works is pretty simple, actually, but I’ll leave it as an exercise for the reader to figure out on his or her own.

CodePudding user response:

Doing this using nested loops are simple and doesn't require any kind of special calculations, if-statements or other more or less fancy stuff. Just keep it simple.

Your task is:

for each row:
    print "rowindex 1 and a space" n-1 times
    print "rowindex 2 and a newline" 1 time

"for each row" is one simple loop.

"n-1 times" is another (nested) simple loop.

So keep it simple... just two ordinary for-loops like:

#include <stdio.h>

int main()
{
    int n = 4;
    for (int i = 0; i < n; i  )  // for each row
    {
        for (int j = 0; j < n-1; j  ) // n-1 times
        {
            printf("%d ", i   1);
        }

        printf("%d\n", i   2);  // 1 time
    }

    return 0;
}

CodePudding user response:

Here is something kind of from out in the left field, and off topic, leaving behind not only the requirements of the homework, but the C language. However, we will find our way back.

We can solve this problem (sort of) using text processing at the Unix prompt:

We can treat the smallest square

12
23

as an initial seed kernel, which is fed through a little command pipeline to produce a square of the next size (up to a single digit limitation):

We define this function:

next()
{
  sed -e 's/\(.\).$/\1&/' | awk '1; END { print $0 | "tr \"[1-9]\" \"[2-8]\"" }'
}

Then:

$ next
12
23
[Ctrl-D][Enter]
112
223
334

Now, copy the 3x3 square and paste it into next:

$ next
112
223
334
[Ctrl-D][Enter]
1112
2223
3334
4445

Now, several steps in one go, by piping through multiple instances of next:

$ next | next | next | next | next
12
23
[Ctrl-D][Enter]
1111112
2222223
3333334
4444445
5555556
6666667
7777778

The text processing rule is:

  1. For each line of input, repeat the second-to-last character. E.g ABC becomes ABBC, or 1112 becomes 11112. This is easily done with sed.

  2. Add a new line at the end which is a copy of the last line, with each digit replaced by its successor. E.g. if the last line is 3334, make it 4445. The tr utility helps here

To connect this to the homework problem: a C program could be written which works in a similar way, starting with an array which holds the 1 2 2 3 square, and grows it. The requirement for nested loops would be satisfied because there would be an outer loop iterating on the number of "next" operations, and then an inner loop performing the edits on the array: replicating the next-to-last column, and adding the new row at the bottom.

#include <stdio.h>
#include <stdlib.h>

#define DIM 25

int main(int argc, char **argv)
{
  if (argc != 2) {
    fputs("wrong usage\n", stderr);
    return EXIT_FAILURE;
  }

  int n = atoi(argv[1]);

  if (n <= 2 || n > DIM) {
    fputs("invalid n\n", stderr);
    return EXIT_FAILURE;
  }

  int array[DIM][DIM] = {
    { 1, 2 },
    { 2, 3 }
  };

  /* Grow square from size 2 to size n */
  for (int s = 2; s < n; s  ) {
    for (int r = 0; r < s; r  ) {
      array[r][s] = array[r][s-1];
      array[r][s-1] = array[r][s-2];
    }
    for (int c = 0; c <= s; c  ) {
      array[s][c] = array[s-1][c]   1;
    }
  }

  /* Dump it */
  for (int r = 0; r < n; r  ) {
    for (int c = 0; c < n; c  )
      printf("= ", array[r][c]);
    putchar('\n');
  }

  return 0;
}

CodePudding user response:

#include<stdio.h>
int main(){

int n;

printf("Enter the number: ");
scanf("%d",&n);

for(int i =1; i<=n; i  ){
     for(int j=1;j<=n;j  ) {
        if(j==n) 
            printf("%d\t",i 1);
        else
        printf("%d\t",i);
     }
     printf("\n");
}
return 0;}

CodePudding user response:

Nested loops will drive you crazy, trying figure out their boundaries.

While I usually oppose adding more variables, in this case it seems justified to keep track of things simply.

#include <stdio.h>

int main() {

    int n = 4, val = 1, cnt1 = 1, cnt2 = 0;

    for( int i = 1; i < n*n 1; i   ) { // notice the 'square' calculation
        printf( "%d ", val );
        if(   cnt1 == n ) // tired of this digit? start the next digit
            cnt1 = 0, val  ;
        if(   cnt2 == n ) // enough columns output? start the next line
            cnt2 = 0, putchar( '\n' );
    }

    return 0;
}
1 1 1 2
2 2 2 3
3 3 3 4
4 4 4 5

A single example of desired output is hard to go by, especially when the code doesn't help... Anyway, here's the output when 'n' = 5.

1 1 1 1 2
2 2 2 2 3
3 3 3 3 4
4 4 4 4 5
5 5 5 5 6

CodePudding user response:

Here is a different concept. Some of the answers are based on the idea that we first think about

1 1 1 1
2 2 2 2
3 3 3 3
4 4 4 4

and then tweak the logic for the item in the last line.

But we can regard it like this also:

We have a tape which goes like this:

1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4

and we are blindly cutting the tape into four-element pieces to form a 4x4 square. Suppose someone deletes the first item from the tape, and then adds 5:

1 1 1 2 2 2 2 3 3 3 3 4 4 4 4 5

Now, if we cut that tape blindly by the same process, we will get the required output:

1 1 1 2
2 2 2 3
3 3 3 4
4 4 4 5

Suppose we have a linear index through the tape, a position p starting at 0.

In the unshifted tape, item p is calculated using p / 4 1, right?

In the shifted tape, this is just (p 1) / 4 1. Of course we substitute the square size for 4.

Thus:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
  if (argc != 2) {
    fputs("wrong usage\n", stderr);
    return EXIT_FAILURE;
  }

  int n = atoi(argv[1]);
  int m = n * n;

  if (n <= 0) {
    fputs("invalid n\n", stderr);
    return EXIT_FAILURE;
  }

  for (int p = 0; p < m; p  ) {
    printf("= ", (p   1) / n   1);
    if (p % n == n - 1)
      putchar('\n');
  }

  return 0;
}
$ ./square 2
  1   2 
  2   3 
$ ./square 3
  1   1   2 
  2   2   3 
  3   3   4 
$ ./square 4
  1   1   1   2 
  2   2   2   3 
  3   3   3   4 
  4   4   4   5 
  •  Tags:  
  • c
  • Related