Applications Google
Menu principal

Post a Comment On: Only Python

"Journey to 117"

11 Comments -

1 – 11 of 11
Anonymous Anonymous said...

Just one remark about the final step where you said you used bruce force to calculate the 10 needed bytes and it was sheer luck that they turned out to be < 256.

Actually, it's not really sheer luck but mathematics. There is a famous old theorem about the existence and uniqueness of the solutions, and a fast algorithem for finding these numbers. It's called "Chinese remainder theorem." This theorem says there is a unique solution modulo the least common divisor, which is in this case 210.

That's why you can simply add 210 to get rid of the characters lower than 32. I.e. you can simply use chr(213) = Õ instead of the ugly 0x3 character.

With a little math you can spare a lot of programming - but ok, with a little programming you can spare a lot of math as well ;-)

9:17 PM

Blogger André Roberge said...

Thanks Christoph, I should have been able to figure that one out. It's been too long since I've had to think about math.

9:43 PM

Blogger André Roberge said...

Christoph:

Actually, it was (almost) sheer luck. As it turned out, the 10 "triplets", which I will denote by (a,b,c) were such that both "b" and "c" were odd numbers. If, for at least one of the triplets, they would have been such that one of (b|c) would have been even while the other onen would have been odd, then they could never have been generated simultaneously through %14 and %10.

7:09 PM

Anonymous Anonymous said...

congratulations Andre, well deserved winner!

10:37 PM

Anonymous Anonymous said...

Andre:

You're right; there was some luck involved as well. Actually, the Chinese Remainder Theorem guarantees a solution only in the case when the three numbers are coprime (have a gcd of 1). For instance, you will always find a solution mod 3, 13, 10. The only problem is that the solution varies in the range of the lcm; in this case 3*10*13=390 which may not fit into one byte. So 3,14,10 was a better triple because its lcm is only 3*2*5*7=210. Because these numbers are not coprime (both 10 and 14 are even), the existence of the solution is not guaranteed, but a certain condition needs to be met (see http://en.wikipedia.org/wiki/Chinese_remainder_theorem): The right sides of the equations must be pairwise congruent modulo the respective gcd's. In the case of

x%2 = i1
x%10 = i2
x%14 = i3

the condition is that i2 and i3 must be congruent modulo the gcd of 10, 14 which is 2, i.e. i2 and i3 must be either both even or both odd which explains your observation.

5:38 AM

Anonymous Anonymous said...

Hi André,

nice work done. Congratulations for the win.

>> I definitely welcome comments from others' journeys.

Maybe for the moment it's a bit more fruitful to prolong your journey a bit.

You like to see a 116 character-long solution in your blog that says journey to 117?

Don't be afraid, it's still your solution with less optimizations ;-)

First I want to repeat your 117 character version from [http://aroberge.blogspot.com/2005/12/pycontest-challenge-117-character-long.html]

I also removed the single quotes inside the double quotes of "'\xa5\x8f\xb1\xdb\xad\xbdi\x03K\x9f'" to make it work correctly:

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

And now let's get rid of another character. Just remove the ''.join optimization in conjunction with the newline string concatenation. And here it is, the 116 character-long solution:

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

With best greetings from Germany
*Markus Schramm

2:42 PM

Blogger André Roberge said...

So, the characters
j=''.join;jj+'\n'
are replaced by
''.join'\n'.join

Ingenious!

3:57 PM

Anonymous Anonymous said...

That 116 character solution is not valid: it doesn't end with a newline character, so it won't pass the tests.

5:22 PM

Anonymous Anonymous said...

Yes. Unfortunately the test required a final '\n'. So 117 still seems to be the philosopher's stone.

BTW, in my last comment there was a typo. The set of congruence equations should be

x%3 = i1
x%14 = i2
x%10 = i3

The rest was correct. The gcd of the modulus of the last two equations is 2, so i2 and i3 must be both odd or both even; if this is the case you will always get a unique solution x<210.

3:44 PM

Blogger Chuck said...

Wow, kinda cool stuff. May require brain surgery for me to understand it a short period of time. I try to think, but nothing happens. Hey, Moe! Hey, Larry!

3:07 PM

Blogger Doncho N. Gunchev said...

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

can be reduced by 2 characters using the trick that '\x03' can be written as octal like '\3':

seven_seg=lambda z:'\n'.join(''.join(' _ |_|_ _| |'[ord('\xa5\x8f\xb1\xdb\xad\xbdi\3K\x9f'[int(a)])%u:][:3]for a in z)for u in(3,14,10))

:-)

6:36 PM

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