/*
 * program to print a triangle of numbers from top to bottom
 * needs curses to get line/col value from terminfo
 * compile with gcc (uses "long long" for 64-bit type)
 * compile: gcc pastri.c -lcurses
 * deepak/19jun07
 */

#ifndef __GNUC__
#error "gcc compiler needed!"
#endif

#include <stdio.h>
#include <string.h>
#include <ncurses.h>

/* return nCr given n and r */
unsigned int nCr(unsigned int n, unsigned int r)
{
  unsigned int i, j;
  unsigned long long npr, rfact;

  /* nCr = nC(n-r) */
  if (r >= n-r)
	r = n - r;

  /* nC0 = 1 always */
  if (r == 0)
	return 1;

  /* do n * (n-1) * ... r times */
  npr = n;
  for (i=n-1, j=1; j<r; i--, j++)
	npr *= (unsigned long long)i;

  /* do factorial(r) */
  rfact = 1;
  for (i=1; i<=r; i++)
	rfact *= (unsigned long long)i;

#ifdef DEBUG
  printf("%uC%u: %llu/%llu: %u\n", n, r, npr, rfact, npr/rfact);
#endif

  /* nCr = nPr / fact(r) */
  return (unsigned long)(npr / rfact);
}


int main(void)
{
  unsigned int i, j;

  /* get LINES, COLS values */
  initscr();
  endwin();

#ifdef DEBUG
  printf("lines: %d, cols: %d\n", LINES, COLS);
#endif

  for (i=0; i<=LINES; i++) {
	char line[BUFSIZ];			/* defined in stdio.h, usu. 1024 */
	unsigned int len, margin;

	line[0] = '\0';

	for (j=0; j<=i; j++) {
	  /* BUFSIZ is quite large for this buf, oh well... */
	  char buf[BUFSIZ];
	  /* get pascal triangle value */
	  snprintf(buf, BUFSIZ, "%u ", nCr(i, j));
	  strncat(line, buf, BUFSIZ);
	}

	len = strlen(line);
	/* resulting line became too big for our screen */
	if (len > COLS)
	  break;
	margin = (COLS - len) / 2;

	/* spaces to left */
	printf("%*c", margin, ' ');
	/* string itself */
	printf("%s", line);
	/* spaces to right */
	printf("%*c", margin, ' ');
	/* we are done with this line */
	printf("\n");
  }

  return 0;
}

