Triangle made with printf, consists of inner frames - c

I posted a question before about a similar idea but with a rectangle,
this time, I got an assignment in which I'm supposed to draw a isosceles right triangle in this way:
I get the size of the triangle's edge as an input from the user;
the triangle's angle will be at the top left corner of the screen, the triangle's frame will be made of the letter a, the inner triangle's frame will be made of b's, the inner frame of the inner traingle of the inner triangle will be made of c and so on...
for example:
aaaaaaaaaaaa
abbbbbbbbba
abccccccba
abcdddcba
abcddcba
abcdcba
abccba
abcba
abba
aba
aa
a
This is what I got so far:
#include <stdio.h>
int main()
{
int length, originalLength;
int counterRows, counterLength;
scanf("%d", &length);
originalLength=length;
for (counterRows=0 ; length > 0; --length, ++counterRows)
{
for(counterLength=0; counterLength<length ;++counterLength)
{
if (counterRows == 0 || counterLength >= originalLength - 2)
printf("%c",'a');
else if (counterRows == 1 || counterRows == originalLength -3)
if (counterLength == 0 || counterLength == length -1)
printf("%c",'a');
else
printf("%c",'a'+1);
else
if (counterLength == 0 || counterLength == length - 1)
printf("a");
else if (counterLength == 1 || counterLength == length - 2)
printf("%c",'a'+1);
else
printf("%c",'a'+2);
}
printf("\n");
}
return 0;
}
and then i noticed that i keep repeating myself and i can't really do this until i reach the letter z. what other better way is there for such algorithm? thanks!

One way to work out a general construction is to observe that there's a triangular pattern within the rows of the triangle. Consider a triangle of size 10, meaning that the top row is 10 characters long. Look at the top four rows:
aaaaaaaaaa
abbbbbbba
abccccba
abcdcba
abccba
abcba
abba
aba
aa
a
There are 10 'a' characters in the top row, 7 'b' characters in the second row, 4 'c' characters in the third row, and 1 'd' character in the fourth row. We can decompose these rows into a middle segment and outer segments:
aaaaaaaaaa aaaaaaaaaa ..........
abbbbbbba .bbbbbbb. a.......a
abccccba ..cccc.. ab....ba
abcdcba ...d... abc.cba
The middle segment has length size-3*i, where size is the length of the top row and i is the row index, starting from 0 at the top. The outer segments consist of characters from 'a' through 'a'+i-1 on the left side, and the same sequence in reverse on the right side.
What about the bottom portion of the triangle? It starts when size-3*i is negative.
abccba
abcba
abba
aba
aa
a
Each row has a rising and falling sequence of characters. In the row of six characters, for example, we can compute each character by sequentially adding 0, 1, 2, 2, 1, 0 to the base character 'a'.
a b c c b a
0 1 2 2 1 0
In the row of five characters, the sequence is 0, 1, 2, 1, 0:
a b c b a
0 1 2 1 0
In general, for a row of length characters, the character at index j has the value 'a'+j or 'a'+length-1-j, whichever is smaller.
Let's illustrate this with a row of six characters.
n = 6:
j = 0 1 2 3 4 5
n-1-j = 5 4 3 2 1 0
min(j, n-1-j) = 0 1 2 2 1 0
Putting it all together, we can generate a triangle with the following code.
for (i = 0; i < size; ++i) {
middle = size-3*i;
if (middle >= 0) { /* Upper portion of the triangle. */
for (j = 0; j < i; ++j) {
printf("%c", 'a'+j); /* Left segment: abc... */
}
for (j = 0; j < middle; ++j) {
printf("%c", 'a'+i); /* Middle: size-3*i characters */
}
for (j = i-1; j >= 0; --j) {
printf("%c", 'a'+j); /* Right segment: ...cba */
}
} else { /* Now we're in the lower portion. */
length = size-i;
for (j = 0; j < length; ++j) {
printf("%c", 'a'+(j < length-1-j ? j : length-1-j));
} /* Rising and falling sequence. */
}
printf("\n");
}
Below is a complete program that gets the size of the triangle from the command line. You can easily modify it to read the desired size with scanf, as in the code you showed in the question.
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **args) {
int size, middle, length, i, j;
if (argc != 2) {
printf("must enter the triangle size\n");
return 0;
}
size = atoi(args[1]);
if (size < 1 || size > 26) {
printf("the size must be in the range [1, 26]\n");
return 0;
}
printf("size = %d\n\n", size);
for (i = 0; i < size; ++i) {
middle = size-3*i;
if (middle >= 0) { /* Upper portion of the triangle. */
for (j = 0; j < i; ++j) {
printf("%c", 'a'+j); /* Left segment: abc... */
}
for (j = 0; j < middle; ++j) {
printf("%c", 'a'+i); /* Middle: size-3*i characters */
}
for (j = i-1; j >= 0; --j) {
printf("%c", 'a'+j); /* Right segment: ...cba */
}
} else { /* Now we're in the lower portion. */
length = size-i;
for (j = 0; j < length; ++j) {
printf("%c", 'a'+(j < length-1-j ? j : length-1-j));
} /* Rising and falling sequence. */
}
printf("\n");
}
return 0;
}

