Applications Google
Menu principal

Post a Comment On: Only Python

"pyContest challenge: 117 character-long solution"

20 Comments -

1 – 20 of 20
Anonymous Anonymous said...

Wow.

How did you come up with the numbers?

3:21 PM

Blogger André Roberge said...

All 3-string combinations can be represented by an index varying between:
0:3, 0:12, 0:10
where I use the Python slice notation. Thus, the shorter sequence for the modulus operation (i.e. that will give the fewer "wasted" indices) are
%3, %12 and %10. However, 3 is a dividor of 12 which means that, as we % from 1 to 255, there's going to be too much of an unwanted overlap (and not all relevant sequences will be generated). The next attempt has to be
%3, %14, %10
where the smallest prime numbers (2, 3, 5, 7) are used. Still, unless I am mistaken, to generate all 3-number combinations with these, you might need 3*14*10 = 420 consecutive integers. I wrote a little program (tried it with various combinations) and it was sheer luck that this generated all the required combinations with integers < 256!

3:36 PM

Anonymous Anonymous said...

Is there an typo in the post somewhere?
>>> s=' _ |_|_ _| |'
>>> s[0:][:3]
' _ '
>>> s[11:][:3]
'|'
>>> s[5:][:3]
'|_ '
>>>

To get '0' I have to use
0, 9, 3

also, with that string, how would you generate 1, which needs ' ' and ' |' ?

5:52 PM

Anonymous Anonymous said...

I tried to dig into your code to see how it works, but the output is not quite right.

j=''.join;seven_seg=lambda z:j(
    j(
        ' _ |_|_ _| |'[ord(
            "
\xa5\x8f\xb1\xdb\xad\xbdi\x03K\x9f"[int(a)]
        )%u:][:3]
        for a in z
    )+"\n"
    for u in(3,14,10)
)
>>> print seven_seg("0123456789")
 _  |_ _  _  |_ _  _  _  _  _ 
||_|| || ||_  _| _||_||_ |_ 
|_ |_| _|| ||_|| ||_ |_||_ | |

(hope blogger will let me use &nbsp;)

The code string seems to be all right (the original post accidentally includes two single quotes in the second string).

That aside, congratulations with this ingenious little lambda function.

6:04 PM

Blogger André Roberge said...

Sorry, I had left out some "pre" tags and spaces were wrongly indicated. It should be fixed now!

6:52 PM

Anonymous Anonymous said...

Just tried to run the test.py a min ago, got:

'0' should result in:
_
| |
|_|

but your module produced:
_
| |
_|

Guess the blog is doing somthing weird?

7:14 PM

Anonymous Anonymous said...

Absolutely brilliant technique -- thanks for sharing! I knew there had to be a way to get rid of that extra space.

Just for fun, I tried to see if there was an ASCII-only solution using this technique, using different values of the two main strings and three integers.

I found 30 such combinations, none of which had fewer than 3 non-ASCII characters... oh well.

You could have used \xd5 instead of \x03 without changing the other string or the integers, as 0xd5 is also congruent to 0, 3, and 3 mod 3, 14, and 10, respectively.

Thanks again for posting your solution!

7:40 PM

Blogger André Roberge said...

Sorry everyone about the problem with the spaces. I sent a copy of the working program to Simon Hengel (of PyContest fame!); hopefully he will agree to post it along with the other solutions.

7:56 PM

Anonymous Anonymous said...

Just for fun, here's a 119-character long variant of
your superb idea that's ASCII only. (Remove the line breaks to make it work!)

j=''.join;seven_seg=lambda z:j(j(' _ | |_ _|_|'
[ord('^r|=Zm.:v\r'[int(a)])%u*2:][:3]for a in z)
+"\n"for u in(3,7,8))

9:09 PM

Anonymous Anonymous said...

Great work, André!

As already noted, there are some problems when you cut&paste the code from HTML because it has only single whitespace (copying from HTML source should work).

Mark's proposal is nice, but has an escaped CR (\r) as the last character in your string.

Here is a 118 character fully printable variant without the \r:

