8
\$\begingroup\$

Preface

There are many "draw x flag" challenges, and upon searching it turns out there are no challenges to draw the union Jack! I feel like this would be a harder flag to draw but it should still be possible.

Challenge

Draw the Union Jack. It can be outputted to a file in any freely available graphics file format or drawn onto the screen.

Dimensions shall be as below. Minimum size 600x300 pixels (or units if your language supports only scalable graphics.) Maximum error 1 pixel.

Colours shall be red, white and blue as defined by your language or its documentation, or #CC0000, #FFFFFF and #003399 per Wikipedia page.

enter image description here

\$\endgroup\$
  • \$\begingroup\$ Related, ASCII version \$\endgroup\$ – Fatalize Aug 25 '16 at 11:46
  • 11
    \$\begingroup\$ "There are many "draw x flag" challenges, and upon searching it turns out there are no challenges to draw the" could be followed by any of thousands of national, organisational, state, etc. flags. What does this flag have which makes drawing it a fundamentally different challenge from all of the existing graphical-output questions? \$\endgroup\$ – Peter Taylor Aug 25 '16 at 11:59
  • 1
    \$\begingroup\$ This is a lot like the Iceland flag challenge, however I find this one has a particular twist in the construction of the diagonal stripes. Since they have rotational symmetry but not exact reflective symmetry, it adds an extra layer to the complexity. Most of the strategies for the Iceland flag would not be a simple conversion to get this one. \$\endgroup\$ – GuitarPicker Aug 30 '16 at 2:24
  • \$\begingroup\$ Not harder than the Portuguese flag! \$\endgroup\$ – sergiol Aug 26 '17 at 12:49
8
\$\begingroup\$

BBC BASIC

Rev B, 234 bytes

Instead of drawing one white and one red cross, we draw 100 progressively narrower crosses, switching from white background to red foreground at a coordinate of 60.

p=20761m=1049w=600h=300F.i=-1TO1V.29,w;h;18;4,m;134*i;0;m;w*i;-233;p;0;466;m;0;67*i;m;-466;h*i;p;932;0;18;1,m;511*i;h*i;25;89*i;0;29977;0;0;m;w*i;-h*i;28953;0;45*i;
N.F.c=-100TO0q=25881-c DIV60*512V.m;-c;-h;q;c;h;m;-w;-c;q;w;c;
N.

Download interpreter free at http://www.bbcbasic.co.uk/bbcwin/bbcwin.html

Fully golfed, 249 bytes

Single byte VDU codes e.g 25,0 combined into double-byte little endian e.g 25; and maximum use of constants for common values. Keywords compressed to abbreviated form, e.g. FOR=>F. (interpreter expands automatically.)

p=20761q=26393r=25881m=1049c=100w=600h=300F.i=-1TO1V.29,w;h;18;4,m;134*i;0;m;w*i;-233;p;0;466;m;0;67*i;m;-466;h*i;p;932;0;18;1,m;511*i;h*i;25;89*i;0;29977;0;0;m;w*i;-h*i;28953;0;45*i;
N.V.m;-c;-h;q;c;h;2m;-w;-c;q;w;c;m;-60;-h;r;60;h;m;-w;-60;r;w;60;

Semigolfed

Raw VDU codes. In BBC BASIC, characters can be sent to the VDU controller like VDU65 (prints an A.) There are certain special characters particular to the BBC for graphics. These must be followed by several other bytes to specify coordinates, etc. Here we use PLOT=>VDU25, GCOL=>VDU18, ORIGIN=>VDU29.

  c=100w=600h=300                                      :REM constants 100,width,height
  FORi=-1TO1                                           :REM loop -1 and 1 (0 draws nothing)
    VDU29,w;h;                                         :REM set origin (bring inside loop for golfing reasons)
    VDU18;4                                            :REM change to blue and draw triangles
    VDU25,4,134*i;0;25,4,w*i;-233;25,81,0;466;25,4,0;67*i;25,4,-466;h*i;25,81,932;0;
    VDU18;1                                            :REM change to red and draw parallelograms
    VDU25,4,511*i;h*i;25,0,89*i;0;25,117,0;0;25,4,w*i;-h*i;25,113,0;45*i;
  NEXT
  VDU25,4,-c;-h;25,103,c;h;25,4,-w;-c;25,103,w;c;      :REM draw white background rectangles
  VDU25,4,-60;-h;25,101,60;h;25,4,-w;-60;25,101,w;60;  :REM draw red foreground rectangles