#include <stdio.h>
#define min(a,b) a < b ? a : b
void print_line(int len, int row, int level){
int deep = min(row, level);
if(len > 1){
putchar('a' + deep);
print_line(len-2, row, level + 1);
putchar('a' + deep);
} else if(len == 1){
putchar('a' + deep);
}
}
int main(){
int length, originalLength;
int i;
scanf("%d", &length);
originalLength=length;
for(i=0; i< originalLength; ++i){
print_line(length--, i, 0);
putchar('\n');
}
return 0;
}

Related

C, 2D Array, How to find specific number in all 8 directions

You are allowed to enter only 0 and 1 as values in the arrays. Then in place of all elements having a value of 0, enter the number of elements with a value of 1 around that element in all eight directions. And on the end print the 2d array and the values with 1 change to *.
Here is an example how it's supposed to look like:
Here is my code
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n,m;
scanf("%d%d", &n, &m);
int a[n][m];
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
scanf("%d", &a[i][j]);
if(a[i][j]==1){
a[i][j]=9;
}
}
}
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
int counter=0;
if(a[i][j]==9){
printf("*\t");
}else if(a[i][j]==0){
if(a[i+1][j+1]==9 && i!=n && j!=m) counter++;
if(a[i-1][j-1]==9 && i!=0 && j!=0) counter++;
if(a[i+1][j-1]==9 && i!=n && j!=0) counter++;
if(a[i-1][j+1]==9 && i!=0 && j!=m) counter++;
if(a[i][j+1]==9 && j!=m) counter++;
if(a[i][j-1]==9 && j!=0) counter++;
if(a[i+1][j]==9 && i!=n) counter++;
if(a[i-1][j]==9 && i!=0) counter++;
a[i][j]=counter;
counter=0;
printf("%d\t", a[i][j]);
}
}
printf("\n");
}
return 0;
}
You have UB (undefined behavior).
With (e.g.):
if (a[i + 1][j + 1] == 9 && i != n && j != m)
Then, a is always fetched, even if i or j is out of range.
To fix this, reorder the terms:
if (i != n && j != m && a[i + 1][j + 1] == 9)
Now, if either i or j is out of range, then the if will be "short circuited": (i.e. _short circuit evaluation) and the a value will not be fetched.
But, your program output is incorrect. You're coding everything out longhand. It makes it hard to debug (i.e. which lines have a bug).
What wasn't explicitly described was that you are summing the non-zero values in a 3x3 kernal around a given zero point.
The hardcoding doesn't scale too well. Suppose the kernal had to be 100x100. Would we code up 10,000 lines of code?
It's much easier to debug if we refactor to use for loops. And, to use more descriptive names instead of i/j/m/n:
n hgt
m wid
i y*
j x*
Here is the code:
#include <stdio.h>
#include <stdlib.h>
int
main(int argc,char **argv)
{
int hgt, wid;
int counter;
FILE *xf;
--argc;
++argv;
if (argc > 0)
xf = fopen(*argv,"r");
else
xf = stdin;
if (xf == NULL) {
perror(*argv);
exit(1);
}
fscanf(xf,"%d%d", &hgt, &wid);
int a[hgt][wid];
for (int ycur = 0; ycur < hgt; ycur++) {
for (int xcur = 0; xcur < wid; xcur++) {
int val;
fscanf(xf,"%d", &val);
if (val == 1)
val = 9;
a[ycur][xcur] = val;
}
}
for (int yctr = 0; yctr < hgt; yctr++) {
for (int xctr = 0; xctr < wid; xctr++) {
if (a[yctr][xctr] == 9) {
printf("*\t");
continue;
}
counter = 0;
for (int yoff = -1; yoff <= 1; yoff++) {
int ycur = yctr + yoff;
if (ycur < 0)
continue;
if (ycur >= hgt)
continue;
for (int xoff = -1; xoff <= 1; xoff++) {
int xcur = xctr + xoff;
if (xcur < 0)
continue;
if (xcur >= wid)
continue;
counter += (a[ycur][xcur] == 9);
}
}
printf("%d\t",counter);
}
printf("\n");
}
return 0;
}
Here is the program output for your sample input:
* 1 1 2 *
2 2 2 * 3
* 1 2 * 2
Not sure what the question is, but there are bugs in the code -
you are accessing out of array boundaries by doing, for example, this:
if(a[i-1][j-1]==9 && i!=0 && j!=0)
When i and j are zeros you are reading the value of a[-1][-1]. Changing the order of conditions and checking i and j first would guard against such an access.
Same happens when you access the "borders" of the matrix.
And, the "i!=n && j!=m" condition is always true within the loops - you iterate as long as i<n and j<m.
But aside of that, some of these accesses in fact read from within the array, but from a wrong location.
Here is an example that shows that:
Given the matrix of 2x2
0 1
1 0
This is the result your code produced:
2 *
* 3
Where obviously, '3' is wrong.
Why it happened?
The 2D array is in fact stored as a 1D array in memory, like this:
0 1 1 0 // this is your data
0 1 2 3 // this is the index in the array (offset from the array start)
And each element is located at an offset of row*columns+column from the array start (i.e. this is the formula to find the index in 1D array given i and j).
When you count the '1'-neighbours for the last element (a[1][1] in this example), you count the two obvious results (at a[1][0] and a[0][1]), but then you hit this condition:
if(a[i-1][j+1]==9 && i!=0 && j!=m)
For this last cell, i is 1 and j is 1, so the second part of the condition is true.
But what about a[i-1][j+1]==9 ?
This references a memory at row*columns+column, right? I.e. (i-1)*2+(j+1), because that's what you tried to access. Substituting i and j with 1 and 1, and you get offset 2 in the 1D array above.
Which is 1 in the input matrix (or actually 9 since you've replaced it).
So you count it twice.
Guarding better against "stepping out" of the matrix (but not necessarily out of the actual array) will solve this bug.

How can I fill a 2D array spirally in C? Example/problem

so I've been struggling with this example for a good hour now and I can't even begin to process how should I do this.
Write a program that, for given n and m, forms a matrix as described.
The matrix should be m x m, and it's filled "spirally" with it's
beginning in the upper left corner. The first value in the matrix is
the number n. It's repeated until the "edge" of the matrix, at which
point the number increments. After the number 9 goes 0. 0 ≤ n ≤ 9, 0 ≤
m ≤ 9
Some time ago I had made a function to display the numbers 1 to n on an odd-sized grid.
The principle was to start from the center and to shift by ;
x = 1
x box on the right
x box on the bottom
x++
x box on the left
x box at the top
x++
With this simple algorithm, you can easily imagine to maybe start from the center of your problem and decrement your value, it seems easier to start from the center.
Here is the code that illustrates the above solution, to be adapted of course for your problem, it's only a lead.
#define WE 5
void clock(int grid[WE][WE])
{
int count;
int i;
int reach;
int flag;
int tab[2] = {WE / 2, WE / 2}; //x , y
count = 0;
flag = 0;
i = 0;
reach = 1;
grid[tab[1]][tab[0]] = count;
for (int j = 0; j < WE - 1 && grid[0][WE - 1] != pow(WE, 2) - 1; j++)
for (i = 0; i < reach && grid[0][WE - 1] != pow(WE, 2) - 1; i++, reach++)
{
if(flag % 2 == 0)
{
for(int right = 0 ; right < reach ; right++, tab[0]++, count++, flag = 1)
grid[tab[1]][tab[0]] = count;
if(reach < WE - 1)
for(int bottom = 0; bottom < reach; bottom++, count++, tab[1]++)
grid[tab[1]][tab[0]] = count;
}
else
{
for(int left = 0; left < reach; left++, count++, tab[0]--, flag = 0)
grid[tab[1]][tab[0]] = count;
for(int top = 0; top < reach; top++, tab[1]--, count++)
grid[tab[1]][tab[0]] = count;
}
}
}
I finally solved it. If anybody's interested, here's how I did it:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
//Fills the row number "row" with the number n
int fillRow(int m, int n, int arr[m][m], int row)
{
int j;
for(j=0;j<m;j++)
{
if(arr[row][j] == -1 || arr[row][j] == n-1) arr[row][j] = n;
}
}
//Fills the column number "col" with the number n
int fillCol(int m, int n, int arr[m][m], int col)
{
int i;
for(i=0;i<m;i++)
{
if(arr[i][col] == -1 || arr[i][col] == n-1) arr[i][col] = n;
}
}
int main()
{
int n, m, i, j, r=1, c=1, row=-1, col=-1;
scanf("%d %d",&n, &m);
int arr[m][m];
//Fill array with -1 everywhere
for(i=0;i<m;i++)
{
for(j=0;j<m;j++)
{
arr[i][j] = -1;
}
}
//Calculate which row/column to fill (variables row/col)
//Fill row then column then row than column...
for(i=0;i<2*m;i++)
{
if(i%2==0)
{
row = (r%2==0) ? m-r/2 : r/2;
fillRow(m, n, arr, row);
n++;
r++;
}
else if(i%2==1)
{
col = (c%2==0) ? c/2-1 : m-c/2-1;
fillCol(m, n, arr, col);
n++;
c++;
}
}
//If an element is larger than 9, decrease it by 10
//Prints the elements
for(i=0;i<m;i++)
{
for(j=0;j<m;j++)
{
if(arr[i][j]>9) arr[i][j] -=10;
printf("%d ",arr[i][j]);
}
printf("\n");
}
return 0;
}

Programming in C - CS50 Mario pyramid blocks print - For loops difficulties

I am working on this problem from the CS50 class. I am still a beginner. What I need to program is this:
Toward the end of World 1-1 in Nintendo’s Super Mario Brothers, Mario
must ascend right-aligned pyramid of blocks, a la the below.
screenshot of Mario jumping up a right-aligned pyramid
Let’s recreate that pyramid in C, albeit in text, using hashes (#) for
bricks, a la the below. Each hash is a bit taller than it is wide, so
the pyramid itself is also be taller than it is wide.
#
##
###
####
#####
######
#######
########
The program we’ll write will be called mario. And let’s allow the user
to decide just how tall the pyramid should be by first prompting them
for a positive integer between, say, 1 and 8, inclusive.
However I have tried many ways, two of which are these:
code mariov1
After looking at some Stack Overflow attempts, it now looks like this:
#include <cs50.h>
#include <stdio.h>
string hash(int);
int main(void)
{
int n;
do
{
n = get_int("Height: ");
}
while (n < 0 || n > 8);
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n-1-i; j++)
{
for(int j = 0; j < i+1; j++)
{
printf(".");
}
printf("#");
}
printf("\n");
}
}
What can I try next?
Suriyu, to add to what Weather Vane said. To pass it through Check50, you'll still need to make small tweaks to the code so that it passes through all CS50 tests.
For the do-while loop, n <=0 instead of n < 0 to ask for an input when n = 0, because the specification demands a minimum of one brick (1 to 8 both inclusive).
You need only the two loops, don't print extra characters not specified in the problem set, ex: printf(".");
All the best with CS50, it's going to be a fun experience!
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int n;
do
{
n = get_int("Height: ");
}
while (n < 1 || n > 8);
// this for loop makes new lines
for (int i = 0; i < n; i++)
{
// here I have two for loops nested inside the above for loop,
// I previously made the mistake of having two inner loops nested.
// this 2nd for loop prints n-1-i spaces
// because if n=5, then in the 4th row, there will be 5-1-3 spaces/dots
for (int j = 0; j < n - 1 - i; j++)
{
printf(" ");
}
// this 3rd for loop prints i+1 hashes
// because if n=5, then in the 4th row, there will be 3+1 hashes.
// (3 because you count from 0)
for (int j = 0; j < i + 1; j++)
{
printf("#");
}
printf("\n");
}
}
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int n;
do
{
n = get_int("Height of the pyramid is:\n");
}
while (n < 1 || n > 8); //condition to get a number from 1-8 from the user
for (int i = 0; i < n; i++) //loop for height
{
for (int j = 0; j < n - 1 - i; j++) //loop for spaces on left pyramid
{
printf(" ");
}
for (int k = 0; k < i + 1; k++) // loop for hashes on left pyramid
{
printf("#");
}
printf(" "); // spacing between pyramids
for (int p = 0; p <= i; p++) //loop for right pyramid
{
printf("#");
}
printf("\n");
}
}
This is the advanced version of the problem if you decide to try it.
Here's a different approach. Instead of iteratively printing blanks, followed by iteratively printing number signs, this version creates a buffer (size defined by a precompiler constant - currently set to 8, change it if you want to allow bigger pyramids), then for each row in the pyramid it first fills the buffer with number signs, then overlays the beginning of the line with the proper number of spaces, and then prints it:
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#define MAXSIZE 8
int main(void)
{
int size, spaces;
char buf[MAXSIZE+1];
do
size = get_int("Height: ");
while (size < 0 || size > MAXSIZE);
buf[size] = '\0';
for(spaces = size-1 ; spaces >= 0 ; --spaces)
printf("%s\n", (char *)memset(memset(buf, '#', size), ' ', spaces));
}
EDIT
And here's yet another approach which builds the entire output block in an array in memory and then prints it using a single call to puts:
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#define MAXSIZE 8
#define TOTSIZE ((MAXSIZE+1) * MAXSIZE)
int main(void)
{
int size, spaces;
char buf[TOTSIZE+1];
do
size = get_int("Height: ");
while (size < 0 || size > MAXSIZE);
memset(buf, '\n', (size+1)*size);
buf[((size+1)*size)] = '\0';
for(char *p = buf, spaces = size-1 ; *p != '\0' ; p += size+1, --spaces)
memset(memset(p, '#', size), ' ', spaces);
puts(buf);
}
This is an option that likely works best:
from cs50 import get_int
while True:
n=get_int("Enter Height: ")
if n>=1 and n<=8:
break
for i in range(0, n-1):
print(" " * (n - (i+1)) + "#" * (i+1))

