You may have heard of the "Hacker Logo", also called the "Hacker Emblem". It looks like this:

hacker logo

This is a pattern from a mathematical simulation called the Game of Life. The glider is the simplest Life pattern that moves, and the most instantly recognizable of all Life patterns.

The challenge

The challenge is pretty simple: Display the hacker logo. This is defined as:

  • A 3x3 grid with a border, a white background and gray gridlines.
  • Five black dots arranged in the GoL glider pattern.
  • Nothing else.

The rules

  • The black dots must fill 40%-80% of their individual grid-boxes.
  • You will display the emblem with graphical output but no ASCII art.
  • The output must be at least 30x30 pixels.
  • The output must only have the colors gray, black and white.
  • Each grid-box in the grid will be the same size. The grid will be a regular 3x3 square.
  • You may not pull the logo from the internet or your filesystem.
  • Your program will display the logo on an empty screen/window. If it terminates it must do so normally.
  • Note that "dots" does not necessarily mean "circles". A "dot" is a single geometric shape centered in the middle of the grid-box with one surface. For example, while a circle or square will qualify as a dot, two triangles or a checkerboard will not.

The winner

As this is , the shortest answer in each language wins!

Please include a screenshot of the output of your program in your answer.

  • 23
    \$\begingroup\$ I had no idea this was called the Hacker Logo. I have used it as my avatar on some sites, guess that makes me a Hacker. \$\endgroup\$ May 31, 2017 at 19:18
  • 16
    \$\begingroup\$ @MarkThomas that or a GoL nerd xD \$\endgroup\$
    – Stephen
    May 31, 2017 at 19:21
  • 3
    \$\begingroup\$ @DavidConrad "clear the screen" means if you're using an IDE/interface that has builtin graphics you can't display it with existing text on the screen. Yes, you can display it in a window. \$\endgroup\$
    – MD XF
    Jun 1, 2017 at 2:40
  • 3
    \$\begingroup\$ Is multiple shades of gray (and related off colors) due to anti-aliasing allowed? \$\endgroup\$
    – Ian Miller
    Jun 1, 2017 at 8:01
  • 3
    \$\begingroup\$ Do we have to display the output or can we return it or save to a file? \$\endgroup\$ Jun 1, 2017 at 9:02

54 Answers 54


CSS+HTML, 56+84=140 bytes 52+84=136 bytes

Saved 4 bytes by incorporating suggestions from the comments.

td{border:1px solid#888;line-height:.4;font-size:3em
<table cellspacing=0><tr><td><td>•<td><tr><td><td><td>•<tr><td>•<td>•<td>•

This uses the UTF-8 character which is 2 bytes long and takes advantage of the graciousness of HTML syntax.

  • 3
    \$\begingroup\$ Not bad; that's pretty clever using ! \$\endgroup\$
    – MD XF
    May 31, 2017 at 21:20
  • 3
    \$\begingroup\$ Very cool. I think you could save a byte with line-height:.4;, and another by omitting the closing } \$\endgroup\$ May 31, 2017 at 21:51
  • 5
    \$\begingroup\$ Doesn't using • count as ASCII art, which is against the challenge rules? \$\endgroup\$ Jun 1, 2017 at 8:55
  • 3
    \$\begingroup\$ @StephenS Sounds like a really futile distinction, plus I don't see the sense in banning ASCII art but allowing unicode art. As for the OP saying it was clever, my comment was in fact directed to the OP, I forgot to put in the @. \$\endgroup\$ Jun 1, 2017 at 13:43
  • 4
    \$\begingroup\$ The only Code Golf answer I ever understood, at least I do believe so. \$\endgroup\$
    – Uwe Keim
    Jun 2, 2017 at 7:22

Mathematica, 62 bytes


enter image description here

Mathematica, 71 bytes