First we draw half the diagonal parts: 2 blue triangles and 2 red parallelograms. Then we change the scale from -1 to +1 and draw the other half. Finally we draw the horizontal and vertical parts on top: 2 white rectangles to form a white cross, then 2 red rectangles. The image after the first iteration of the loop is shown below, along with the final image.

enter image description here

Ungolfed code

BBC basic remembers the last 2 locations of the graphics cursor. PLOT81 draws a triangle between the new coordinates specified and these last two locations. PLOT113 and PLOT117 draw a parallelogram in a similar way: three corners of the parallelogram have to be given in the order they are found going round the perimeter. The last three bits of the PLOT code define whether the given coordinates are absolute or relative, and whether foreground or background colour is used. The more significant bits define what type of shape is drawn (point, line, triangle, parallelogram, rectangle, etc.)

  ORIGIN600,300       :REM move the origin (which will be centre of flag) away from the corner of the screen.

  FORi=-1TO1          :REM at scales of -1 and 1, plot half each of the diagonal parts (i=0 plots nothing).
    GCOL0,4             :REM blue foreground colour
    PLOT4,134*i,0       :REM absolute move to peak of upper/lower triangle
    PLOT4,600*i,-233    :REM absolute move to left hand corner
    PLOT81,0,466        :REM relative move to right hand corner, plotting triangle

    PLOT4,0,67*i        :REM absolute move to peak of left/right triangle
    PLOT4,-466,300*i    :REM absolute move to lower corner
    PLOT81,932,0        :REM relative move to upper corner, plotting triangle

    GCOL0,1             :REM red foreground colour
    PLOT4,511*i,300*i   :REM absolute move to long edge of flag
    PLOT0,89*i,0        :REM relative move to corner of flag (top right / bottom left)
    PLOT117,0,0         :REM absolute move to centre of flag, plotting parallelogram (stripe)
    PLOT4,600*i,-300*i  :REM absolute move to corner of flag (bottom right / top left)
    PLOT113,0,45*i      :REM relative move to short edge of flag, plotting parallelogram (stripe)
  NEXT                :REM diagonal parts completed, now plot vertical/horizontal parts on top.

  PLOT4,-100,-300     :REM move to bottom left of vertical white stripe
  PLOT103,100,300     :REM move to top right corner, plot it in background colour (white)
  PLOT4,-600,-100     :REM move to bottom left corner of horizontal white stripe
  PLOT103,600,100     :REM move to top right corner, plot it in background colour (white)

  PLOT4,-60,-300      :REM move to bottom left of vertical red stripe
  PLOT101,60,300      :REM move to top right corner, plot it in foreground colour (red)
  PLOT4,-600,-60      :REM move to bottom left corner of horizontal red stripe
  PLOT101,600,60      :REM move to top right corner, plot it in foreground colour (red)
\$\endgroup\$
  • 6
    \$\begingroup\$ The right language (name) for the task :-D \$\endgroup\$ – Luis Mendo Aug 28 '16 at 3:14
3
\$\begingroup\$

SVG, 298 bytes

score excludes 3 unnecessary newlines added for clarity.

<svg xmlns="http://www.w3.org/2000/svg">
<path d="M67,0h466L0,267v-234L533,300h-466L600,33v232z" fill="blue"/>
<path d="M0,0v22L300,172L45,300h-45L600,0h-45L300,128L600,278v22z" fill="red"/>
<path d="M-10,110h270v-120h80v120h270v80h-270v120h-80v-120h-270z" fill="red" stroke="#fff" stroke-width="20"/>

