Addicting. For folks (like me) who like this kind of thing. For others, perhaps just dumb. Or infuriating.
Years ago -- many, many years ago -- I vaguely remember a similar game with a name like "insanity" or something like that. Now there's http://www.notpron.com and http://www.weffriddles.com. All of these are "show the page source" HTML games. These games are a kind of steganography: the page your browser renders isn't what you need to see.
What's important about the Python Challenge is that it's not specifically about Python. Any programming language would do. Although I suspect that folks who don't know Python will have a difficult time with some of the puzzles. I found that having Pillow was essential for problems 7 and 11. I'm sure there are packages as powerful as PIL/Pillow for other languages.
Also, one of the hints included dated Python 2.7 code. The rest of the problems, however, seem to fit perfectly well with Python 3.4.
I wasted a morning getting to challenge 11. It was a ton of fun.
Challenge 12 was the first of the show-stoppers. The hint "evil1.jpg" is beyond subtle. Let me add this hint: This is the first puzzle where the pictures have digits. Perhaps there are related pictures.
I spent hours studying and rearranging and filtering and enhancing evil1.jpg before I finally broke down and searched for a hint. The hint -- of course -- included the whole solution, so I had to skim the code to figure out what I'd missed.
I have chapters to review. I really shouldn't be playing around with silliness like this.
In spite of that, let me just say, that reading about the "Look-and-Say" sequence was a bunch of fun. See http://oeis.org/A005150. Whatever you do, avoid reading this: http://archive.lib.msu.edu/crcmath/math/math/c/c671.htm; it won't help you with the Python Challenge at all. But it's interesting. And a huge time-waster. This particular challenge was more like Project Euler problems. [Project Euler is back up and running, BTW.]
Here's my variation on the Conway sequence theme:
def say( digits ): def run_lengths(digits): d_iter= iter(digits) c, d0 = 1, next(d_iter) for d in d_iter: if d0 == d: c += 1 else: yield str(c)+d0 c, d0= 1, d yield str(c)+d0 return "".join(run_lengths(digits))
I'm a fan of generator functions. A big fan.
The interesting part is that we can do run-length encoding for the look-and-say function relatively simply using the "buffered generator" design pattern.
1. Seed the buffer with the head of the sequence, next(d_iter)
2. For each item in the tail of the sequence:
a. If it matches, count.
b. If it doesn't match, yield the interim reduction and reset the counter.
3. Yield the tail reduction.
This design pattern seems to occur in a number of contexts outside games and abstract math.