enter image description here

  • 2
    \$\begingroup\$ I think you can save bytes by using a pure function with Graphics@Disk[] as an argument. \$\endgroup\$ May 31, 2017 at 19:58
  • \$\begingroup\$ If you mean this Grid[{{,#,},{,,#},{#,#,#}},Frame->All,FrameStyle->Gray]&@Graphics@Disk[] it is 72 bytes \$\endgroup\$
    – ZaMoC
    Jun 1, 2017 at 1:02
  • 3
    \$\begingroup\$ A 69 byte variant on this: Rasterize@Grid[{{,●,},{,,●},{●,●,●}},Frame->All,FrameStyle->Gray]. The ● is a two byte unicode character. As it doesn't have to strictly be a circle perhaps some ASCII character could work to meet the 40%-80% requirement. \$\endgroup\$
    – Ian Miller
    Jun 1, 2017 at 7:57
  • \$\begingroup\$ actually I made it to 62 bytes meeting all requirements \$\endgroup\$
    – ZaMoC
    Jun 2, 2017 at 15:31
  • \$\begingroup\$ I think you need Rasterize or similar to meet the requirement of graphical output but no ASCII art as the symbols are still selectable in the grid as Unicode characters. \$\endgroup\$
    – Ian Miller
    Jun 4, 2017 at 10:10

GLSL (fragment shader), 278 235 256 bytes

precision highp float;void main(){vec2 a=gl_FragCoord.xy/20.-.2;ivec2 b=ivec2(a);a-=vec2(b)+.5;if(b.x>2||b.y>2)discard;gl_FragColor=a.x<-.5||a.y<-.5||a.x>.3||a.y>.3?vec4(.5,.5,.5,1.):length(a+.1)<.4&&(b.x+b.y-3)*b.y==0?vec4(0.,0.,0.,1.):vec4(1.,1.,1.,1.);}

enter image description here

See it in action: http://glslsandbox.com/e#40717.2

  • 1
    \$\begingroup\$ Hmm... does the border go all the way around the graphic? Also, are you sure the circles are only 80% of the grid-boxes? \$\endgroup\$
    – MD XF
    Jun 1, 2017 at 21:00
  • 14
    \$\begingroup\$ A circle that touches all four sides of its enclosing square fills a proportion π/4 of the square, or about 78.5%. \$\endgroup\$ Jun 1, 2017 at 22:25
  • 2
    \$\begingroup\$ I reduced your code's size to 222 bytes: precision highp float;void main(){vec2 a=gl_FragCoord.xy/20.-.2;ivec2 b=ivec2(a);a-=vec2(b)+.5;gl_FragColor=vec4(vec3(a.x<-.5||a.y<-.5||a.x>.3||a.y>.3?.5:length(a+.1)<.4&&(b.x+b.y-3)*b.y==0?.0:1.)*float(b.x<3&&b.y<3),1.);} \$\endgroup\$ Nov 2, 2017 at 3:57

Python 2,  169 140  137 bytes

from turtle import*
while i:i-=1;goto(20-i/3*20,i%3*20-20);stamp();209&2**i or dot(15,0,0,0)

Actual size, 61 by 61, plotted within a much larger canvas of 300 by 400:

actual size

Showing the pixel grid:

pixel grid version

The dots use 177 pixels within the range of 40%-80% whether considering the 19 by 19 white fill (144.4-288.8) or the 21 by 21 including both borders (176.4-352.8).

Note: the program terminates and closes the canvas window as soon as the drawing has been finished, to allow manual window closure append the line done().

turtle is a Python package developed for introductory graphical programming. A pen starts at x,y=0,0 in the middle of a 300 by 400 pixel canvas (by default), up lifts the pen, goto moves the pen, shape sets the shape of the pen to a named shape ("square" is a predefined shape with a default pixel-width of 21), color sets the colour, where two parameters set stroke (with default a width of 1) and fill; a byte is saved by using the (r,g,b) tuple option to replace "white" with [1,1,1] using the list multiplication [1]*3. Finally dot draws a dot with the given width in pixels and colour. The dot's default width value is too small to qualify, as is 9 so I made it an aesthetic and qualifying 15. The dot's colour could be "black" but the unpacked (r,g,b) tuple of 0,0,0 is shorter by two bytes.

The pen must move away from any dot at the end since otherwise the gray/white pen hides the dot.

The grid is traversed using a div (/) and mod (%) of i starting at 8 (i is initialised to 9 but is decremented at the beginning of the while loop) and working down to 0, offsetting the results of 2,1,0 to -1,0,1 using (1-...) and scaling each up to the grid size using a factor of 20 (note that 20-i/3*20 is actually a byte less than 20*(1-i/3), same goes for %). This produces the order [bottom-left, centre-left, top-left, bottom-middle, centre-middle, top-middle, bottom-right, centre-right, top-right], and requires a "hasDot" evaluation of [1,0,0,1,0,1,1,1,0], which is 302 in binary so may be accessed by inspecting the ith power of two component of 302 with using a bitwise-and, 302&2**i. This can then be inverted to 209&2**1 enabling the use of or rather than and.

  • \$\begingroup\$ Very good approach and much shorter than I thought would be possible using turtle. \$\endgroup\$
    – Mast
    Jun 3, 2017 at 11:11

HTML & CSS, 155 bytes

Turns out HTML is really forgiving about syntax errors.

1 byte saved thanks to @Octopus · 1 byte saved thanks to @Downgoat · 2 bytes saved thanks to @StephenS

2 bytes saved thanks to @Ryan · 3 bytes saved thanks to @styfle · 4 bytes saved thanks to @Ferrybig

13 bytes saved thanks to @SteveBennett

<table cellspacing=0 border=1><td><td><p><td><tr><td><td><td><p><tr><td><p><td><p><td><p

  • \$\begingroup\$ You can save quite a few bytes by removing the td CSS definition, and changing the <table> to <table cellspacing=0 border=1 .... The output is slightly different, but it looks close enough to my eyes. shrug \$\endgroup\$ Jun 1, 2017 at 23:19
  • \$\begingroup\$ Weirdly, I can replace most of the <div> to <p> and it works, but if I replace all of them, it doesn't. Particularly the one in the top row - if I change it, they all disappear. Chrome 58.0.3029.110 (64-bit), OSX. \$\endgroup\$ Jun 1, 2017 at 23:27
  • \$\begingroup\$ It actually looks like a bug in Chrome. In the inspector, if I disable one of the style properties, and re-enable, the table gets redrawn correctly. \$\endgroup\$ Jun 1, 2017 at 23:29
  • \$\begingroup\$ @SteveBennett thanks! about the p thing, I've tried it before, doesn't work on my chrome 59.. (circles get ellipse shape) \$\endgroup\$
    – Uriel
    Jun 1, 2017 at 23:33
  • \$\begingroup\$ border=1 will be correct and save two bytes over border=1px. \$\endgroup\$
    – Ry-
    Jun 2, 2017 at 5:01

Applesoft BASIC, 479 476 516 515 483 482 bytes

-32 by using unreadable variable names :P
-1 because Apple decided to be magical and let me use an implicit/nonexistent GOTO

Here is my own (very beatable) program for an example of an output that does not use circles:



  • 1
    \$\begingroup\$ I am not sure if this is valid, since line 1, being longer than 239 characters, is impossible to enter by normal methods, at least on a //e. \$\endgroup\$ Jun 2, 2017 at 6:29
  • 1
    \$\begingroup\$ @insert_name_here You have to save it to a file on a disk. \$\endgroup\$
    – MD XF
    Jun 2, 2017 at 14:20

IA-32 machine code, 81 80 bytes


60 8b f9 b8 50 35 20 20 ab b8 32 35 36 20 ab ab
ab fe 4f fe 33 c9 66 49 51 8a c1 d4 55 50 8a c5
d4 55 5b b2 80 84 c0 74 1f 84 db 74 1b b2 ff 2c
10 3c 35 77 13 93 2c 10 3c 35 77 0c 8d 0c 58 8a
cd b0 e4 d2 e0 79 01 42 92 aa 59 e2 cb aa 61 c3

It's a fastcall function called doit that returns the image in PGM format in the supplied buffer. Usage:

char buf[256 * 256 + 256];

FILE* f = fopen("k.pgm", "wb");
fwrite(buf, 1, sizeof buf, f);


hacker's logo

I used 256x256 resolution because it's cool it lets me split the pixel's index in ecx automatically into coordinates y in ch and x in cl. Also, the PGM file format requires the number 255 in the image header.

The inner squares are 54x54 (41% of the cell by area).

Source code (can be compiled by Visual Studio):

    pushad;                 // save all registers
    mov edi, ecx;           // edi is now the pointer to output
    mov eax, '  5P';        // PGM file header
    stosd;                  // store it
    mov eax, ' 652';        // the number 256 and a space
    stosd;                  // store the width
    stosd;                  // store the height
    stosd;                  // store maximum brightness
    dec byte ptr [edi-2];   // fix maximum brightness to 255

    xor ecx, ecx;           // initialize the counter of pixels
    dec cx;                 // to 65535
    push ecx;

    mov al, cl;             // al = cl = x coordinate in the image
    _emit 0xd4;             // divide by 85
    _emit 85;               // ah = x cell number, al = x coordinate in cell
    push eax;
    mov al, ch;             // al = ch = y coordinate in the image
    _emit 0xd4;             // divide by 85
    _emit 85;               // ah = y cell number, al = y coordinate in cell
    pop ebx;                // bh = x cell number, bl = x coordinate in cell

    mov dl, 0x80;           // gray pixel value
    test al, al             // is cell boundary (y)?
    je output1;
    test bl, bl;            // is cell boundary (x)?
    je output1;

    mov dl, 255;            // white pixel value
    sub al, 16;
    cmp al, 53;
    ja output1;             // if outside the inner square, output white
    xchg eax, ebx;          // exchange the registers to shorten following code
    sub al, 16;
    cmp al, 53;
    ja output1;             // if outside the inner square, output white

    lea ecx, [ebx * 2 + eax]; // cell index = y * 2 + x
    mov cl, ch;
    mov al, 0xe4;           // load the bitmap for the glider pattern
    shl al, cl;             // shift the needed but into SF
    jns output1;            // the bit was 0? - output white
    inc edx;                // the bit was 1? - change to black

    xchg eax, edx;
    stosb;                  // output the byte

    pop ecx;
    loop myloop;
    stosb;                  // output an additional gray pixel

The cell pattern

0 1 0
0 0 1
1 1 1

can be represented by an "optimized" bitmap of 7 bits.

The bits are indexed by the expression y * 2 + x, where (x,y) is the location of the cell. This expression gives the same index to 2 pairs of cells. It's a lucky coincidence that the bit values there are the same.

  • 1
    \$\begingroup\$ This is cool, but I make 42*42/85/85 only 24.4%. \$\endgroup\$ Jun 1, 2017 at 21:21
  • \$\begingroup\$ @JonathanAllan: The white parts of the cell are only 84x84, but yes, a 42x42 box is only a quarter of a 84x84 box. \$\endgroup\$ Jun 1, 2017 at 22:36
  • \$\begingroup\$ I've asked for clarification (if it does go to area I hope it's not too hard to update). \$\endgroup\$ Jun 1, 2017 at 22:42
  • \$\begingroup\$ The ruling is in - it's area... \$\endgroup\$ Jun 1, 2017 at 22:46
  • \$\begingroup\$ I enlarged the black dots from 42 to 54. It's the minimum, making them 40% by area, and they have already started being ugly... \$\endgroup\$
    – anatolyg
    Jun 1, 2017 at 23:00

PNG, 105 100 bytes

PNG image    (i.e. this image file)

Considering that HTML and other non-programming languages are allowed, I was curious to see how much I could golf a plain browser-displayable image, to serve as a baseline comparison. The result is compressed with the open-source tools optipng (-o7 -zm1-9 -strip all) and pngwolf. I also experimented with zopflipng, but the results were bigger. Other closed-source compression tools might be able to shave off a couple more bytes.

Image data in base64:


<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB8AAAA

Edit I made the dots touch the cell top and bottom, to cause more repetitiveness in the pixel pattern and thus improve the compression ratio. But don't worry, a dot still only fills (79)/(99) ≈ 78% of its cell.

Non-standard PNG, 88 bytes

As pointed out by @anatolyg, there is some golfing potential by removing the IEND chunk (12 bytes). Technically, IEND is required by the standard. However, each PNG chunk includes its own size and checksum information. It is therefore not absolutely necessary to have an end-marker. And indeed, all browsers I tested can display the image without issue.

Unfortunately (or fortunately), this non-standard image is rejected by imgur, so I cannot actually upload it. This is the base64 encoding:


<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB8AAAA

  • \$\begingroup\$ I'm not sure if this valid. PNG is not a programming language. \$\endgroup\$
    – DJMcMayhem
    Jun 2, 2017 at 15:43
  • 4
    \$\begingroup\$ Thank you MD XF. @DJMcMayhem Neither is HTML. But considering the small size of the image, I submitted it as an interesting outside-the-box entry. \$\endgroup\$
    – Meyer
    Jun 2, 2017 at 15:51
  • 4
    \$\begingroup\$ @DJMcMayhem Answers in non-programming-languages are technically allowed by consensus. Especially, for fixed-output challenges. \$\endgroup\$ Jun 2, 2017 at 16:39
  • 4
    \$\begingroup\$ Also, welcome to PPCG, @Meyer! :) \$\endgroup\$ Jun 2, 2017 at 16:41
  • 1
    \$\begingroup\$ You can remove a few bytes at the end of the file and still have the image. Might depend on a viewer though; I imagine most viewers don't require e.g. the end-chunk to be present. \$\endgroup\$
    – anatolyg
    Jun 4, 2017 at 9:50

R (130 119 113 bytes)


enter image description here

  • \$\begingroup\$ You can use axes=F to replace xaxt="n",yaxt="n". If you double all coordinate values, you save 4 net bytes (but can't use the 1:3,2:3 trick). \$\endgroup\$ Jun 1, 2017 at 11:02
  • \$\begingroup\$ @user2390246: thx for the suggestions. I didn't find much time to golf this out. I'm sure there are more possible improvements. I had to add ;box() as axes=F also removes the frame. Also, as axes is a plot parameter and not passed on to par through ... as xaxt/yaxt, it doesn't even need to be spelled out completely. \$\endgroup\$
    – mschilli
    Jun 1, 2017 at 15:00
  • 1
    \$\begingroup\$ You can shave off 7 bytes by (1) replacing c(1,7) with a variable (l=c(1,7)); (2) replacing ann with an; (3) replacing [xy]li with [xy]li; and (4) removing the second, redundant argument to grid: grid(3,lt=1). In fact, I’ve taken the liberty of editing this in (under review). \$\endgroup\$ Jun 2, 2017 at 13:25
  • 1
    \$\begingroup\$ @KonradRudolph Seems relevant: codegolf.meta.stackexchange.com/questions/1615/… \$\endgroup\$
    – Matt
    Jun 2, 2017 at 13:46
  • \$\begingroup\$ @Matt Hm. Seems that this makes sense if it applies fundamentally different optimisations, rather than just implementing straightforward improvements. Fair enough. \$\endgroup\$ Jun 2, 2017 at 13:56

Python 2.7, 214 311 309 bytes

from matplotlib.pyplot import*
for i in j:x.add_artist(Circle((i),.4,color='k'))     
for o in x.spines.values():o.set_edgecolor('gray')
for s in 'xy':exec"x.set_"+s+"ticks((.5,1.5,2.5));"+s+"lim(-.5,2.5);"

This is my first attempt here at code golf, so I'm sure this can be improved upon. I would have liked to not established the limits, but it appears that matplotlib can't detect that I plotted circles where I did. Without setting xlim() and ylim() it only shows the bottom two circles.



Edit:Fixed the color of the borders and removed the tick numbers. I must say matplotlib is very densely worded, and not too friendly with changing axis colors.

Shaved off 3 bytes thanks to @DJMcMayhem

Edit:Took off two bytes by setting my ticks as a tuple inside of set_ticks functions.

  • \$\begingroup\$ Sorry, the numbers on the graph are not allowed. Also, is the border gray? \$\endgroup\$
    – MD XF
    May 31, 2017 at 21:53
  • 3
    \$\begingroup\$ Welcome to the site! This is a nice first answer. :) \$\endgroup\$
    – DJMcMayhem
    May 31, 2017 at 22:02
  • 1
    \$\begingroup\$ Some minor golfs I see: 1) You can join lines 5 and 6 to remove one space and a newline (-2 bytes) 2) if the order of set xy_ticks and xy_lim doesn't matter, you could do something like for s in'xy':exec"x.set_"+s+"ticks(a);"+s+"lim(-.5,2.5);". (I haven't tested that though, so I'm not positive) \$\endgroup\$
    – DJMcMayhem
    May 31, 2017 at 22:06

