1
\$\begingroup\$

Whilst scanning my C programming textbook, I saw this practice problem from a very early chapter:

I got to thinking that the problem probably wants you to draw each shape separately, which would be very easy.

But to do literally what the question asks (print them on the same line), I couldn't see any easy way! The rectangle is 9x9, but they seem 5 spaces apart, the oval is 7 wide, the arrow tip is 5x3, etc. Maybe if the arrow had tips on both ends, I could dissect the whole picture horizontally.

After dabbling with ways to produce the rectangle, oval, arrow, and diamond by themselves, and then to somehow print each row correctly with loops and ifs, I realized maybe I should just draw it literally.

#include <stdio.h>

int main() {

    puts("*********       ***         *           *");
    puts("*       *      *   *       ***         * *");
    puts("*       *     *     *     *****       *   *");
    puts("*       *     *     *       *        *     *");
    puts("*       *     *     *       *       *       *");
    puts("*       *     *     *       *        *     *");
    puts("*       *     *     *       *         *   *");
    puts("*       *      *   *        *          * *");
    puts("*********       ***         *           *");

    return 0;

}

I could have put it all in one puts with newlines but I found that was pretty unreadable.

Is there any better way to do this? Am I completely missing something / am I doing it in the most efficient way?

\$\endgroup\$
  • \$\begingroup\$ The question asks to "print the following shapes", it doesn't say anything about them having to be on the same line. \$\endgroup\$ – Mat Jan 14 '16 at 6:40
  • \$\begingroup\$ @Mat The example output has them on the same line, so if you follow the problem literally and also based on other problems in the book, you should print them on the same line. I think you're right though, they should be done separately, but as I said that'd be too easy :P \$\endgroup\$ – Insane Jan 14 '16 at 6:44
  • \$\begingroup\$ Did you consider to use a bitmap (an array of 64 bit integers where each bit is a column and each item is a row of your output? 1 for asterisk and 0 for space). Less readable to write (unless you can use 0b notation) but more compact and reusable. \$\endgroup\$ – Adriano Repetti Jan 14 '16 at 8:11
3
\$\begingroup\$

It really is that simple. Your idea of putting everything into one puts() call would be an improvement, because I/O calls are relatively expensive. Not that it really matters in this exercise. It's just a good habit.

The second shape should be a little bit wider. =)

Note that a return 0; at the end of main() is automatically implied, as a special case.

#include <stdio.h>

int main() {

    puts("*********        ***          *           *\n"
         "*       *      *     *       ***         * *\n"
         "*       *     *       *     *****       *   *\n"
         "*       *     *       *       *        *     *\n"
         "*       *     *       *       *       *       *\n"
         "*       *     *       *       *        *     *\n"
         "*       *     *       *       *         *   *\n"
         "*       *      *     *        *          * *\n"
         "*********        ***          *           *");

    return 0;

}
\$\endgroup\$
  • \$\begingroup\$ Ah, didn't know you could split it up like that. +1 \$\endgroup\$ – Insane Jan 14 '16 at 21:37
  • \$\begingroup\$ @SirPython (1) I mentioned that it's optional, but I wouldn't necessarily drop return 0 if it's already written. (2) #include <stdio.h> should be there, at least on OS X and Linux. \$\endgroup\$ – 200_success Jan 14 '16 at 23:43
2
\$\begingroup\$

You're not really asking for a code review here; you're more like asking the community how they would write the code for this problem. So, not really on-topic.

However, here's a hint (partial answer) for you.

Consider each of the four shapes in isolation. Write four functions, one per shape, each taking an int parameter that indicates which of the 9 lines (top to bottom) the function should be outputting. For example:

#include <stdio.h>

void square(int line)
{
    if (line == 0 || line == 8) {
        printf("*********\n");
    } else {
        printf("*       *\n");
    }
}

void arrow(int line)
{
    if (line == 1) {
        printf("   ***   \n");
    } else if (line == 2) {
        printf("  *****  \n");
    } else {
        printf("    *    \n");
    }
}

int main()
{
    for (int i=0; i < 9; ++i) {
        square(i);
    }
    for (int i=0; i < 9; ++i) {
        arrow(i);
    }
}

Compile and run that program. Look at its output. Then, make a relatively small modification to the program so that it outputs the square and the arrow side-by-side instead of one-above-the-other.

Then, add the circle and the diamond.

\$\endgroup\$
  • \$\begingroup\$ Yes, this is actually exactly what I was doing before! I'm happy I'm not the only one who thought to do it like that. +1 \$\endgroup\$ – Insane Jan 14 '16 at 21:37
  • \$\begingroup\$ FYI, the "small modification" I had in mind is to remove the \ns, move the call to arrow(i) into the first for loop in main(), and get rid of the second for loop. \$\endgroup\$ – Quuxplusone Jan 16 '16 at 22:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.