Send a cosmic call

16

4

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

xem

Posted 2016-06-13T13:32:51.503

Reputation: 5 523

19“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 :) – Lynn – 2016-06-13T14:20:08.857

Haha, okay, so I'll limit the number of programs to 23. – xem – 2016-06-13T14:29:28.010

Are trailing newlines / spaces permitted? – Loovjo – 2016-06-13T16:12:50.223

yep . . . . . . – xem – 2016-06-13T16:49:30.090

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. – HopefullyHelpful – 2016-06-17T04:34:29.177

you can count external files size in your score :) – xem – 2016-06-17T08:48:58.490

Answers

18

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

innovati

Posted 2016-06-13T13:32:51.503

Reputation: 281

7Hello, and welcome to PPCG! While this is not going to win, it is still a good post. – NoOneIsHere – 2016-06-14T00:31:36.363

Did you dither? May be able to save 300bytes or so if you use additive transparencies on the transitions. – Magic Octopus Urn – 2016-09-09T22:44:29.033

7

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

xem

Posted 2016-06-13T13:32:51.503

Reputation: 5 523

1shortest answer+1 – Erik the Outgolfer – 2016-06-15T14:14:32.913

didn't say my last word yet! – xem – 2016-06-15T17:32:18.790

I'm certain I can't understand what you intended to say here. – Erik the Outgolfer – 2016-06-15T17:40:28.540

sorry, I meant I'm trying to make something even smaller – xem – 2016-06-15T17:55:48.557

6

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

Aaron

Posted 2016-06-13T13:32:51.503

Reputation: 1 213

I am :) (and congrats for this score!) – xem – 2016-09-10T06:22:36.730

@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 – Aaron – 2016-09-10T18:33:19.453

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.. – Aaron – 2016-09-10T18:35:03.997

1@xem I added a dl link... – Aaron – 2016-09-12T15:38:32.577

Love the 2D compression idea... What about 3D compression? (Stacking the images) – NonlinearFruit – 2016-09-13T03:54:13.443

@NonlinearFruit That sounds like a very interesting idea, however the characters would have to line up in similar xy positions in order to match multiple times. For this challenge, I don't think that approach would make the file any smaller, but it could possibly be beneficial in some very specific applications. – Aaron – 2016-09-13T13:18:24.750

3

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.

Julie Pelletier

Posted 2016-06-13T13:32:51.503

Reputation: 719

1I think you can save a couple of k using ’bzip2’ instead! – Dom Hastings – 2016-06-13T20:04:40.473

@DomHastings: I finally followed your advice. – Julie Pelletier – 2016-06-13T20:58:08.757

For further research: Bubblegum and zopfli.

– Digital Trauma – 2016-06-13T23:36:31.113

2

Pyth, 46381 bytes

For obvious reasons it cannot be posted here.

jc.BC"<too long>"127

Sample.

Pastebin of hexdump of program.

Leaky Nun

Posted 2016-06-13T13:32:51.503

Reputation: 45 011

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 – xem – 2016-06-13T14:37:38.730

1Yes, I'm making a better compression. I encoded them 8 by 8, by the way. – Leaky Nun – 2016-06-13T14:39:23.277

By the way, I wonder how you got this score: 12712723/8 = about 46371 bytes. Where did the 355 other bytes go? – xem – 2016-06-13T14:51:46.280

Thanks, it exactly matches it now. You can actually see the extra 10 bytes in the code above (jc.BC""127"). – Leaky Nun – 2016-06-13T15:20:56.947

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) – xem – 2016-06-13T15:43:50.980

I prepend a zero at the beginning. It gets disregarded by the .B. – Leaky Nun – 2016-06-13T15:54:52.387

then it's perfect :) thanks for the explanation – xem – 2016-06-13T16:02:18.893

If you compress your hexdump using LZW and then decompress it in your program you can save roughly 100096 bytes. – Benjamin Williams – 2016-06-16T16:19:23.620

You mean my source code instead of my hexdump? The program cannot read the hexdump directly. Of course the hexdump can be compressed: they are only made up of 17 characters. – Leaky Nun – 2016-06-16T18:43:14.610

2

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

Display Name

Posted 2016-06-13T13:32:51.503

Reputation: 654

OP author likes this – xem – 2016-08-26T22:07:00.353

1

Python 3, 64513 bytes

Use only ASCII !

http://pastebin.com/PMLb4Xti

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

TuxCrafting

Posted 2016-06-13T13:32:51.503

Reputation: 4 547

import lzma,base64,os – Erik the Outgolfer – 2016-06-15T07:42:56.790

@EʀɪᴋᴛʜᴇGᴏʟғᴇʀ Thank you ! – TuxCrafting – 2016-06-15T10:59:54.760

1@Mego I don't think that's necessary, given that it's ridiculously long. Let the comment votes decide. – Rɪᴋᴇʀ – 2016-08-26T17:47:07.143