Inspired by Siren's deleted answer (and in particular the saving in bytes from omitting </svg> at the end of the document), I came up with an SVG that is both dimensionally correct and slightly shorter.

It consists of a blue path and a red path (filled, without strokes) for the diagonal parts and a red path (filled, with 20 unit white border) for the final cross. Because of the thickness of the white border, the specified dimensions of the cross must exceed the required dimensions by 10 all around.

This works fine for me in Microsoft IE and Edge. Sometimes displays an "extra content at the end of the document" warning in Chrome.

Here's how it appears without and with the final cross. 8 points are required to describe the blue path, 10 points to describe the red path, and 12 points for the final cross. The intersections of straight lines within the first two paths do not have to be given.

enter image description here

\$\endgroup\$
  • \$\begingroup\$ SVG is an image format, not a programming language \$\endgroup\$ – Mego Aug 31 '16 at 3:08
  • 2
    \$\begingroup\$ @Mego there are quite a few SVG submissions on this site. It's actually more challenging to do it without the benefit of loops. Perhaps I should apply the following argument as used by the great Peter Taylor here: codegolf.stackexchange.com/questions/19050/… though I was reluctant to do so as I don't know PHP: PS If anyone wants to argue that SVG isn't a programming language (and I'd be very inclined to agree), consider this a PHP program in the style of many PHP submissions to this site which just echo literal text. \$\endgroup\$ – Level River St Aug 31 '16 at 18:43
1
\$\begingroup\$

Logo, 260 239 bytes

(XLogo Interpreter)

I used the Java-based XLogo interpreter since it was one of the few Logo implementations I could find which supports setting the output window size.

The XLogo editor normally saves files as procedures which are meant to be called. This program is written to be pasted into the immediate window instead. This saves about 9 bytes.

window setscreensize[600 300]setsc 4 lt atan 2 repeat 2[repeat 2[setpc 7 setpw 60 fd 400 setpw 20 lt 90 fd 10 lt 90 setpc 1 fd 400 lt 90 fd 10 rt 90]lt asin .8]home wrap setpw 100 setpc 7 repeat 2[repeat 2[fd 600 lt 90]setpw 60 setpc 1] ht

Since exact colors weren't required, I regolfed this to use built-in color numbers which saved several bytes. If you want to see a version with exact RGB colors, check the revisions. I also substituted a trigonometric calculation with a shorter equivalent.

Union Jack flag output

Ungolfed with commentary

The only real trickery here is changing colors for the second pass of a loop, and taking advantage of the wrap feature which allows us to draw the horizontal stripes with very little effort. Since the flag height and width are both factors of 600, we can go forward 600 for either vertical or horizontal stripes and end up back at the center again. This avoids having separate cases for each, even if it does draw the vertical bar twice as often. We're saving code space, not clock-cycles.

to UnionJack
  #Initialize the screen
  window  #Allow the turtle to overshoot the boundary without reappearing on the opposite side
  setscreensize[600 300]
  setsc 4  #blue background

  lt atan 2 #Turn left, preparing to draw first diagonal
  repeat 2 [ #Draw 2 sets of main diagonal bars
    repeat 2 [ #Each main bar is made of 2 spokes
      setpc 7 setpw 60 #Use a wide white pen
      fd 400 #Draw past the corner of the window
      setpw 20 #Make the pen narrow
      lt 90 fd 10 lt 90 #Do a 10px U-turn
      setpc 1 #Switch to a red pen
      fd 400 #Draw back to the center.
      lt 90 fd 10 rt 90 #Do a 10 px S curve back to center, ready to draw the opposite spoke
    ] #Finish spoke
    lt asin .8 #Turn for the next bar.
  ] #Finish bar
  home #Return to a sane heading
  wrap #Makes the turtle wrap to the opposite side if it overshoots the boundary
  setpw 100 setpc 7 #Wide white pen
  repeat 2 [ #Draw 2 crosses
    repeat 2 [ #Each cross has 2 stripes
      fd 600 #Overshoot the boundary so that we end up where we started at the center, leaving a stripe behind
      lt 90 #Rotate to draw the next stripe
    ] #Finish the stripe
    setpw 60 setpc 1 #Change to a narrow red pen
  ] #Finish cross
  ht #Hide the turtle