how to write a code that prints an specific numerical spiral pattern in c using for loops without array

I want to write a code that gets the integer n from the user and prints numbers in a spiral pattern from 1 to n*n without using arrays.
output for entering 5
input3
output:
1 2 3
8 9 4
7 6 5
do you have any suggestions on how to write this code?
EDIT:
here is the code using arrays:
#include <stdio.h>
int main(){
/*declaration of the variables*/
int i, j, ascendingNumbers;
int leftAndTop, rightAndBottom;
int size;
scanf("%d", &size);
int matrix[size][size];
leftAndTop = 0;
rightAndBottom = size - 1;
ascendingNumbers = 1;
/*filling the array*/
for(i = 1; i <= size/2; i++, leftAndTop++, rightAndBottom--){
/*left to right*/
for(j = leftAndTop; j <= rightAndBottom; j++, ascendingNumbers++){
matrix[leftAndTop][j] = ascendingNumbers;
}
/*top to bottom*/
for(j = leftAndTop + 1; j <= rightAndBottom; j++, ascendingNumbers++){
matrix[j][rightAndBottom] = ascendingNumbers;
}
/*right to left*/
for(j = rightAndBottom-1; j >= leftAndTop; j--, ascendingNumbers++){
matrix[rightAndBottom][j] = ascendingNumbers;
}
/*bottom to top*/
for(j = rightAndBottom - 1; j >= leftAndTop+1; j--, ascendingNumbers++){
matrix[j][leftAndTop] = ascendingNumbers;
}
}
/*fill the center for odd size*/
if(size % 2){
matrix[leftAndTop][j + 1] = ascendingNumbers;
}
/*print*/
for(i = 0; i < size; i++){
for(j = 0; j < size; j++){
printf("%d ", matrix[i][j]);
}
printf("\n");
}
return 0;
}
One solution is to take code that already can fill an array with the spiral pattern, and put it in a nested loop that uses that code to find the number for the current printing position. There are certainly more efficient solutions, but this allows you to transform a solution that works for arrays into one that does not need arrays.
The first program here uses an array to print a spiral pattern of numbers. The second program is a modified version of the first that prints a number when the printing position matches the position in the spiral loop instead of storing it in an array. I'll leave it to you to see if you can modify your existing code to accomplish this.
Using a 2d array:
/* A program that prints a spiral using a 2d array */
#include <stdio.h>
int main(int argc, char *argv[])
{
int size;
if (argc < 2 || (sscanf(argv[1], "%d", &size) != 1) || size < 1) {
fprintf(stderr, "Usage: spiral N [N > 0]\n");
return 1;
}
int arr[size][size];
int num_elems = size * size;
enum Dir { RIGHT, DOWN, LEFT, UP };
int num_directions = 4;
int side_len = size;
int row = 0; // arr row index
int col = 0; // arr column index
int pos = 0; // position in a side
// travel around the spiral to fill the array
enum Dir direction = RIGHT;
for (int i = 0; i < num_elems; i++) {
arr[row][col] = i + 1;
++pos;
if (pos == side_len) { // change direction
direction = (direction + 1) % num_directions;
pos = 0;
// having changed direction, shorten side_len in two cases
if (direction == DOWN || direction == UP) {
--side_len;
}
}
switch (direction) {
case RIGHT:
++col;
break;
case DOWN:
++row;
break;
case LEFT:
--col;
break;
case UP:
--row;
break;
default:
fprintf(stderr, "Unexpected value in switch statement\n");
return 1;
}
}
for (row = 0; row < size; row++) {
for (col = 0; col < size; col++) {
printf("%4d", arr[row][col]);
}
putchar('\n');
}
putchar('\n');
return 0;
}
Using only loops:
/* A program that prints a spiral using loops but no arrays */
#include <stdio.h>
int main(int argc, char *argv[])
{
int size;
if (argc < 2 || (sscanf(argv[1], "%d", &size) != 1) || size < 0) {
fprintf(stderr, "Usage: spiral N [N >= 0]\n");
return 1;
}
int num_elems = size * size;
enum Dir { RIGHT, DOWN, LEFT, UP };
int num_directions = 4;
// loop printing positions: print a row at a time
for (int y = 0; y < size; y++) {
for (int x = 0; x < size; x++) {
int side_len = size; // length of current side
int row = 0; // arr row index
int col = 0; // arr column index
int pos = 0; // position in a side
// travel around spiral until printing number is reached
enum Dir direction = RIGHT;
for (int i = 0; i < num_elems; i++) {
if (row == y && col == x) { // print and escape loop
printf("%4d", i + 1);
break;
}
++pos;
if (pos == side_len) { // change direction
direction = (direction + 1) % num_directions;
pos = 0;
// having changed direction, shorten side_len in two cases
if (direction == DOWN || direction == UP) {
--side_len;
}
}
switch (direction) {
case RIGHT:
++col;
break;
case DOWN:
++row;
break;
case LEFT:
--col;
break;
case UP:
--row;
break;
default:
fprintf(stderr, "Unexpected value in switch statement\n");
return 1;
}
}
}
// newline after row
putchar('\n');
}
// newline after printing all numbers
putchar('\n');
return 0;
}
Here are a couple of sample interactions with the second program:
>$ ./spiral2 3
1 2 3
8 9 4
7 6 5
>$ ./spiral2 6
1 2 3 4 5 6
20 21 22 23 24 7
19 32 33 34 25 8
18 31 36 35 26 9
17 30 29 28 27 10
16 15 14 13 12 11

