29
\$\begingroup\$

Special Independence Day (USA) themed challenge for you today. You must write a program that prints this ascii-art representation of The American Flag.

0
|---------------------------------------------------------
| *   *   *   *   *   * #################################|
|   *   *   *   *   *                                    |
| *   *   *   *   *   *                                  |
|   *   *   *   *   *   #################################|
| *   *   *   *   *   *                                  |
|   *   *   *   *   *                                    |
| *   *   *   *   *   * #################################|
|   *   *   *   *   *                                    |
| *   *   *   *   *   *                                  |
|########################################################|
|                                                        |
|                                                        |
|########################################################|
|                                                        |
|                                                        |
|########################################################|
|                                                        |
|                                                        |
|########################################################|
|---------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

Trailing spaces on each line, as well as one trailing newline, are allowed.

Note that this isn't quite the way the flag should look, but it's the closest I could get with ASCII.

As usual, this is so standard loopholes apply and shortest answer in bytes wins!

\$\endgroup\$
  • \$\begingroup\$ Is trailing whitespace allowed? \$\endgroup\$ – Dennis Jul 4 '15 at 17:04
  • \$\begingroup\$ @Dennis as long as it's not excessive I don't see why not. So one trailing newline is OK. \$\endgroup\$ – DJMcMayhem Jul 4 '15 at 17:23
  • 9
    \$\begingroup\$ I would make this a pop-contest and see who prints the most realistic flag. \$\endgroup\$ – Hosch250 Jul 4 '15 at 19:08
  • 7
    \$\begingroup\$ @Hosch250 That would end up closed as "art contest" \$\endgroup\$ – Sp3000 Jul 4 '15 at 19:09
  • 1
    \$\begingroup\$ @steveverrill Yes, but we could draw a flag rippling in the breeze, perhaps. \$\endgroup\$ – Hosch250 Jul 4 '15 at 23:21
21
\$\begingroup\$

CJam, 184 120 109 101 76 74 69 67 64 62 58 bytes

0'-57*"  #"56f*'|f+7*2>" *  "50*22/W<Sf+..e&~J$]N'|+a37*.+

Try it online in the CJam interpreter.

Idea

The most interesting part of the flag is the stars and stripes pattern.

If we repeat two spaces and a number sign 56 times and append a vertical bar to each, we get

                                                         |
                                                         |
#########################################################|

Repeating this pattern 7 times and discarding the first two lines, we obtain the stripes:

#########################################################|
                                                         |
                                                         |
#########################################################|
                                                         |
                                                         |
#########################################################|
                                                         |
                                                         |
#########################################################|
                                                         |
                                                         |
#########################################################|
                                                         |
                                                         |
#########################################################|
                                                         |
                                                         |
#########################################################|

Now, if we repeat the string " * " 50 times and split the result into chunks of length 22, we obtain the stars:

 *   *   *   *   *   *
   *   *   *   *   *  
 *   *   *   *   *   *
   *   *   *   *   *  
 *   *   *   *   *   *
   *   *   *   *   *  
 *   *   *   *   *   *
   *   *   *   *   *  
 *   *   *   *   *   *
   

The whitespace is a little off, but we can fix that by eliminating the last chunk and appending a space to the remaining ones.

Now, if we superimpose stripes and stars, we get

 *   *   *   *   *   * #################################|
   *   *   *   *   *                                    |
 *   *   *   *   *   *                                  |
   *   *   *   *   *   #################################|
 *   *   *   *   *   *                                  |
   *   *   *   *   *                                    |
 *   *   *   *   *   * #################################|
   *   *   *   *   *                                    |
 *   *   *   *   *   *                                  |
########################################################|
                                                        |
                                                        |
########################################################|
                                                        |
                                                        |
########################################################|
                                                        |
                                                        |
########################################################|

All that's left to do is adding two lines of 57 dashes, adding a column of 37 vertical bars and putting the cherry on top.

Code

