16
\$\begingroup\$

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

\$\endgroup\$
  • 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 Jun 13 '16 at 14:20
  • \$\begingroup\$ Haha, okay, so I'll limit the number of programs to 23. \$\endgroup\$ – xem Jun 13 '16 at 14:29
  • \$\begingroup\$ Are trailing newlines / spaces permitted? \$\endgroup\$ – Loovjo Jun 13 '16 at 16:12
  • \$\begingroup\$ yep . . . . . . \$\endgroup\$ – xem Jun 13 '16 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\$ – HopefullyHelpful Jun 17 '16 at 4:34
18
\$\begingroup\$

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

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

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):

https://twitter.com/MaximeEuziere/status/742440423994580992

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

Python 2.7 - 10971 8077 bytes

update:

  • 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
a[2541:,0]=0
a[2412:,-1]=0
a[:2287,-1]=0
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
i=fromarray(a*255)
i.show()
link to download for the zip file...

\$\endgroup\$
  • \$\begingroup\$ I am :) (and congrats for this score!) \$\endgroup\$ – xem Sep 10 '16 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 Sep 10 '16 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 Sep 10 '16 at 18:35
  • 1
    \$\begingroup\$ @xem I added a dl link... \$\endgroup\$ – Aaron Sep 12 '16 at 15:38
  • \$\begingroup\$ Love the 2D compression idea... What about 3D compression? (Stacking the images) \$\endgroup\$ – NonlinearFruit Sep 13 '16 at 3:54
3
\$\begingroup\$

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.

\$\endgroup\$
  • 1
    \$\begingroup\$ I think you can save a couple of k using ’bzip2’ instead! \$\endgroup\$ – Dom Hastings Jun 13 '16 at 20:04
  • \$\begingroup\$ @DomHastings: I finally followed your advice. \$\endgroup\$ – Julie Pelletier Jun 13 '16 at 20:58
  • \$\begingroup\$ For further research: Bubblegum and zopfli. \$\endgroup\$ – Digital Trauma Jun 13 '16 at 23:36
2
\$\begingroup\$

Pyth, 46381 bytes

For obvious reasons it cannot be posted here.

jc.BC"<too long>"127

Sample.

Pastebin of hexdump of program.

\$\endgroup\$
  • \$\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 Jun 13 '16 at 14:37
  • 1
    \$\begingroup\$ Yes, I'm making a better compression. I encoded them 8 by 8, by the way. \$\endgroup\$ – Leaky Nun Jun 13 '16 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 Jun 13 '16 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 Jun 13 '16 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 Jun 13 '16 at 15:43
2
\$\begingroup\$

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.

and

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).

\$\endgroup\$
  • \$\begingroup\$ OP author likes this \$\endgroup\$ – xem Aug 26 '16 at 22:07
1
\$\begingroup\$

Python 3, 64513 bytes

Use only ASCII !

http://pastebin.com/PMLb4Xti

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

\$\endgroup\$
  • \$\begingroup\$ import lzma,base64,os \$\endgroup\$ – Erik the Outgolfer Jun 15 '16 at 7:42
  • \$\begingroup\$ @EʀɪᴋᴛʜᴇGᴏʟғᴇʀ Thank you ! \$\endgroup\$ – TuxCrafting Jun 15 '16 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\$ – Rɪᴋᴇʀ Aug 26 '16 at 17:47

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.