Bash + ImageMagick, 233 226 characters

convert xc: +antialias -resize 31 -draw "stroke gray fill none ${r=rectangle} 0,0 10,30$r 20,0 30,30$r 0,0 30,10$r 0,20 30,30stroke #000 fill #000 ${c=circle} 15,5 15,8$c 25,15 25,18$c 5,25 5,28$c 15,25 15,28$c 25,25 25,28" x:

Sample output:

Glider drawn with Bash and ImageMagick

Bash + ImageMagick, 215 characters

convert xc: -resize 31 -draw "stroke gray fill none ${r=rectangle} 0,0 10,30$r 20,0 30,30$r 0,0 30,10$r 0,20 30,30stroke #000 fill #000 ${c=circle} 15,5 15,8$c 25,15 25,18$c 5,25 5,28$c 15,25 15,28$c 25,25 25,28" x:

The question owner not answered yet the anti-aliasing question and some other solutions also have additional gray shades added by the anti-aliasing, so for now this shorter one looks also acceptable.

Sample output:

Glider drawn with Bash and ImageMagick - with anti-aliasing


Ruby, 144 166 164 148 144 bytes

set background:'grey'
g.map{|y|g.map{|x|Square.new(x,y,9);Square.new(x+2,y+2,5,"black")if c[d]>0;d+=1}}