Pascal's triangle in C weird output

I'm trying to write a program to display Pascal's triangle up to a user-inputted number of levels. We aren't allowed to use the factorial method. My current code is this:
#include <stdio.h>
void trianglePrint(const int numLevels);
int main() {
int numLevels;
printf("Please enter how many levels of Pascal's Triangle you would
like to see: ");
scanf("%d", &numLevels);
trianglePrint(numLevels);
return 0;
}
void trianglePrint(const int numLevels) {
int pascalTriangle[28][28];
int i, j;
for (i = 0; i < numLevels; ++i) {
for (j = 0; j <= i; ++j) {
if (i == 0 || i == 1 || j == 0 || j == numLevels) {
pascalTriangle[i][j] = 1;
printf("%d ", pascalTriangle[i][j]);
}
else {
pascalTriangle[i][j] = pascalTriangle[i - 1][j - 1] +
pascalTriangle[i - 1][j];
printf("%d ", pascalTriangle[i][j]);
}
}
printf("\n");
}
}
We're only supposed to be able to go up to 28 levels, which is why I am using an array of size 28 in both dimensions.
This works fine for about 6 levels of the triangle, but for larger levels it gives really large integers. I assumed it was due to uninitialized arrays, but I'm not sure. Does anyone know where the error is?
If you change
if (i == 0 || i == 1 || j == 0 || j == numLevels)
to
if (i == 0 || i == 1 || j == 0 || j == i)
(thanks to Melpomene), then all accesses to your array end up on already intiailised members.
That solves the strange numbers.
Output:
Please enter how many levels of Pascal's Triangle you would like to see: 6
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
Process returned 0 (0x0) execution time : 2.264 s
Press any key to continue.
Note:
Also initialising an array is a wise precaution. You could initialise with values which help finding an error, instead of hiding it, e.g. 42.
The problem is that you haven't set pascalTriangle[i - 1][j] before you use it to compute pascalTriangle[i][j] in the else clause.
Try the code
void Pascal(int n)
{
int arr[n][n];
for (int i = 0; i < n; i++)
{
for (int j = 0; j <= i; j++)
{
// First and last values in every row are 1
if (i == j || j == 0)
arr[i][j] = 1;
else // Other values are sum of values just above and left of above
arr[i][j] = arr[i-1][j-1] + arr[i-1][j];
printf("%d ", arr[i][j]);
}
printf("\n");
}
}

Resources