end
\$\endgroup\$
1
\$\begingroup\$

Processing, 312 bytes

This is the type of puzzle where Processing is pretty efficient.

int a=300,b=2*a,c=255,d=100;size(b,a);background(0,51,153);stroke(c);strokeWeight(60);line(0,a,b,0);line(0,0,b,a);stroke(c,0,0);strokeWeight(20);line(0,310,a,160);line(-22,0,a,160);line(a,139,b,-12);line(a,139,624,a);noStroke();fill(c);rect(250,0,d,b);rect(0,d,b,d);fill(c,0,0);rect(270,0,60,b);rect(0,120,b,60);

Results in:

enter image description here

\$\endgroup\$
0
\$\begingroup\$

Python 2, 265 bytes

r="D\0\0"
b="\0\x173"
w="U"*3
N=20*(270*w+60*r+270*w)
L=190*[b]+60*[w]+40*[r]+20*[w]+190*[b]
j=''.join
F=lambda p:j([j(L[150-p*100+i:150+p*150+i:p])+20*w+60*r+20*w+j(L[345-p*145-i:345+p*105-i:p])for i in range(0,200,2)])
print"P6 600 300 85 "+F(-1)+N+36000*r+N+F(1)

Output as binary PPM, usage:

python golf_unionjack.py > unionjack.ppm

L represents a vertical slice of the diagonal parts and F uses the (sort of) symmetry to save code and calculate the indices for upper and lower part.

\$\endgroup\$
0
\$\begingroup\$

Postscript (166 bytes)

00000000: 880a 880a 928b 3020 3092 6b30 881e 9263  ......0 0.k0...c
00000010: 883c 3330 9263 883c 3092 6392 1692 142f  .<30.c.<0.c..../
00000020: 727b 2e38 8800 3092 9d7d 9233 2f77 7b31  r{.8..0..}.3/w{1
00000030: 8801 3192 9d7d 9233 924e 3220 3192 8b30  ..1..}.3.N2 1..0
00000040: 202e 3220 2e36 929d 3020 3088 1e33 3092   .2 .6..0 0..30.
00000050: 8088 0f31 3592 ad34 3592 8834 7b77 2030  ...15..45..4{w 0
00000060: 88fd 881e 3692 8072 8800 3088 1e32 9280  ....6..r..0..2..
00000070: 3930 9288 7d92 8392 4d88 1e31 3592 ad32  90..}...M..15..2
00000080: 7b77 88fb 88e2 880a 3630 9280 3930 9288  {w......60..90..
00000090: 7d92 8332 7b72 88fd 88e2 3688 3c92 8039  }..2{r....6.<..9
000000a0: 3092 887d 9283                           0..}..

Non-tokenized version:

10 10 scale
0 0 moveto
0 30 lineto
60 30 lineto
60 0 lineto
closepath
clip
/r {.8 0 0 setrgbcolor} def
/w {1 1 1 setrgbcolor} def
gsave
2 1 scale
0 .2 .6 setrgbcolor
0 0 30 30 rectfill
15 15 translate
45 rotate
4 {w 0 -3 30 6 rectfill r 0 0 30 2 rectfill 90 rotate} repeat
grestore
30 15 translate
2 {
w
-5 -30 10 60 rectfill
90 rotate
} repeat
2 {
r
-3 -30 6 60 rectfill
90 rotate
} repeat

Output:

enter image description here

\$\endgroup\$

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.