j=''.join;seven_seg=lambda x:j(j(' _ |_|_ _| |'[ord('^rm=3|4:s»'[int(c)])%d*2:][:3]for c in x)+"\n"for d in(3,8,7))

Note that there is only one non-ascii character in the code.

Also, as already mentioned, you can get rid of the 0x3-Byte like this:

j=''.join;seven_seg=lambda z:j(j(' _ | |_ _|_|'
[ord('^r|=Zm.:v\r'[int(a)])%u*2:][:3]for a in z)
+"\n"for u in(3,7,8))

11:19 PM

Anonymous Anonymous said...

Sorry, I missed the point. Mark's solution was fully 7-bit though it was one char longer. It's questionable whether my shorter solution should be called "printable" because of the one 8-bit char (there is a difference between "visible" and "printable").

In the next contest, there should be subcategories for pure 7-bit ascii and no imports.

6:02 AM

Blogger Matt Wilson said...

Wait -- what does

j=''.join;

accomplish?

11:10 AM

Blogger André Roberge said...

Matt:

If you look closely, you will see that the solution reads:

lambda z:j(j( ...

Without j=''.join, this would have been

lambda z:''.join(''.join( ...

Even accounting for defining j, this assignment shortens the overall solution.

11:40 AM

Anonymous Anonymous said...

Nice solution Christoph!

I was unhappy with the carriage return too, until I realised that while there is a CR in the string, there actually isn't any CR in the Python *source*; merely an r and a backslash next to each other. So every character c in the solution has ord(c) between 32 and 126, which I guess is what I meant when I said `fully printable' (though tabs and newlines should also be considered printable, I suppose).

Still, this isn't `my solution'; it's the result of my playing with André's solution. Before seeing this, my best solution was still running at around 180 chars!

Mark (having figured out how to post non-anonymously).

11:52 AM

Anonymous Anonymous said...

>>> print seven_seg("7337")
_ _ _ _
|_ _| _||_
|_||_ |_ |_|

>>>

Ummm, its very nice program, i tryed to do the python challenge too but couldnt get a workin test, however, urs prints out each digit 1 lower.. y?

7:39 PM

Blogger André Roberge said...

Here's the result of an interactive session, with forbidden characters (by blogger) replaced...

Furthermore, pre-formatted html is not allowed here :-(

>>> j=''.join
>>> print '\xa5\x8f\xb1\xdb\xad\xbdi\x03K\x9f'
######### -> to be pasted in below
>>> seven_seg=lambda z:j(j('~_~~~|_|_~_|~|'
... [ord("#########"[int(a)])%u:][:3]for a in z)
... +"\n"for u in(3,14,10))
>>> print seven_seg('0123456789')
~_~~~~~_~~_~~~~~_~~_~~_~~_~~_~
|~|~~|~_|~_||_||_~|_~~~||_||_|
|_|~~||_~~_|~~|~_||_|~~||_|~_|

8:12 PM

Anonymous Anonymous said...

Hi André!

[OT]-question:

You write that it's been a while since you did any programming. I'm very interested in RUR-PLE, but it's been while since anything happened - how is 1.0 coming along?

/Håkan

4:35 PM

Blogger André Roberge said...

Regarding RUR-PLE:

I just started again working on it last week. I've revised the first 20 lessons or so, making a few small, but important changes. I'm hoping to have version 1.0 done in about three months. This will include anywhere between 20 and 30 additional lessons as compared with 0.9. It will include dealing with classes and objects, both within rur-ple and for stand-alone programs.

After completing version 1.0, I am planning to continue expanding the lessons with an introduction to pygame.

4:57 PM

Anonymous Anonymous said...

That sounds great! I think the work so far has been fantastic! I'm looking forward to 1.0.

/Håkan

3:23 AM

Anonymous Anonymous said...

These comments have been invaluable to me as is this whole site. I thank you for your comment.

5:35 AM

Spammers: none shall pass.
You can use some HTML tags, such as <b>, <i>, <a>

Comments on this blog are restricted to team members.

You will be asked to sign in after submitting your comment.
Please prove you're not a robot