Edit: Now has grey gridlines.

  • 3
    \$\begingroup\$ I can see a few golfing opportunities here. For starters, d=d+1 has a shorter form (d+=1) and ==1 here is equivalent to >0. Also consider what happens when you set c to a Fixnum instead of an array :-) \$\endgroup\$
    – RJHunter
    Jun 1, 2017 at 6:26
  • 1
    \$\begingroup\$ @RJHunter I missed some low hanging fruit! And I thought about stuff like creating a bitfield with c, but couldn't come up with a way that's actually shorter in implementation. \$\endgroup\$ Jun 1, 2017 at 23:34
  • 2
    \$\begingroup\$ Perhaps surprisingly, Ruby actually has some bitfield support built in! You can access an integer with [] as if it were an array of bits (read-only, but that's OK here). \$\endgroup\$
    – RJHunter
    Jun 2, 2017 at 0:28
  • \$\begingroup\$ @RJHunter thanks! All I had to do was change c to the appropriate number. Reduced it quite a bit. \$\endgroup\$ Jun 2, 2017 at 0:44
  • \$\begingroup\$ You can change g=[2,13,24] to g=2,13,24 and replace each with map. \$\endgroup\$
    – Jordan
    Jun 3, 2017 at 18:28

Tikz, 193 175 170 bytes


Here is the output:


  • 3
    \$\begingroup\$ @MDXF It cuts close but since these are perfect circles and squares they make up π/4 of the square which is just about 79% of the square. \$\endgroup\$
    – Wheat Wizard
    Jun 1, 2017 at 18:46
  • \$\begingroup\$ Damn, looked at the challenge and had the exact same idea ;) \$\endgroup\$
    – racer290
    May 17, 2018 at 7:51