0         e# Push a zero.
'-57*     e# Push a string of 57 dashes.
"  #"56f* e# Repeat each character in the string 56 times.
'|f+      e# Append a vertical bar to each resulting string.
7*        e# Repeat the resulting array of strings 7 times.
2>        e# Discard the first two strings.
" *  "50* e# Repeat the string 50 times.
22/       e# Split the result into chunks of length 22.
W<        e# Discard the last, partial chunk.
Sf*       e# Append a space to each chunk.
..e&      e# Twofold vectorized logical AND.
          e# Since all characters in the strings are truthy, this always selects
          e# the second character, painting the stars over the stripes.
~         e# Dump all resulting strings on the stack.
J$        e# Copy the string of dashes.

]         e# Wrap the entire stack in an array.
N'|+a37*  e# Repeat ["\n|"] 37 times.
.+        e# Perform vectorized concatenation.
\$\endgroup\$
  • 13
    \$\begingroup\$ For a very short, magic moment I was beating you \$\endgroup\$ – edc65 Jul 4 '15 at 18:35
  • 2
    \$\begingroup\$ It ain't every day you see someone write a CJam program 120 bytes too long. \$\endgroup\$ – lirtosiast Jul 4 '15 at 21:30
  • 1
    \$\begingroup\$ What I like best is how you found a way to have 6 stars on each line, then naturally get rid of the ones you didn't want. \$\endgroup\$ – Level River St Jul 4 '15 at 23:24
  • \$\begingroup\$ @steveverrill: I liked that too, but I found something shorter... \$\endgroup\$ – Dennis Jul 5 '15 at 4:44
  • \$\begingroup\$ Cool! (You did something similar with the honeycomb didn't you?) But now you need to revise the superimposed image in your explanation. \$\endgroup\$ – Level River St Jul 5 '15 at 4:50
27
\$\begingroup\$

Python 2, 113 bytes

for i in range(38):print i and"|"+["-"*57,(" *  "*7)[i%2*2:][:(i<11)*23].ljust(56,"  #"[i%3])+"|"][1<i<21]*(i<22)

String slicing and modulo checks galore.

\$\endgroup\$
  • \$\begingroup\$ +1 Very impressive, 7 bytes ahead of my ruby answer. Both you and EDC65 were ahead of Dennis at one time? wow! \$\endgroup\$ – Level River St Jul 4 '15 at 19:16
  • 11
    \$\begingroup\$ A python answer that is competing with a cjam answer. What a time to be alive! \$\endgroup\$ – DJMcMayhem Jul 4 '15 at 19:19
  • 3
    \$\begingroup\$ I like how the value i=0 is itself being printed. \$\endgroup\$ – xnor Jul 5 '15 at 8:37
8
\$\begingroup\$

Brainf**k, 3355 3113 1598 1178 782 bytes

What is this language?

Here is the hand optimized version featuring 28 loops. I think I've taken this about as far as it will go.

Here's the run at ideone.com:

+++[>++++<-]>[>+++>+++>+++>++++++++++>+>++++<<<<<<-]>++++++>---->->>>.<--.
<++++.>>---.>+++++++[<........>-]<<.
<.<<<<+++++[>>.<.>..<<-]>>.<.>.<<++++[>>>........<<<-]>>>.>.>.
<.<<<<+++++[>>...<.<-]+++++[>>.......<<-]>>.>>.>.
<.<<<<++++++[>>.<.>..<<-]++++[>>........<<-]>>>>.>.
<.<<...<<+++++[>.>...<<-]++++[>>>........<<<-]>>>.>.>.
<.<<<<++++++[>>.<.>..<<-]++++[>>........<<-]>>>>.>.
<.<<<<+++++[>>...<.<-]+++++[>>.......<<-]>>.>>.>.
<.<<<<+++++[>>.<.>..<<-]>>.<.>.<<++++[>>>........<<<-]>>>.>.>.
<.<<<<+++++[>>...<.<-]+++++[>>.......<<-]>>.>>.>.
<.<<<<++++++[>>.<.>..<<-]++++[>>........<<-]>>>>.>.
>>>+++[<<<
<.>>>+++++++[<<<<........>>>>-]<<<.>.
>>++[<<
<.<<<<+++++++[>>........<<-]>>>>.>.
>>-]<<
>>>-]<<<
<.>>>+++++++[<<<<........>>>>-]<<<.>.
<.>>.>+++++++[<........>-]<<.
>>++++++++[<<<.>.<.>.>>-]

How does this work?

 1: +++[>++++<-]>[>+++>+++>+++>++++++++++>+>++++<<<<<<-]>++++++>---->->>>.<--.
 2: <++++.>>---.>+++++++[<........>-]<<.
 3: <.<<<<+++++[>>.<.>..<<-]>>.<.>.<<++++[>>>........<<<-]>>>.>.>.
 4: <.<<<<+++++[>>...<.<-]+++++[>>.......<<-]>>.>>.>.
 5: <.<<<<++++++[>>.<.>..<<-]++++[>>........<<-]>>>>.>.
 6: <.<<...<<+++++[>.>...<<-]++++[>>>........<<<-]>>>.>.>.
 7: <.<<<<++++++[>>.<.>..<<-]++++[>>........<<-]>>>>.>.
 8: <.<<<<+++++[>>...<.<-]+++++[>>.......<<-]>>.>>.>.
 9: <.<<<<+++++[>>.<.>..<<-]>>.<.>.<<++++[>>>........<<<-]>>>.>.>.
10: <.<<<<+++++[>>...<.<-]+++++[>>.......<<-]>>.>>.>.
11: <.<<<<++++++[>>.<.>..<<-]++++[>>........<<-]>>>>.>.
12: >>>+++[<<<
13: <.>>>+++++++[<<<<........>>>>-]<<<.>.
14: >>++[<<
15: <.<<<<+++++++[>>........<<-]>>>>.>.
16: >>-]<<
17: >>>-]<<<
18: <.>>>+++++++[<<<<........>>>>-]<<<.>.
19: <.>>.>+++++++[<........>-]<<.
20: >>++++++++[<<<.>.<.>.>>-]

This program uses 10 memory locations:

0: loop counter #1
1: loop counter #2
2: "*"  ASCII 42
3: spc  ASCII 32
4: "#"  ASCII 35
5: "|"  ASCII 124
6: "\n" ASCII 10
7: "0"  ASCII 48, "-"  ASCII 45
8: loop counter #3
9: loop counter #4

Line 1

  • This line sets up the ASCII characters in registers 2 through 7 (mostly). Some tweaking is done later.
  • This code first puts 3 in register 0, and then loops 3 times incrementing register 1 four times each loop: +++[>++++<-]. Then end result is that register 0 is 0, and register 1 is 12.
  • The 12 is used as the loop counter for the next loop. For 12 times through the loop, registers 2, 3, and 4 are incremented 3 times, register 5 is incremented 10 times, register 6 is incremented 1 time, and register 7 is incremented 4 times. At the end of this loop, they contain: R2(36), R3(36), R4(36), R5(120), R6(12), R7(48). After the loop register 2 is incremented 6 times, register 3 is decremented 4 times, and register 4 is decremented once. At this point, the values are: R2(42), R3(32), R4(35), R5(120), R6(12), R7(48). All but registers 5 and 6 contain their initial ASCII values.
  • Next register 7 is output, the "0" at the top of the flag!
  • Next register 6 is decremented twice to 10 (ASCII newline) and output. Done with the first line of the flag!

Line 2

  • First it increments register 5 by 4 which makes it "|" (ASCII 124) and outputs it.
  • Then it decrements register 7 by three changing it from "0" (ASCII 48) into "-" (ASCII 45) and outputs it.
  • Next it puts 7 into loop counter 3 (register 8) and loops 7 times, writing out 8 dashes each time for a total of 7*8 = 56 dashes.
  • Finally it ends by outputting a newline.

Line 3

  • This line contains two loops.
  • The first loop writes " * " 5 times.
  • Then " * " is written
  • The second loop loops 4 times writing 8 "#" for a total of 32.
  • Then "#", "|", and "\n" are written.

Lines 4 - 11

  • These lines use the same technique as line 3 to write out the stars and stripes of the flag.

Line 12

  • This line starts a loop that runs 3 times.
  • The loop ends at line 17.

Line 13

  • Writes a strip that goes across the flag.
  • Uses a loop that runs 7 times writing "#" 8 times each time through the loop.

Line 14

  • The start of a loop that runs 2 times.

Line 15

  • Writes a strip that goes across the flag.
  • Uses a loop that runs 7 times writing " " 8 times each time through the loop.

Line 16

  • End of inner loop that started at line 14.

Line 17

  • End of outer loop that started at line 13.

Line 18

  • Draws bottom stripe of flag.

Line 19

  • Draws bottom border of flag.

Line 20

  • Draws the flagpole.
  • Loops 8 times, writing "|" and newline twice each time through the loop.
\$\endgroup\$
  • 2
    \$\begingroup\$ You actually managed to compress the flag! I hope you'll post an explanation when you're done golfing. I'd very much like to know how this works. \$\endgroup\$ – Dennis Jul 8 '15 at 23:52
  • \$\begingroup\$ I will post an explanation. I'm still golfing! \$\endgroup\$ – vacawama Jul 8 '15 at 23:53
7
\$\begingroup\$

///: 225 characters

/D/ddd//d/--------//H/hhh//h/########//S/sss//s/        //A/aaaaa//a/ *  //b/|HHh|
|SSs|
|SSs|
//p/|
|
|
|
/0
|DDd-
|A * Hh#|
|  A Ss |
|A * Ss |
|  A Hh#|
|A * Ss |
|  A Ss |
|A * Hh#|
|  A Ss |
|A * Ss |
bbb|HHh|
|DDd-
pppp
\$\endgroup\$
7
\$\begingroup\$

JavaScript (ES6), 153 156

Using template string, there is 1 newline that is significant and counted

Test running the snippet below (being EcmaScript 6, Firefox only)

// TEST - Just for testing purpose,redefine console.log

console.log = (...x) => O.innerHTML += x+'\n'

// SOLUTION

o=[0];for(o[r=1]=o[21]='-'[R='repeat'](57);++r<21;o[r]=" *  "[R](7).substr(r%2*2,r<11&&23)+'  #'[r%3][R](r<11?33:56)+'|')o[37]='';console.log(o.join`
|`)
<pre id=O></pre>

To be even more patriotic, here is the EcmaScript 5 version

// TEST - Just for testing purpose,redfine console.log

console.log = function(x){ O.innerHTML += x+'\n' }

// SOLUTION - 175 bytes

for(o=(A=Array)(38),o[0]=0,r=2;r<21;r++)o[r]=A(8)[J='join'](" *  ").substr((r&1)*2,r<11?23:0)+A(r<11?34:57)[J]('  #'[r%3])+'|';
o[1]=o[r]=A(58)[J]('-'),console.log(o[J]('\n|'))
<pre id=O></pre>

\$\endgroup\$
  • 4
    \$\begingroup\$ +1 for calling ES5 more patriotic \$\endgroup\$ – Pete TNT Jul 6 '15 at 6:55
6
\$\begingroup\$

Ruby, 104 102 bytes

Using ideas from ManAtWork's Ruby answer with permission.

puts 0,s=?|+?-*57,(0..18).map{|i|?|+("#  "[i%3]*(i>8?56:33)).rjust(56," *   *"[i%2*2,4])+?|},s,'|
'*16

Ruby, 127 121 112 bytes

Changed quotes to ? used array instead of conditional for stripe colour. used conditional instead of formula for stripe length.

puts 0,s=?|+?-*57
19.times{|i|puts ?|+("#  "[i%3]*(i>8?56:33)).rjust(56,i%2>0?"   *":" *  ")+?|}
puts s,"|\n"*16

The trick here is to draw the stripes (both red/# and white/space) to the correct length, then right justify them, padding with stars. Ruby's rjust allows us to specify the padding string, which alternates between " * " and " *".

Original version, 127 bytes

puts 0,s="|"+"-"*57
19.times{|i|puts("|"+((i%3>0?" ":"#")*((i+1)/10*23+33)).rjust(56,i%2>0?"   *":" *  ")+"|")}
puts s,"|\n"*16
\$\endgroup\$
  • \$\begingroup\$ Oops, I forgot to reload the page before checking whether a Ruby answer already exists. As my answer is not significantly different, I deleted it. Feel free to use any good part you may find in it. \$\endgroup\$ – manatwork Jul 4 '15 at 19:39
  • \$\begingroup\$ @manatwork I don't see that you needed to delete it, it was shorter than mine and I'd already upvoted it. There were some Ruby tricks in there I didn't know, I'm new to ruby. I'm down to 104 using the best of both answers, which is the shortest answer in a conventional language. I don't understand why I can use the map in the middle of the puts but I can't use it on its own, even if i surround it with brackets: puts((0.18).map{}). If you see any further improvements either let me know, or undelete your own answer and post it there. \$\endgroup\$ – Level River St Jul 4 '15 at 20:13
  • \$\begingroup\$ I'm impressed that Ruby rjust can take a string and not just a char. Too bad Python can't do that... \$\endgroup\$ – Sp3000 Jul 5 '15 at 7:22
3
\$\begingroup\$

SWI-Prolog, 275 bytes

In a language of French origin, which is kind of fitting

a:-put(48),nl,b,c(0).
b:-z,w(-,57).
c(I):-nl,I=36;J is I+1,(I=19,b,c(J);I>19,z,c(J);I>8,z,(I mod 3=:=0,w(#,56);tab(56)),z,c(J);z,(I mod 2=:=0,tab(1),w('*   ',5),put(42),tab(1);w('   *',5),tab(3)),(0=:=I mod 3,w(#,33);tab(33)),z,c(J)).
z:-put(124).
w(A,B):-writef('%r',[A,B]).

See the result here

\$\endgroup\$
  • \$\begingroup\$ I hate to break an existing answer, but the first version had 11 stripes instead of 13. I didn't change anything else. You can check the edit history to see what I changed. Sorry about that. \$\endgroup\$ – DJMcMayhem Jul 4 '15 at 17:59
  • \$\begingroup\$ @DJMcMayhem Fixed, only needed to change two numbers and didnt change the length of the answer, so it's all good \$\endgroup\$ – Fatalize Jul 4 '15 at 18:02
1
\$\begingroup\$

C, 235 211 208 205 203 198 197 186 bytes

i;x(){for(puts("0");i<37;i++){char b[58]="";i<21?memset(b,i%20?i%3&1?35:32:45,56),i&&i<10?memcpy(b," *   *   *   *   *   *   "+(i%2?0:2),23):0,b[56]=i%20?124:45:0;printf("|%.57s\n",b);}}

edit: added some of Cool Guy's suggestions and made use of ?: to replace some if statements.

edit: removed overflow \0 prevention and used string length limiter in printf instead.

edit: reworked both memset conditionals.

edit: moved puts("0") inside the for header to remove its semicolon.

edit: slight refactoring to get 11 more bytes.

\$\endgroup\$
  • \$\begingroup\$ Good first attempt. But this does not seem to print the | at the start of every line... \$\endgroup\$ – Spikatrix Jul 6 '15 at 7:39
  • \$\begingroup\$ Your code in 198 bytes:i;c(){puts("0");for(;i<37;i++){char b[58]="|";if(i<21){memset(b,!((i-1)%3)?35:32,56);if(i<10)memcpy(b," * * * * * * "+((i%2)?0:2),23);b[56]='|';}if(!i||i==20){memset(b,45,57);}puts(b);}} \$\endgroup\$ – Spikatrix Jul 6 '15 at 8:03
  • \$\begingroup\$ @Cool Guy: Thanks for the catch. I forgot to move the '|' back to the second printf from the initializer. I tried running your code using GCC under Cygwin, but the formatting is off. Is there anything special I need to do to run it or any flags needed at compile time? \$\endgroup\$ – openaddr Jul 6 '15 at 8:17
  • \$\begingroup\$ No special flags required. Test it here Golf it more by using 45 instead of '-' and 35 instead of '#' and 32 instead of ' ' \$\endgroup\$ – Spikatrix Jul 6 '15 at 8:23
  • \$\begingroup\$ @Cool Guy: Good suggestion on the character encoding values. And good catch on the i==0 I overlooked. I think your initial code wasn't working because of the second puts(), but that was partially my fault because by forgetting to change the "|"'s position back, it made it seem like the buffer contained the entire string. The code in the link you provided using the printf at the end does work now. \$\endgroup\$ – openaddr Jul 6 '15 at 9:04

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.