The cosmic call is a message sent into space in 1999 and 2003. It's made of 23 127*127px monochrome bitmap images, as detailed here.

Your mission is to write a program that displays the entire 127*2921px message, either as a text (made of zeros, ones and line breaks) or as an image (drawn on screen or saved on disk). There will be two categories of winners: one for text output and one for image output.

All the tricks are permitted, except common loopholes.

It is allowed to output the 23 pages separately.

It is allowed to write up to 23 programs (like, one for each page) and sum their size to determine your score.

It is allowed to use up to 23 binary files alongside your program(s). Their weight is counted in your score.

The shortest code (in byte) wins.

At 1 bit per pixel, the image contains 127*127*23/8 = 46370 bytes + 7 bits of data. (warning: it's not allowed to output an extra zero if you store pixel values into 46371 bytes)

Trailing newline/space is allowed for the text output.

Visual output can not contain any black pixel besides the black pixels of the cosmic call. It can be drawn in one column (ordered correctly), or split in 23 images, or animated (like a gif), also ordered correctly.

Attachment: the text output, and the image output to reproduce:

cosmic call

  • 19
    \$\begingroup\$ “It is allowed to write many programs (like, one for each page) and sum their size to determine your score.” This is dangerous: the empty Jelly program prints 0, the empty Snails program prints 1, and the empty GolfScript program prints a newline. Someone might submit a 0-byte, 373888-program answer :) \$\endgroup\$
    – lynn
    Commented Jun 13, 2016 at 14:20
  • \$\begingroup\$ Haha, okay, so I'll limit the number of programs to 23. \$\endgroup\$
    – xem
    Commented Jun 13, 2016 at 14:29
  • \$\begingroup\$ Are trailing newlines / spaces permitted? \$\endgroup\$
    – xenia
    Commented Jun 13, 2016 at 16:12
  • \$\begingroup\$ yep . . . . . . \$\endgroup\$
    – xem
    Commented Jun 13, 2016 at 16:49
  • \$\begingroup\$ Can we use another file or do we have to work solely on the source file ? Eg. can I use IO to store a compressed version and then decompress it or does everything need to be a literal in the code. \$\endgroup\$ Commented Jun 17, 2016 at 4:34

7 Answers 7


GIF, 27386 bytes

Here are the pages of the original transmission sliced into individual GIF frames, it turned out not to be as small as 1 PNG of all of them :(

cosmic call animated GIF

  • 7
    \$\begingroup\$ Hello, and welcome to PPCG! While this is not going to win, it is still a good post. \$\endgroup\$ Commented Jun 14, 2016 at 0:31
  • \$\begingroup\$ Did you dither? May be able to save 300bytes or so if you use additive transparencies on the transitions. \$\endgroup\$ Commented Sep 9, 2016 at 22:44

HTML, 16012b

I compressed the image in PNG8, opened it in a text editor, appended

<svg onload="document.body.innerHTML='<img src=#>'">

at the end, and voilà:

Demo: http://xem.github.io/miniCosmicCall/

NB: appending just <img src=#> works too but it lets a lot of garbage visible, so I prefer not to.

PS: for the fun, I also put the entire message in a single, executable tweet (you can copy-paste it in a browser console and the image appears):


  • 1
    \$\begingroup\$ shortest answer+1 \$\endgroup\$ Commented Jun 15, 2016 at 14:14
  • \$\begingroup\$ didn't say my last word yet! \$\endgroup\$
    – xem
    Commented Jun 15, 2016 at 17:32
  • \$\begingroup\$ I'm certain I can't understand what you intended to say here. \$\endgroup\$ Commented Jun 15, 2016 at 17:40
  • \$\begingroup\$ sorry, I meant I'm trying to make something even smaller \$\endgroup\$
    – xem
    Commented Jun 15, 2016 at 17:55

Python 2.7 - 10971 8077 bytes


  • LZMA actually for some reason doesn't work for me, so I went back to Deflate.

  • I found an online tool to compress the PNG even further (they say they use lossy compression, but the array remains unchanged)

  • I golfed the __main__.py script a bit more...
  • I found I was omitting a step (extracting the data files from zip archive)
  • Added DL link (see bottom)

Most compression algorithms look at data as a 1 dimensional array, and therefore cannot capture the repeating 2 dimensional characters displayed in the cosmic call (IMO also makes it harder for aliens to understand too :P).

First, I selected each character as a 7*5 array and made a list of all unique characters (101 if I recall). Then I iterated over the image, and when a character was found, the position and index of that character (in the character list) were recorded.

Those positions could be represented with a single int, however with over 2K chars found, and positions ranging from 0-370966 (divmod form) require up to 3 bytes each. I collected the character positions in order however, so I instead converted absolute position to offset position, making most of the numbers less than 1 byte. I encoded this list in utf-8 to account for the few numbers that were greater than 1 byte

After recording and removing all the matched characters, I saved the png with maximum compression. I then packaged the python reconstruction script (reverse same process), the png, the chatacter template, and the character position list all into a zip file to take advantage of the fact that python can take a folder or zip file as an argument, and it will begin execution at any file in the top level named __main__.py. I played around with 7z a bit to get the best compression, which turned out to be LZMA with a 1M dict and 32bit words.

here's the decoder script (golfed but with comments still)

import sys,zipfile as z
z.ZipFile(sys.argv[0]).extractall() #extract data files from zip to cwd
from numpy import*
o=open  #next line overwrites open, which I need
from PIL.Image import*
from scipy.ndimage import*
a=imread('p')[:,:,0]/255 #read image file
a[:2414,0]=0 #draw vertical borders
for x in range(0,2921,127):a[[x,x+126],:]=0 #draw horizontal borders
with o('c','rb') as f:t=f.read();C=[int(i)for c in t for i in'{0:08b}'.format(ord(c))] #read character template file and convert to list of bytes
C=array(C[:-1]).reshape([101,7,5]) #re-slice (extra 0 appended to make even number of bytes) and re-shape
with o('l','rb') as f:L=array([ord(x)for x in f.read().decode('utf_8')]).reshape([2158,2]) #read decode and reshape positional list
p=0 #relative position accumulator
for e in L:p+=e[0];x,y=p%127,p/127;a[y:y+7,x:x+5]=C[e[1]] #divmod for x,y position and paste character template onto array at position
link to download for the zip file...

  • \$\begingroup\$ I am :) (and congrats for this score!) \$\endgroup\$
    – xem
    Commented Sep 10, 2016 at 6:22
  • \$\begingroup\$ @xem ...shortly after posting, I continued to mess with it, and it's broken rn (python giving me some sort of zlib error on load) also it's on my work computer. I'll put it up monday tho if I can revert it to a working state. :P \$\endgroup\$
    – Aaron
    Commented Sep 10, 2016 at 18:33
  • \$\begingroup\$ I feel like It could be possible to optimize a balance between the png compression and which characters I encode (lesser used ones) to save a few more bytes.. \$\endgroup\$
    – Aaron
    Commented Sep 10, 2016 at 18:35
  • 1
    \$\begingroup\$ @xem I added a dl link... \$\endgroup\$
    – Aaron
    Commented Sep 12, 2016 at 15:38
  • \$\begingroup\$ Love the 2D compression idea... What about 3D compression? (Stacking the images) \$\endgroup\$ Commented Sep 13, 2016 at 3:54

