Alphabetical Pyramid

110 Views Asked by At

I'm trying to make a program that takes input number of rows from the user and prints this type of pattern for example if "number of rows: 5", then it should print this pattern OUTPUT I WANT

I wrote this C code,

#include <stdio.h>

int main() {
    int rows, i, j, k;

    // Take input for the number of rows
    printf("Enter the number of rows: ");
    scanf("%d", &rows);

    for (i = 1; i <= rows; i++) {
        k = 'A';
        for (j = 1; j <= 2 * rows - 1; j++) {
            // Adjusted condition to reduce one space in all rows
            if ((j <= rows - i || j >= rows + i) && !(i == 1 && j == rows)) {
                printf("%c", k);
                j < rows ? k++ : k--;
            } else {
                if (j != rows) {
                    printf(" ");
                }
                if (j == rows) {
                    k--;
                }
            }
        }
        printf("\n");
    }

    return 0;
}

And after execution of this above code I'm getting this type of answer UNDESIRED RESULT

2

There are 2 best solutions below

2
Chris On

Reduce complexity. Break down what your program actually has to do into smaller steps.

For an input of N, your function has to print N lines.

int main(void) {
    int n = 5;
    
    for (int i = 0; i < n; i++) {

    }
}

On the first line you need to print N letters in the sequence from A to Z and zero spaces. On the second line you need to print N - 1 letters and one space. And so on.

int main(void) {
    int n = 5;
    
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n - i; j++) {
            printf("%c", 'A'+j);
        }

        for (int j = 0; j < i; j++) {
            printf(" ");
        }

        printf("\n");
    }
}

Output so far:

ABCDE
ABCD
ABC
AB
A

Now, you just need to reverse these steps to print the end of each line.

int main(void) {
    int n = 5;

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n - i; j++) {
            printf("%c", 'A'+j);
        }

        for (int j = 0; j < i; j++) {
            printf(" ");
        }

        for (int j = 0; j < i - 1; j++) {
            printf(" ");
        }

        for (int j = n - i - 1; j >= 0; j--) {
            // Skip the first letter
            if (j == n - 1) continue;

            printf("%c", 'A'+j);
        }

        printf("\n");
    }
}

Output:

ABCDEDCBA
ABCD DCBA
ABC   CBA
AB     BA
A       A

With some math those two loops to print the spaces can now be reduced to one.

int main(void) {
    int n = 5;

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n - i; j++) {
            printf("%c", 'A'+j);
        }

        for (int j = 0; j < (i - 1) * 2 + 1; j++) {
            printf(" ");
        }

        for (int j = n - i - 1; j >= 0; j--) {
            if (j == n - 1) continue;

            printf("%c", 'A'+j);
        }

        printf("\n");
    }
}

Which could further be reduced to:

        int spaces = i == 0 ? 0 : (i - 1) * 2 + 1;
        printf("%*.*s", spaces, spaces, " ");

Alternatively, if we create strings representing the forward and backwards parts of the string, we can use printf to control printing much as we did with the spaces in the previous snippet.

int main(void) {
    int n = 5;

    char str[n+1];
    for (int i = 0; i < n; i++) str[i] = 'A' + i;
    str[n] = '\0';
    // For n=5, this is "ABCDE"

    char rev[n];
    for (int i = 0; i < n; i++) rev[i] = str[n - i - 2];
    rev[n-1] = '\0';
    // For n=5 this is "DCBA"

    for (int i = 0; i < n; i++) {
        printf(
          "%-*.*s%*.*s\n",
          n, n - i, str,
          // Conditionally specify length for first loop.
          n - 1, (i == 0 ? n - 1 : n - i), rev
        );
    }
}

Note: as both str and rev are always being printed with a width specifier, you could eliminate the null terminators on both arrays.

1
Alexander Mihail On

You could consider leaving it all to printf, and do it in one printf line:

int main(int argc, char* argv[])
{
    for (auto str : { "", "M", "ABCDEEDCBA", "ABCDEDCBA" })
        for (int L = strlen(str), i = 0; i < L / 2; i++)
            printf(
                "%-*.*s"
                "%*c\b" // backspace to erase one space because printf doesn't honour a 0 count of chars.
                "%*.*s\n",
                L / 2 - i, L / 2 - i, str,
                2 * i + L % 2 + 1, ' ', // one more space than we need is to be erased by backspace
                L / 2 - i, L / 2 - i, str + L / 2 + i + L % 2);
    return 0;
}

Yes, it does requires the more advanced feature of printf.

Regards.