aamHimel
aamHimel

Reputation: 33

How to print an array in a particular triangular shape?

I have an array of ten elements {a, b, c, d, e, f, g, h, i, j}. I want to print it like this:

a  
b e
c f h
d g i j

Note that the first column consists of the first four values of my array. The second column (starting in row two) consists of the next three values of the array and so on.

My code is given below

#include <stdio.h>

#define size 10

int main() {
  int arr[size] = {14, 22, 34, 57, 44, 42, 33, 55, 48, 47};
  int i, j, n, c, maxTemp;
  n = 4;
  maxTemp = 1;
  c = n - 1;

  for (i = 0; i < n; i++) {
    for (j = i; j < maxTemp; j = j + c) {
      printf("%d ", arr[j]);
    }
    if (maxTemp <= size) {
      maxTemp = maxTemp + c + 1;
    }
    printf("\n");
  }
  return 0;
}

For the array

int arr[size] = {14, 22, 34, 57, 44, 42, 33, 55, 48, 47};

I expected

14  
22 44   
34 42 55  
57 33 48 47  

but got:

14  
22 44  
34 42 48   
57 33 47 13  

Here maybe this is happening because variable c value is not decreasing
because I wanted to decrease c's value by one. I've tried but couldn't figure out.

Upvotes: 3

Views: 1506

Answers (2)

NiVeR
NiVeR

Reputation: 9806

Although the answer of Yunnosch is perfectly fine, it involves some not trivial index calculation. In regard of that I propose my solution, which is certainly longer but I believe it is a bit more natural to follow.

Lets consider the example with the letters array = {a, b, c, d, e, f, g, h, i, j}. Following the idea that size of the array is triangular number, we can obtain that the number of elements in the longest column will be floor(sqrt(n * 2)) — in our case floor(sqrt(10 * 2)) = 4. Once we have that number, it lets us create the following matrix:

a b c d
0 e f g
0 0 h i 
0 0 0 j

This matrix is easy to make filling it by nested loop using as a limit the number of calculated previously. Once you have this matrix just take the transpose of it, and there you have your desired matrix. One may argue that the transposition is itself a complex operation but I think that since it is very well known operation it is easier to spot than calculating the indexes directly.

Implementation

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

int getT(int n){
    int sqr = sqrt(n*2);
    return sqr;
}

int main() {
    char a[10] = {14, 22, 34, 57, 44, 42, 33, 55, 48, 47};
    char b[10][10];

    int limit = getT(10);
    int index1d = 0;
    for(int i = 0; i < limit; i++){
        for(int j = 0; j < limit; j++){
            if(j < i) b[i][j] = 0;
            else{
                b[i][j] = a[index1d++];
            }
        }
    }
    //transposing by switching the indexes
    for(int i = 0; i < limit; i++){
        for(int j = 0; j <= i; j++){
            printf("%d ",b[j][i]);
        }
        printf("\n");
    }
}

Upvotes: 0

Yunnosch
Yunnosch

Reputation: 26763

Lets look at the indexes you want, they are

0
1 4
2 5 7
3 6 8 9

Fill up the empty spaces with linear numbers (we just not print them later)

0 (3  5  6)
1  4 (6  7)
2  5  7 (8)
3  6  8  9

The indexes, according to desired pattern rise through the columns.
That gives a linear relation to i, i.e. the index will be caculated invovling a i + ... part.

Each column (including the fill-in values inside "()") starts with higher value than the last number in the previous column, more or less higher by n.
But starting lower (i.e. using some of the values from previous column), in order to match the first empty (filled) rows.
That gives a linear relation to j*n, i.e. there will be a ... + j*n.

Lets try, here are the indexes as i+j*n.

0 4 8 12
1 5 9 13
2 6 10 14
3 7 11 15

These are too high, in each row by 0, 1, 3, 6.
E.g. look at the last row
3-0==3 7-1==6 11-3==8 15-6==9

That is j*(j+1)/2.
I did not find this myself by the way, so I used my favorite search engine to search for literally "0, 1, 3, 6"; and this popped up:
https://www.mathsisfun.com/algebra/triangular-numbers.html

Put it together and the correct index is:

i+j*n - j*(j+1)/2 

In code:

#include<stdio.h>
#define size 10

int main(void) {
  int arr[size] = {14, 22, 34, 57, 44, 42, 33, 55, 48, 47};
  int i, j, n=4;
  for (i = 0; i < n; i++)
  {
    for (j = 0; j < i+1; j++)
    {
      printf("%d ", i+j*n - j*(j+1)/2 );
    }
    printf("\n");
  }
  return 0;
}

Output:

0
1 4
2 5 7
3 6 8 9

Upvotes: 5

Related Questions