ASCII art compression

0

The following challenge is basically a simpler version of the one proposed by Dennis (Lossy ASCII art compression). I found the idea super interesting but a bit too convulted, and seeing as it didn't seem to be getting much attention I decided to modify it a little bit.

You'll be downloading 5 ASCII art text files, each of them composed only of the following characters:

@#+';:,.` 

Each char represents a different brightness level (1-10 from @ to the whitespace).

Given a quality ratio q, which varies from 0.5 to 0.9 in 0.1 increments, your job is to output a compressed version of each ASCII file, while making those files able to decompress themselves.

That is to say, ImageX.txt is compressed by Program.py into CompImageX-xx.cpp (xx being the quality of the compressed image). Once CompImageX-xx.c is executed, a final decompressed image ImageX-xx.txt is created.

The .py and .c extensions are just an example, you can write the compressor and compressed images in any language that you want (doesn't have to be the same language for both, but you can't use different languages for different images).

The quality changes the image output in a relatively simple way. We'll call the array of usable chars Arr. Each char of ImageX becomes Arr[RoundHalfDown((Arr.Index(char)*q))], with the exception of the whitespace which remains the same no matter the quality.

RoundHalfDown(0.6) = RoundHalfDown(0.7) = RoundHalfDown(1) = 1

RoundHalfDown(0.5) = RoundHalfDown(0.4) = RoundHalfDown(0) = 0

For a short example:

 '#;@

at q=0.5 would become

 #@+@`

You have to implement your own compressor, can't use any libraries that handle it for you.

You can view the images here and download them from here.

Your score is the square root of the size of your compressor, multiplied by the sum of the size of all the compressed files --> sqrt(c)*sum(f). Lowest score wins.

USER                    LANGUAGE                    SCORE
Dennis                  CJam                        1046877

Nicolás Siplis

Posted 2015-07-17T04:15:38.100

Reputation: 609

If I'm correctly interpreting it, Arr[RoundHalfDown((Arr.Index(char)*q))] is hideous. With q=0.4 you're mapping 1 2 3 4 5 6 7 8 9 10 to 1 2 2 3 3 3 4 4 5 10. You would actually get a better quality reduction by mapping them to 1 1 4 4 4 7 7 7 10 10, which uses fewer output values but spaces them evenly across the brightness. Unless you're assuming a crazy gamma value in the input images? – Peter Taylor – 2015-07-17T16:39:03.350

1Arrays are zero indexed. – Nicolás Siplis – 2015-07-17T18:51:26.970

Answers

1

CJam → CJam, score 1046877.4413

I'm not going to participate in my own challenge, but since this one doesn't contain its core part (figuring out the optimal transformation to make the original image more compressible), here I go:

q"@#+';:,.` ":P9,easdf*.4f+:iPf=S+er_N/z,:L;N-__&W%:Pf#2f+e`{(2b1>}%
e_P,2+b256b:c`P`":P,2+\256b\b{_2,#)_(@a?)+}%{(2-a\2b)*}%e_Pf="L"/N*"

The linefeed is for "readability" only.

It should be possible to improve the score by improving or simplifying the compression.

Summary

e# Read the input and modify the palette according to the quality.

q"@#+';:,.` ":P9,easdf*.4f+:iPf=S+er

e# Compute the line length and the unique characters of the palette.

_N/z,:L;N-__&W%:P

e# Replace each character by its index in the palette, plus two.

f#2f+

e# Perform run-length ecnoding, saving the runs using bijective base-2 numeration.
e# All related code has been adapted from this answer: 
e# http://codegolf.stackexchange.com/a/53065

e`{(2b1>}%

e# Convert from base length(palette)+2 to byte array (string).

e_P,2+b256b:c`

e# Push the palette and the code for the decoder.

P`":P,2+\256b\b{_2,#)_(@a?)+}%{(2-a\2b)*}%e_Pf="L"/N*"

Score

$ LANG=en_US
$ for i in {1..5}; do for q in 0.{5..9}; do
> cjam comp.cjam $q < image$i.txt > image-$i-$q.cjam
> done; done
$ wc -c comp.cjam
136 comp.cjam
$ wc -c image*.cjam
 2131 image-1-0.5.cjam
 2248 image-1-0.6.cjam
 2346 image-1-0.7.cjam
 2350 image-1-0.8.cjam
 2446 image-1-0.9.cjam
 3006 image-2-0.5.cjam
 3718 image-2-0.6.cjam
 3894 image-2-0.7.cjam
 3356 image-2-0.8.cjam
 4064 image-2-0.9.cjam
 2949 image-3-0.5.cjam
 2947 image-3-0.6.cjam
 3582 image-3-0.7.cjam
 3784 image-3-0.8.cjam
 3745 image-3-0.9.cjam
 2879 image-4-0.5.cjam
 2887 image-4-0.6.cjam
 3379 image-4-0.7.cjam
 3615 image-4-0.8.cjam
 3537 image-4-0.9.cjam
 4427 image-5-0.5.cjam
 4802 image-5-0.6.cjam
 5536 image-5-0.7.cjam
 6030 image-5-0.8.cjam
 6111 image-5-0.9.cjam
89769 total

Dennis

Posted 2015-07-17T04:15:38.100

Reputation: 196 637