Gzip bzip2 in the shell, 20914 18965 bytes

Make the output data file with the text output provided in the question, bzip2 it and rename the file to s. This then allows:

bzcat s

to do the job. So it adds up to 18958 bytes of data and a 7 byte command.

  • 1
    \$\begingroup\$ I think you can save a couple of k using ’bzip2’ instead! \$\endgroup\$ Commented Jun 13, 2016 at 20:04
  • \$\begingroup\$ @DomHastings: I finally followed your advice. \$\endgroup\$ Commented Jun 13, 2016 at 20:58
  • \$\begingroup\$ For further research: Bubblegum and zopfli. \$\endgroup\$ Commented Jun 13, 2016 at 23:36

Bash + WebP binary, 11 + 15330 = 15341 bytes

As the rules state this:

Your mission is to write a program that displays the entire 127*2921px message … or as an image (drawn on screen or saved on disk).

It is allowed to use up to 23 binary files alongside your program(s). Their weight is counted in your score.


All the tricks are permitted, except common loopholes.

…I could not resist to post something stupidly simple.

The program is in bash and it outputs the image by saving it on disk.
It uses 1 binary file, which also happens to be image file (yeah WebP is an image format), therefore the program can do as little as… make a copy of that file.

So, the code (11 bytes):

cp b a.webp

Assuming the companion binary is named "b", the code writes the image file to disk with correct extension ("a.webp").

I see little reason to upload the binary, because it's trivially created by running

cwebp -z 9 <downloaded input file> b

it produces the file with 15330 bytes. If anyone wants, I can upload it somewhere.

NB: -z option in cwebp activates lossless compression mode. 9 is the compression strength (max).

  • \$\begingroup\$ OP author likes this \$\endgroup\$
    – xem
    Commented Aug 26, 2016 at 22:07

Pyth, 46381 bytes

For obvious reasons it cannot be posted here.

jc.BC"<too long>"127


Pastebin of hexdump of program.

  • \$\begingroup\$ you encode the bits 7 by 7 in latin-1 chars, right? Simple and nice! :) Of course, I'm looking for much better compression :p \$\endgroup\$
    – xem
    Commented Jun 13, 2016 at 14:37
  • 1
    \$\begingroup\$ Yes, I'm making a better compression. I encoded them 8 by 8, by the way. \$\endgroup\$
    – Leaky Nun
    Commented Jun 13, 2016 at 14:39
  • \$\begingroup\$ By the way, I wonder how you got this score: 127*127*23/8 = about 46371 bytes. Where did the 355 other bytes go? \$\endgroup\$
    – xem
    Commented Jun 13, 2016 at 14:51
  • \$\begingroup\$ Thanks, it exactly matches it now. You can actually see the extra 10 bytes in the code above (jc.BC""127"). \$\endgroup\$
    – Leaky Nun
    Commented Jun 13, 2016 at 15:20
  • \$\begingroup\$ How do you deal with the extra bit? (the entire message takes 46370 bytes + 7 bits. Your last byte may produce an extra zero, which is not a valid output) \$\endgroup\$
    – xem
    Commented Jun 13, 2016 at 15:43

Python 3, 64513 bytes

Use only ASCII !


Old version, 64529 bytes: http://pastebin.com/nteYkUtM

  • \$\begingroup\$ import lzma,base64,os \$\endgroup\$ Commented Jun 15, 2016 at 7:42
  • \$\begingroup\$ @EʀɪᴋᴛʜᴇGᴏʟғᴇʀ Thank you ! \$\endgroup\$ Commented Jun 15, 2016 at 10:59
  • 1
    \$\begingroup\$ @Mego I don't think that's necessary, given that it's ridiculously long. Let the comment votes decide. \$\endgroup\$
    – Riker
    Commented Aug 26, 2016 at 17:47

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.