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

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.

Related

Checking monotonic sequences - C programming

I am doing a problem about checking monotonic sequences. The problem is inputting a sequence and then print "YES" if it is monotonic, "NO" if it is not.
This is my code:
#include <stdio.h>
int main()
{
//Inputting the sequence
int n;
scanf("%d", &n);
int a[n];
for (int i = 1; i <= n; i++)
{
scanf("%d ", &a[i]);
}
//Checking monotonic sequence
for (int i = 1; i <= n; i++)
{
if ((a[i] > a[i-1]) && (a[i] > a[i+1]))
{
printf("NO");
return;
}
else if ((a[i] < a[i-1]) && (a[i] < a[i+1]))
{
printf("NO");
return;
}
}
printf("YES");
return 0;
}
I have failed 2 test case with sequences [1, 2, 3] and [10, 6, 4, 2, 1, -100]; and passed one test case with [1, 2, 3, 3, 2, 1]. Can anyone please point out the problem in my code? I would truly appreciate that. Thank you.
Remove trailing " ". It obliges additional input (or end-of-file) after the number is entered before scanf() returns.
// scanf("%d ", &a[i]);
scanf("%d", &a[i]);
In addition to index problems in 2 places, code needs to look for overall monotonic and not just local monotonic behavior.
bool up = true;
bool down = true;
// for (int i = 1; i <= n; i++)
for (int i = 1; i < n; i++) {
if (a[i] > a[i-1]) down = false;
if (a[i] < a[i-1]) up = false;
}
printf((up || down) ? "YES" : "NO");
Additional code to short-circuit loop.
// for (int i = 1; i < n; i++) {
for (int i = 1; i < n && (up || down); i++) {
Further there is lack of the coding goal clarity on tie cases. May need
if (a[i] >= a[i-1]) down = false;
if (a[i] <= a[i-1]) up = false;
a has indices from 0 to n-1; you code references a[0] (which never gets assigned to) and a[n] (which is outside the bounds of the array).
You are checking with invalid array index. here you are declaring an array size of n but you are checking with i+1 that means n+1 for the last case. This is out of bound for your array. First of all you are storing data in array from 1 to n . But when you declare a array size n then it has index from 0 to n-1.so you can store data from 0 to n and start the check from 1 and end in n-1.
this one will work for you:
#include <stdio.h>
int
main ()
{
//Inputting the sequence
int n;
scanf ("%d", &n);
int a[n];
for (int i = 0; i < n; i++)
{
scanf ("%d", &a[i]);
}
int inc = 0;
int dec = 0;
//Checking monotonic sequence
for (int i = 1; i < n ; i++)
{
if (a[i] > a[i - 1])
{
inc = 1;
}
else if (a[i] < a[i - 1])
{
dec = 1;
}
}
if (inc == 1 && dec == 1)
{
printf ("NO");
}
else
{
printf ("YES");
}
return 0;
}

How to connect puzzles so that right edge has same length as left edge of another puzzle?

I have puzzles that looks like this:
=== ====
=== ===
=== ====
left edge has length from 0 to 10 000 and right also, middle part is from 1 to 10 000.
So the question is if i can build a rectangle? like first puzzle has length of left edge equal to 0 and the last puzzle has right edge of length 0 and in the middle they fit perfectly?
I am given the number of puzzle i have and their params like this:
6
1 9 2
0 3 1
0 4 1
8 9 0
2 9 0
1 5 0
and result can be any of that:
2
0 3 1
1 5 0
or
3
0 3 1
1 9 2
2 9 0
or
2
0 4 1
1 5 0
But if there is no result i have to printf("no result")
I have to do this in C, I thought about doing some tree and searching it with BFS where vertices would have edge lengths and edge would have middle length and when reached 0 i would go all way up and collect numbers but it's hard to code. So i decided to do recursion but im also stuck:
#include<stdio.h>
int main(){
int a;
scanf("%d", &a);//here i get how many puzzles i have
int tab[a][3];//array for puzzles
int result[][3];//result array
int k = 0;//this will help me track how many puzzles has my result array
for(int i = 0; i < a; i++){//upload puzzles to array
for(int j = 0; j < 3; j++){
scanf("%d", &tab[i][j]);
}
}
findx(0, a, tab, result, k);//start of recursion, because start has to be length 0
}
int findx(int x, int a, int *tab[], int *result[], int k){//i am looking for puzzle with length x on start
for(int i = 0; i < a; i++){
if(tab[a][0] == x){//there i look for puzzles with x length at start
if(tab[a][2] == 0){//if i find such puzzle i check if this is puzzle with edge length zero at the end
for(int m = 0; m < 3; m++){//this for loop add to my result array last puzzle
result[k][m] = tab[a][m];
}
return print_result(result, k);//we will return result go to print_result function
}
else{//if i have puzzle with x length on the left and this is not puzzle which ends rectangle i add this puzzle
//to my result array and again look for puzzle with x equal to end length of puzzle i found there
for(int m = 0; m < 3; m++){
result[k][m] = tab[a][m];
k += 1;
}
findx(tab[a][2], a, tab, result, k);
}
}
}
printf("no result");
}
int print_result(int *result[], int k){
printf("%d", &k);//how many puzzles i have
printf("\n");
for(int i = 0; i < k; i++){//printing puzzles...
for(int j = 0; j < 3; j++){
printf("%d ", &result[i][j]);
}
printf("\n");//...in separate lines
}
}
I have an error that result array can't look like this int result[][3] because of of [] but I don't know how many puzzles I'm gonna use so?... and I have implicit declaration for both of my functions. Guys please help, I dont know much about C and its super hard to solve this problem.
I'm not sure I understand the overall logic of the problem, but you definitely are in need of some variable sized containers for result AND tab. Arrays are fixed size and must be defined at compile time. The following should at least compile without warnings:
#include<stdio.h>
#include<stdlib.h>
void print_result(int (*result)[3], int k){
printf("%d", k);//how many puzzles i have
printf("\n");
for(int i = 0; i <= k; i++){//printing puzzles...
for(int j = 0; j < 3; j++){
printf("%d ", result[i][j]);
}
printf("\n");//...in separate lines
}
}
void findx(int x, int a, int (*tab)[3], int (*result)[3], int k){//i am looking for puzzle with length x on start
for(int i = 0; i < a; i++){
if(tab[i][0] == x){//there i look for puzzles with x length at start
if(tab[i][2] == 0){//if i find such puzzle i check if this is puzzle with edge length zero at the end
for(int m = 0; m < 3; m++){//this for loop add to my result array last puzzle
result[k][m] = tab[i][m];
}
print_result(result, k);//we will return result go to print_result function
return;
}
else{//if i have puzzle with x length on the left and this is not puzzle which ends rectangle i add this puzzle
//to my result array and again look for puzzle with x equal to end length of puzzle i found there
for(int m = 0; m < 3; m++){
result[k][m] = tab[i][m];
k += 1;
///** Increase size of result **/
//int (*newptr)[3] = realloc(result, (k+1) * sizeof(int[3]));
//if (newptr)
// result = newptr;
}
findx(tab[i][2], a, tab, result, k);
}
}
}
printf("no result\n");
}
int main(){
int a;
scanf("%d", &a);//here i get how many puzzles i have
int (*tab)[3] = malloc(a * sizeof(int[3]));//array for puzzles
int (*result)[3] = malloc(a * sizeof(int[3]));//array for puzzles
int k = 0;//this will help me track how many puzzles has my result array
for(int i = 0; i < a; i++){//upload puzzles to array
for(int j = 0; j < 3; j++){
scanf("%d", &tab[i][j]);
}
}
findx(0, a, tab, result, k);//start of recursion, because start has to be length 0
}
Note that I changed the tab and result types to (*int)[3]. Due to order of operations, we need parentheses here. Because they are variable size, they require dynamic memory allocations. In the interest of brevity and readability, I did not check the returned values of malloc or realloc. In practice, you should be checking that the returned pointer is not NULL. Because we are using dynamic memory allocations, we should also use free if you plan on doing anything else with this program. Otherwise, it doesn't really matter because exiting the program will free the resources anyway. You actually don't want to free. because we are passing a pointer by value to findx and the realloc can change the address, it may come back with a different address. Also, take note that I needed to include <stdlib.h> for the dynamic memory allocations.
Additional Issues
Your functions print_results and findx are not declared when you call them in main. Your function either need to be above main or have "function prototypes" above main.
In the printfs you do not need the &. You do not want to send the address of the variable to printf. You want to send what will actually be printed.
Now what?
The program still does not provide you with the correct results. It simply outputs 0 as the result every time. This should at least give you a starting point. By changing this line in print_results:
for(int i = 0; i < k; i++){//printing puzzles...
to
for(int i = 0; i <= k; i++){//printing puzzles...
I was at least able to output 0 0 0. This seems more correct because if k is 0, we don't loop at all.
#include<stdio.h>
void findx(int x, int a, int tab[a][3], int result[200000][3], int puzzlesinresult) { //i am looking for puzzle with length x on start
for (int i = 0; i < a; i++) {
if (tab[i][0] == x) { //there i look for puzzles with x length at start
if (tab[i][2] == 0) { //if i find such puzzle i check if this is puzzle with edge length zero at the end
for (int m = 0; m < 3; m++) { //this for loop add to my result array last puzzle
result[puzzlesinresult][m] = tab[i][m];
}
return print_result(result, puzzlesinresult); //we will return result go to print_result function
} else { //if i have puzzle with x length on the left and this is not puzzle which ends rectangle i add this puzzle
//to my result array and again look for puzzle with x equal to end length of puzzle i found there
while (result[puzzlesinresult - 1][2] != tab[i][0] && puzzlesinresult > 0) {
puzzlesinresult -= 1;
}
int isusedpuzzle = 0;
for (int j = 0; j < puzzlesinresult; j++) {
if (result[j][0] == tab[i][0] && result[j][1] == tab[i][1] && result[j][2] == tab[i][2]) {
isusedpuzzle = 1;
} else {
//pass
}
}
if (isusedpuzzle == 0) {
for (int m = 0; m < 3; m++) {
result[puzzlesinresult][m] = tab[i][m];
}
puzzlesinresult += 1;
findx(tab[i][2], a, tab, result, puzzlesinresult);
}
}
}
}
}
void print_result(int result[200000][3], int puzzlesinresult) {
printf("%d\n", puzzlesinresult + 1); //how many puzzles i have
for (int i = 0; i < puzzlesinresult + 1; i++) { //printing puzzles...
for (int j = 0; j < 3; j++) {
printf("%d ", result[i][j]);
}
printf("\n"); //...in separate lines
}
exit(0);
}
int main() {
int a;
scanf("%d", & a); //here i get how many puzzles i have
int tab[a][3]; //array for puzzles
int result[100][3]; //result array
int puzzlesinresult = 0; //this will help me track how many puzzles has my result array
for (int i = 0; i < a; i++) { //upload puzzles to array
for (int j = 0; j < 3; j++) {
scanf("%d", & tab[i][j]);
}
}
for (int i = 0; i < a; i++) { //here i delete puzzles that doesnt contribute anything like 1 x 1,2 x 2,..
if (tab[i][0] == tab[i][2] && tab[i][0] != 0) {
for (int p = i; p < a; p++) {
for (int j = 0; j < 3; j++) {
tab[p][j] = tab[p + 1][j];
}
}
}
}
findx(0, a, tab, result, puzzlesinresult); //start of recursion, because start has to be length 0
printf("NONE");
}
This returns sometimes correct result. If you can find when this program fails I would rly appreciate sharing those cases with me :)

Why won't for loop terminate?

My function:
int checkSE(disk board[][SIZE], disk hypotheticalDisk)
{
int i;
int j;
int row;
int col;
int player;
int opponent;
int checkSEflag;
player = hypotheticalDisk.type;
(player == 0) ? (opponent = 1) : (opponent = 0);
row = hypotheticalDisk.pos.row;
col = hypotheticalDisk.pos.col;
checkSEflag = 0;
for (i = row + 2, j = col + 2; ((i < SIZE) && (j < SIZE) && (checkSEflag == 0)); i++, j++)
{
if (board[i][j].type == player)
{
for (--i, --j; board[i][j].type == opponent; i--, j--)
{
if (i == row && j == col)
{
checkSEflag = 1;
break;
}
}
}
printf("\n%d and %d and %d", i, j, checkSEflag);
}
return checkSEflag;
}
My output:
2 and 3 and 0
2 and 3 and 0
2 and 3 and 0
2 and 3 and 0
2 and 3 and 0
.
.
.
And it keeps on going...
I want both i and j to increase until they are equal to SIZE (SIZE predefined to be 8) or until checkSEflag is assigned to be equal to 1.
It looks like the values of i and j just aren't being changed...
I tried taking them out of the loop conditions and instead placed them
in the loop body, though that didn't change anything.
I doubt the post increment operators just decided to not work so I must be doing something wrong, any ideas of what that may be?
These two lines:
for(i = row+2, j = col+2; ((i < SIZE) && (j <SIZE) && (checkSEflag == 0)); i++, j++)
...
for(--i, --j; board[i][j].type == opponent; i--, j--)
so, you are both incrementing and decrementing (i,j); try sprinkling printfs around these and see if you are both incrementing and decrementing i,j on each iteration...

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");
}
}

Triangle made with printf, consists of inner frames

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;
}

Resources