Skip to main content

Ralsina.Me — Roberto Alsina's website

Ok, here is how you write the shortest one

About http://www.py­con­test.net... here's how it's done.

Sad­ly, it's pret­ty much im­pos­si­ble to put the code on the web be­cause it has some re­al­ly non-ascii stuff in it ;-)

Here's the key tricks (thanks to Re­mi and the oth­er­s):

One of the key tricks is writ­ing a short ver­sion of a very long oc­tal num­ber (or three­).

I tried us­ing base36 and in­t('­gob­ledy­gook',36).

You could use 0x­hex­a­code­here.

But here's the most space-­ef­fi­cient one: use base 256!

For each byte you wan­t, cre­ate a char us­ing chr(byte). Then paste them all to­geth­er. Then put it in your code as a string. If you are lucky you will have no quotes or new­lines in it, and the python in­ter­preter will eat it.

You can lat­er get the byte num­ber x us­ing or­d('h!als­d­f'[x]), and each byte by some di­vid­ing and mod­u­lo op­er­a­tion.

An­oth­er im­por­tant piece is en­cod­ing 7 3-char­ac­ter strings as com­pact­ly as pos­si­ble, and split­ting them by off­sets (which are en­cod­ed in the pre­vio­su­ly men­tioned big num­ber in base 8 ;-)

One ex­tra squeeze is find­ing the short­est way to con­cate­nate strings.

It's ''.join(), but if you are us­ing it twice (or more), you save space by do­ing j=''.join and us­ing j lat­er.

Last one: In­stead of defin­ing a func­tion, do a lamb­da:

def sev­en_seg(x): re­turn .....

sev­en_seg=lamb­da x:

6 chars less!

And here is the short­est code I got so far (121 char­ac­ter­s, re­quires python 2.4. On 2.2, it has to be 124).

In the con­test, some guys are at 120. I don't know how. I can't even guess how ;-)

Up­date: it turns out I did know how to do it check it out I think it's the first pub­lic 120 :-)

BTW: you can't write that us­ing kwrite. Vim work­s, though.

brucehoult / 2006-04-04 12:44:

cool, well done.



I'd taken your earlier post and played around with [foo:][:3] instead of [foo::7], and also compressing the strings by overlapping 1st and last chars but you beat me to it. GHuess it didn't help that I was learnign python at the same time.



One other thing I tried was to note hat you only actually need one bit for each character. Try this:



[' |_'[(94685>>a&1)*((a/7&1)+1)] for a in range(21)]



But I coudln't see how to get the decoding compact enough to be a win

rnd0110 / 2006-04-04 12:49:

Probably soemthing could be done to do it with &7 and remake binary encoding of the data... Then it will be 119?



I do not have time to check, but maybe ' _...' thingie could be made shorter by ' '*2 trick - this way the end + the beginning serve too. However, my math intuition tells me it doesn help.


Ian Bicking / 2006-04-04 12:49:

That's almost exactly like mine, except where you do '...'/u&14, I do '...'>>u&14, which takes one more character, but means later I use (6,0,3) (different numbers for a different string) where you use (64,8,1), and I get the one character back.

Joost Molenaar / 2006-04-04 12:51:

This is my 120 byte version, I made on change: the x7f was a literal ASCII code 127 in the submitted version.



j=''.join;seven_seg=lambda x:j(j(' _|?|'[ord('w$km>c&b;]for a in x for b in(2,1,4))+'n'for c in(6,3,0))



I can't wait to see the 119 byte one, it's killing me! I've tortured my mind for an hour trying to save one more byte, I think the 119 byte algorithm must be fundamentally different.

Roberto Alsina / 2006-04-04 12:51:
an anonymous coward / 2006-04-04 12:52:

Any solution that contains non-printable chars doesn't look "clean" enough. BTW it's non-portable, and portability might count if you decide to incorporate this code into some embedded hardware (which it should belong to).

André / 2006-04-04 12:52:

Joost: Just to torture you some more...



Indeed, I found a potential 117 character solution but the encoding string had some ascii character which couldn't be printed. (The way I built my solution was to write the encoding string directly to a file; I got a null file in that case.) I tried again, shifted all the values in the string by -1 and found a way (using a two character combination ...) to shift it back in my seven_seg.py program. There is perhaps a way to include the string that wouldn't "print" directly inside a file, thereby allowing for a 117 character solution.



Note that, other than my first name, I am posting this anonymously so as not to scoop the official announcement.

Roberto Alsina / 2006-04-04 12:53:

It is perfectly portable.



The default encoding for python source code is 8-bit ascii, and the program is written in 8-bit ascii.



If you need to use any other encoding you have to explicitly set it on a specially formatted comment, regardless of current locale.



And no, this kind of code doesn' t belong anywhere outside of a contest, IMHO :-)


Contents © 2000-2024 Roberto Alsina