Octave, 127 124 bytes

Removed 3 bytes thanks to Luis. grid is sufficient (instead of grid on).


Outputs (after saving):

Note that the output shows grey grid lines in the plot window. They turn black when saving it (for some reason).

enter image description here

Well, that was long and messy! Had to go through a lot of modifications to make this adhere to the specs.

Explanation and hopefully some golfing coming up...

  • \$\begingroup\$ That doesn't look very squary, but since the OP did an answer with a similar output I guess it's fine.. \$\endgroup\$
    – L3viathan
    May 31, 2017 at 20:43
  • 2
    \$\begingroup\$ I think the height/width ratio is platform dependent. Add 'square' to make it square on all platforms. spy([0,1,0;0,0,1;1,1,1],'.k',80),set(gca,'XTick',.5:4,'XTickLabel','','YTick',.5:4,'YTickLabel',''),axis(.5+[0,3,0,3],'square'),grid on. \$\endgroup\$ May 31, 2017 at 20:55

Processing, 212 198 bytes

background(-1);noFill();stroke(99);rect(0,0,99,99);rect(0,33,99,33);rect(33,0,33,99);fill(0);int f=25;ellipse(15,83,f,f);ellipse(50,83,f,f);ellipse(83,83,f,f);ellipse(83,50,f,f);ellipse(50,15,f,f);

Basically, we are using simple Processing to draw a white Background, then setting the transparency of the rectangles used for the grid and drawing their strokes in gray. We continue by defining the rectangle, setting the fill value again to fill the circles black and defining fives circles.


enter image description here

You could add


or more to see the color of the strokes better.

