Ok, here is how you write the shortest one
About http://www.pycontest.net... here's how it's done.
Sadly, it's pretty much impossible to put the code on the web because it has some really non-ascii stuff in it ;-)
Here's the key tricks (thanks to Remi and the others):
One of the key tricks is writing a short version of a very long octal number (or three).
I tried using base36 and int('gobledygook',36).
You could use 0xhexacodehere.
But here's the most space-efficient one: use base 256!
For each byte you want, create a char using chr(byte). Then paste them all together. Then put it in your code as a string. If you are lucky you will have no quotes or newlines in it, and the python interpreter will eat it.
You can later get the byte number x using ord('h!alsdf'[x]), and each byte by some dividing and modulo operation.
Another important piece is encoding 7 3-character strings as compactly as possible, and splitting them by offsets (which are encoded in the previosuly mentioned big number in base 8 ;-)
One extra squeeze is finding the shortest way to concatenate strings.
It's ''.join(), but if you are using it twice (or more), you save space by doing j=''.join and using j later.
Last one: Instead of defining a function, do a lambda:
def seven_seg(x): return .....
seven_seg=lambda x:
6 chars less!
And here is the shortest code I got so far (121 characters, requires python 2.4. On 2.2, it has to be 124).
In the contest, some guys are at 120. I don't know how. I can't even guess how ;-)
Update: it turns out I did know how to do it check it out I think it's the first public 120 :-)
BTW: you can't write that using kwrite. Vim works, though.
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
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.
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.
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.
Joost: even worse: andre claims a 117 should be possible!
http://gumuz.looze.net/wordpress/index.php/archives/2005/12/28/pycontest-seven-segment-display/
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).
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.
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 :-)