(That's my first Code-Golf, I hope I did everything right.)

EDIT: Thanks to Kritixi Lithos! Removed the newlines, changed to int f=25 and used -1 in background(float)

  • 1
    \$\begingroup\$ Great first golf, and welcome to PPCG! \$\endgroup\$
    – MD XF
    Jun 1, 2017 at 22:05
  • 1
    \$\begingroup\$ You can save some bytes by removing the newlines, changing the float f=25; to int f=25; and by using background(-1) instead of background(255); \$\endgroup\$
    – user41805
    Jun 2, 2017 at 6:19

SmileBASIC, 125 bytes

GBOX.,8,30,38GBOX 10,8,20,38GBOX.,18,30,28G.,1G 1,2G-1,3G.,3G 1,3DEF G X,Y
GPUTCHR X*10+12,Y*10,58081,.END

58081 (U+E2E1, which is in the "Private Use Area" block) is the character code for a circle symbol. Putting it in a string would work too, but since it is encoded as 3 bytes in UTF-8, it would be the same length (and not show up correctly here).

markdown is awful

  • 1
    \$\begingroup\$ It's always refreshing to see basic answers! \$\endgroup\$ Feb 23, 2018 at 19:24

MATL, 74 69 68 64 62 bytes


Try it at MATL Online! (It takes a few seconds.)

Output from the online interpreter:

enter image description here


Processing, 134 bytes

Inspired by @Zep, here's my Processing one-liner (and also my first code golf):

stroke(127);for(int i=0;i<9;i++){int x=i%3*30;int y=i/3*30;fill(255);rect(x+5,y+5,30,30);if(i==1||i>4){fill(0);ellipse(x+20,y+20,23,23);}};

Thanks for @Kritixi Lithos for his brilliant tips on shaving a few bytes off!

glider in Processing

  • \$\begingroup\$ Please include a Language and Score line. \$\endgroup\$
    – Theraot
    Jun 2, 2017 at 3:50
  • \$\begingroup\$ Welcome to PPCG and nice first answer! As stated by Theraot, all submissions are required to have a header that contains the language and the bytecount. Also, you can golf some bytes by declaring all the variables in the for-loop, like for(int i=0,x,y;... so that you can drop the int in the body of the loop. Additionally, fill(255); can become just fill(-1); \$\endgroup\$
    – user41805
    Jun 2, 2017 at 6:17
  • \$\begingroup\$ I haven't tested this, but I think you can drop the +20 while setting the values of x and y, so that you can change the rect to rect(x+5,y+5,30,30); and the ellipse to ellipse(x+20,y+20,23,23); and save two bytes. \$\endgroup\$
    – user41805
    Jun 2, 2017 at 6:24

LaTeX + Tikz, 155 bytes

\documentclass[tikz]{standalone}\begin{document}\tikz{\draw(0,0)grid(3,3);\foreach\x/\y in{0/0,1/0,2/0,2/1,1/2}\fill(\x+.5,\y+.5)circle(.5);}\end{document}


  • 1
    \$\begingroup\$ Is that 1/0 doing division? \$\endgroup\$
    – wizzwizz4
    Jun 2, 2017 at 11:52
  • \$\begingroup\$ Sorry, but no, it is a simple separator in the pairs of x and y coordinates. \$\endgroup\$ Jun 2, 2017 at 11:54
  • \$\begingroup\$ You should be able to save a few bytes by scaling everything up by 2, so that your .5's become just 1. \$\endgroup\$
    – Chris
    Aug 28, 2017 at 4:07
  • \$\begingroup\$ @Chris The grid builtin produces unit-length cells by default, and it takes about 8 bytes more (adding [step=2]) to produce a larger grid. Simplifying the coordinates for the circles drawing would not save enough bytes. (You get 157 bytes if you do it) \$\endgroup\$ Aug 28, 2017 at 8:38
  • \$\begingroup\$ @TonioElGringo Ah, true. Teaches me to comment without testing it first ;) \$\endgroup\$
    – Chris
    Aug 28, 2017 at 18:39

Desmos, 90 characters/bytes

Nobody saw that one coming.


Graph link
Thanks pydude for reminding me about inequalities!
If needed, I can crop the exported Desmos PNG to remove the axis/unneeded graph space

Desmos exported PNG

Desmos graph

  • 1
    \$\begingroup\$ I'm pretty sure that you can fill in the region using an inequality. It will take some more equations to get to work, though. \$\endgroup\$
    – Luke B
    Mar 15, 2019 at 20:54
  • \$\begingroup\$ @pydude I made the circles inequalities. Thanks. \$\endgroup\$ Mar 15, 2019 at 21:02
  • 1
    \$\begingroup\$ A lot of bytes can be saved by rearranging and combining the equations: Graph link \$\endgroup\$
    – Endenite
    Mar 6, 2020 at 15:30
  • \$\begingroup\$ 38 bytes \$\endgroup\$ Jun 2, 2020 at 19:20
  • 1
    \$\begingroup\$ @AsoneTuhid my gosh you madlad. I'll edit when I get the chance. \$\endgroup\$ Jun 4, 2020 at 1:27

C#, 333 bytes

using System.Drawing;_=>{var b=new Bitmap(31,31);var g=Graphics.FromImage(b);g.FillRectangle(Brushes.White,0,0,31,31);for(int x=0,y;x<3;++x)for(y=0;y<3;++y){g.DrawRectangle(Pens.Gray,x*10,y*10,10,10);if(x==1&y<1|x>1&y==1|y>1)g.FillEllipse(Brushes.Black,x*10+1,y*10+1,8,8);}b.Save("t.png");System.Diagnostics.Process.Start("t.png");};

Full/Formatted version:

using System.Drawing;
Action<int> a = _ =>
    var b = new Bitmap(31, 31);
    var g = Graphics.FromImage(b);

    g.FillRectangle(Brushes.White, 0, 0, 31, 31);

    for (int x = 0, y; x < 3; ++x)
        for (y = 0; y < 3; ++y)
            g.DrawRectangle(Pens.Gray, x * 10, y * 10, 10, 10);
            if (x == 1 & y < 1 | x > 1 & y == 1 | y > 1)
                g.FillEllipse(Brushes.Black, x * 10 + 1, y * 10 + 1, 8, 8);


Idea is simple we create a graphics object from the image and use that to make the image all white. Then loop over each square of the image drawing the bounding rectangle. If it is one of the locations for a dot we draw that too. Lastly we save the image to file and let windows decide how to open it, in my case it opens with Windows Photo Viewer.

Using a Process to show the image and saving to file is a lot shorter than creating a windows forms or WPF app because of all the different classes and extra fluff needed to create them.



  • \$\begingroup\$ I don't think you have to use Process.Start, for example Titus answer just outputs image, doesn't open it \$\endgroup\$ Jun 4, 2017 at 11:55
  • \$\begingroup\$ @JeremyThompson the rules state you must display the image \$\endgroup\$ Jun 4, 2017 at 16:40

PHP, 221+2 bytes

<?imagefill($i=imagecreatetruecolor(31,31),0,0,~0);function q($i,$x,$y,$f){imagerectangle($i,$x*=10,$y*=10,$x+10,$y+10,5e6);$f?:imagefilledellipse($i,$x+5,$y+5,8,8,0);}for($p=16;$p--;)q($i,$p&3,$p>>2,53>>$p&1);imagepng($i);

Save to file; call in browser. Should your browser display gibberish,
insert header("Content-Type:image-png"); before imagepng($i);.

output The dots aren´t very round; that´s due to the small proportions.


function q($i,$x,$y,$f){        # function to draw quadrant:
    imagerectangle($i,$x*=10,$y*=10,$x+10,$y+10,5e6);   # draw lines in 0x4c4b40
    $f?:imagefilledellipse($i,$x+5,$y+5,8,8,0);         # if bit not set, draw dot

    imagecreatetruecolor(31,31) # create image
    ,0,0,~0);                   # fill with 0xffffff (white)
for($p=16;$p--;)q($i,           # loop through positions, call function
    $p&3,                           # $x=lower two bits
    $p>>2,                          # $y=upper two bits
    53>>$p&1                        # $f=one bit from %0000 0000 0011 0101
);                                      # (reversed inverted bit mask for dots)
imagepng($i);                   # output image

I think that 0x4c4b40 qualifies as approximated gray. If not, add four bytes.


R 313 236 bytes

a=function(s,...){axis(s,labels=F,tck=1, col="gray",lwd=9,...)}

Revised Code, based mostly on comments from @user2390246 saved 77 bytes. Much appreciate the help.

Also, want to add a call-out to the shorter R solution by @mschilli. It shows an elegant way of addressing the problem of the R graphical defaults.


Goes to a file names "r". Omitting and extension saved me four bytes. But then I had to edit the file extension back to "bmp" to get it to upload. So maybe I should not get credit for those four bytes.

The Hacker Logo


I thought to myself, "That graphic's nothing but a simple graph with five dots. Should be a simple matter to implement in a language with robust data graphics capabilities. Let's try it in R." But then I had to spend on the order of 80% of the bytes just working around R's graphic defaults.

Kinda the wrong tool for the job....

I could not find a less verbose way of guaranteeing the size and aspect ratio of the graphic than by calling the bmp constructor and then dev.off(). The combination accounts for 25 bytes. If your R session is set up right, you might get a graphic that looks more or less correct without spending those bytes, but it's not reliable or consistent.

  • 1
    \$\begingroup\$ A few suggestions: don't define your data frame b at all, just put the two vectors unnamed directly into the plot function. Use c(l,3) for xaxp and yaxp. You can just use F for false, no need to define it. And define a new function a(x,...) that calls axis(x) but has default values for labels, tck, etc, so that you don't need to specify them all twice. \$\endgroup\$ Jun 1, 2017 at 10:33
  • \$\begingroup\$ You can also use axes=F rather than xaxt='n',yaxt='n'. And you forgot to use .5 when defining l though you did use that trick later. \$\endgroup\$ Jun 1, 2017 at 10:46
  • 1
    \$\begingroup\$ Actually, what if you doubled all coordinate values to get rid of those pesky .5s altogether? \$\endgroup\$ Jun 1, 2017 at 10:54
  • 1
    \$\begingroup\$ If you're already gonna take off the .bmp file extension, you might as well just name the file r. \$\endgroup\$
    – MD XF
    Jun 1, 2017 at 18:49
  • \$\begingroup\$ @user2390246 -- Many thanks for the suggestions. Cumulatively saved on the order of 70 bytes. This was my first effort at golfing in R, and you spotted a lot of tyro's errors I probably should have seen. Next time I'll know better. \$\endgroup\$
    – CCB60
    Jun 2, 2017 at 4:42

TI-BASIC, 218 140 137 bytes

Note: this byte count is a bit inflated. The program only uses 85 tokens, but that's saved in 137 bytes. Also, if you're using a non-color calculator, you could save another 4 tokens because you don't have to specify the color (which is blue by default), but I don't know if their screens are large enough for this challenge because I don't own one.

prgmHACKER (138 bytes, 86 tokens):


For proper display, this program requires that Xmin = Ymin = 0, Xmax = Ymax = 3, Xscl = Yscl = 1. dX also needs to be properly set, but the calculator does that for you when you set any other window variable. I couldn't see how much space these variables used in RAM.

Furthermore, the format settings should be { RectGC, CoordOff, GridLine, GridColor:MEDGRAY, Axes:OFF, ExprOff, BorderColor:1, Background:OFF } but these are toggled values and don't consume any extra space depending on the setting.

  • \$\begingroup\$ To golf down the list, you could express these as {0,1,2,1,2} and {0,0,0,2,1} then add 0.5 to each item. \$\endgroup\$
    – wizzwizz4
    Jun 2, 2017 at 11:58
  • \$\begingroup\$ Tried that, but it didn't change the amount of RAM used by the lists. However, you gave me the idea to get rid of the lists in RAM and define them when the program runs, saving 78 bytes in RAM. \$\endgroup\$
    – foxite
    Jun 2, 2017 at 12:04
  • \$\begingroup\$ Order in the golf people! Change the L1 and L2 to L₁ and L₂, since you already use them. I think you can remove }, and L₁(I)+.5→A=>.5+L₁(I and L₂(I)+.5→B => .5+L₂(I→B. \$\endgroup\$
    – Adalynn
    Aug 1, 2017 at 0:11

R, 119 114 111 bytes

(Thans to @JayCe for saving me 3 bytes)

Not shorter than the other R solution, but a completely different approach:

for(i in 1:9){frame();if(i>4)points(.5,.5,,19,cex=29);box(fg=8)}

Uses a layout in which the 4 first plots are the empty cells, and the 5 others the ones with dots in them.


  • \$\begingroup\$ Can me made shorter than the other solution using positional arguments: here \$\endgroup\$
    – JayCe
    May 16, 2018 at 18:33
  • \$\begingroup\$ @JayCe indeed, thanks! \$\endgroup\$
    – plannapus
    May 17, 2018 at 7:40

Excel VBA, 180 bytes

An anonymous VBE Immediate window function that takes no input and outputs to the default worksheet object (Sheet1).

Cells.RowHeight=48:Cells.Interior.Color=-1:[B2:D4].Borders.Color=7434613:For Each s In[{21,32,13,23,33}]:Sheet1.Shapes.AddShape(9,48*(s\10)+4,Mid(s,2)*48+4,40,40).ShapeStyle=8:Next

Commented Version

Cells.RowHeight=48                      ''  Make the Cells square
Cells.Interior.Color=-1                 ''  Remove the default grid
[B2:D4].Borders.Color=7434613           ''  Create the 3x3 gray grid at range `B2:D4`
For Each s In [{21,32,13,23,33}]        ''  Assign and iterate over a list of where
                                        ''  to place the dots; This list is a range that 
                                        ''  is coerced into a numeric array
    Sheet1.Shapes.AddShape(         _   ''  Add a shape to the Sheet1 object
                9,                  _   ''  An Oval (msoShapeOval)
                48*(s\10)+4,        _   ''  At the calculated value from the left
                Mid(s,2)*48+4,      _   ''  At the calculated value from the top
                40,                 _   ''  that is 40 units wide
                40                  _   ''  and is 40 units tall
                ).ShapeStyle=8          ''  and is black filled with a black outline

Next                                    ''  repeat to end of list


Hacker Logo

-6 bytes for using [{21,32,13,23,33}] over Split("21 32 13 23 33")

-2 bytes for using Mid(s,2) over Right(s,1)

-3 bytes for using (s\10) over Left(s,1)


Octave 107 94 103 bytes

scatter([1:3,3,2],[1,1,1:3],1e5,zeros(5,3),'.');axis off;a=[1,7]/2;for i=.5:3.5;line(a,i);line(i,a);end


plot([1:3,3,2],[1,1,1:3],'k.','markersize',250);axis off;a=[1,7]/2;for i=.5:3.5;line(a,i);line(i,a);end

both solutions are 103 bytes.

  • 2
    \$\begingroup\$ I believe the dots have to be black \$\endgroup\$ Jun 1, 2017 at 10:38
  • \$\begingroup\$ ah, interesting, matlab interprets a scalar as a point, as opposed to broadcasting it. so instead of line([x1,x2],y) you have to do line([x1,x2],[y,y]) \$\endgroup\$ Jun 1, 2017 at 10:52

gnuplot, 158 156 bytes

se si ra-1
se xti 2
se yti 2
se st l 9 lc"gray"lt 1
se gr xt ls 9 yt ls 9
se bor ls 9
uns k
se form""
p'-'w cir fc"black"fs s
3 5 1
5 3 1
1 1 1
3 1 1
5 1 1

Because the radii are the same, I tried the following:

[... first eight lines same as above ...]
p'-'u 1:2:(1) w cir fc"black"fs s
3 5
5 3
1 1
3 1
5 1

But that lead to the same byte count.

Ungolfed with comments:

set size ratio -1                                     # make it a square.
set xtics 2                                           # vertical lines every 2 units
set ytics 2                                           # horizontal lines every 2 units
set style line 9 linecolor rgb "gray" linetype 1      # define line type 9 as solid gray
set grid xtics linestyle 9 ytics linestyle 9          # make internal lines of type 9
set border linestyle 9                                # make outside lines of type 9
unset key                                             # no legend please
set format ""                                         # no numbers next to axes please
plot '-' with circle fillcolor rgb "black" fill solid # plot black circles
3 5 1                                                 # at these locations
5 3 1
1 1 1
3 1 1
5 1 1

  • \$\begingroup\$ Are the circles <= 80% of the grid-boxes? \$\endgroup\$
    – MD XF
    Jun 1, 2017 at 18:49
  • \$\begingroup\$ Maybe by area, 𝜋/4 ≈ 78% \$\endgroup\$
    – anatolyg
    Jun 1, 2017 at 20:00
  • 2
    \$\begingroup\$ Yes, they cover pi/4, which is around 78%. I could make them slightly smaller and look better, but that would cost byte. \$\endgroup\$
    – user34409
    Jun 2, 2017 at 5:47
  • \$\begingroup\$ ... would cost one byte. \$\endgroup\$
    – user34409
    Jun 2, 2017 at 6:22

Apple Swift (iOS - CoreGraphics/QuartzCore) - 832 Bytes

I drew the shape entirely using Quartz for an Apple iOS device. Unfortunatly this isn't a particularly size mindful language so the result is quite large, but this is as small as I can get it.

UIGraphicsBeginImageContext(CGSize(width:60,height:60));let c=UIGraphicsGetCurrentContext()!;UIColor.lightGray.setStroke();c.addRect(CGRect(x:0,y:0,width:60,height:60));c.move(to: CGPoint(x:20,y:0));c.addLine(to: CGPoint(x:20,y:60));c.move(to: CGPoint(x:40,y:0));c.addLine(to: CGPoint(x:40,y:60));c.move(to: CGPoint(x:0,y:20));c.addLine(to: CGPoint(x:60,y:20));c.move(to: CGPoint(x:0,y:40));c.addLine(to: CGPoint(x:60, y:40));c.strokePath();UIColor.black.setFill();c.addEllipse(in:CGRect(x:22,y:2,width:16,height:16));c.addEllipse(in:CGRect(x:42,y:22,width:16,height:16));c.addEllipse(in:CGRect(x:2,y:42,width:16,height:16));c.addEllipse(in:CGRect(x:22,y:42,width:16,height:16));c.addEllipse(in:CGRect(x:42,y:42,width:16,height:16));c.fillPath();let i=UIGraphicsGetImageFromCurrentImageContext();sub.addSubview(UIImageView(image:i))

A more readable version for anyone that is interested:

    UIGraphicsBeginImageContext(CGSize(width: 60, height: 60))
    let c = UIGraphicsGetCurrentContext()!
    c.addRect(CGRect(x: 0, y: 0, width: 60, height: 60))
    c.move(to: CGPoint(x: 20, y: 0))
    c.addLine(to: CGPoint(x: 20, y: 60))
    c.move(to: CGPoint(x: 40, y: 0))
    c.addLine(to: CGPoint(x: 40, y: 60))
    c.move(to: CGPoint(x: 0, y: 20))
    c.addLine(to: CGPoint(x: 60, y: 20))
    c.move(to: CGPoint(x: 0, y: 40))
    c.addLine(to: CGPoint(x: 60, y: 40))
    c.addEllipse(in: CGRect(x: 22, y: 2, width: 16, height: 16))
    c.addEllipse(in: CGRect(x: 42, y: 22, width: 16, height: 16))
    c.addEllipse(in: CGRect(x: 2, y: 42, width: 16, height: 16))
    c.addEllipse(in: CGRect(x: 22, y: 42, width: 16, height: 16))
    c.addEllipse(in: CGRect(x: 42, y: 42, width: 16, height: 16))
    let i = UIGraphicsGetImageFromCurrentImageContext()
    sub.addSubview(UIImageView(image: i))

Here is the output produced in the iOS Simulator: Output


Ruby with Shoes, 118 characters

stroke gray
fill white
rect x=i%3*w=10,y=i/3*w,w,w
stroke fill black
oval x+2,y+2,7if 482[i]>0}}

Bit checking borrowed from RJHunter's comment made on Mark Thomas's Ruby solution.

Sample output:

Glider drawn with Ruby with Shoes


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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