<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>UnixWars &#187; python challenge</title>
	<atom:link href="http://unixwars.com/tag/python-challenge/feed/" rel="self" type="application/rss+xml" />
	<link>http://unixwars.com</link>
	<description>Taher Shihadeh's ragbag</description>
	<lastBuildDate>Mon, 26 Dec 2011 23:38:31 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Python Challenge level 23: &#8220;what is this module?&#8221;</title>
		<link>http://unixwars.com/2007/09/29/python-challenge-level-23-what-is-this-module/</link>
		<comments>http://unixwars.com/2007/09/29/python-challenge-level-23-what-is-this-module/#comments</comments>
		<pubDate>Fri, 28 Sep 2007 23:17:34 +0000</pubDate>
		<dc:creator>Taher Shihadeh</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[python challenge]]></category>

		<guid isPermaLink="false">http://unixwars.com/2007/09/29/python-challenge-level-23-what-is-this-module/</guid>
		<description><![CDATA[As I understand it, this was the former last level of the game. Level 23. In time 10 more levels were added. Hint 1: it can&#8217;t find it. this is an undocumented module. Hint 2: va gur snpr bs jung? One needs Python to solve this one. No other language will do. There&#8217;s no real [...]]]></description>
			<content:encoded><![CDATA[<p>As I understand it, this was the former last level of the game. <a title="Level 23 challenge" href="http://www.pythonchallenge.com/pc/hex/bonus.html">Level 23</a>. In time 10 more levels were added.</p>
<p><strong>Hint 1:</strong> <em>it can&#8217;t find it. this is an undocumented module.</em><br />
<strong>Hint 2:</strong> <em>va gur snpr bs jung?</em></p>
<p>One needs Python to solve this one. No other language will do. There&#8217;s no real need to <strong>use</strong> Python, but you doo need it.<br />
After having spent some time in the forums for hints for some of the previous level, one gets to see that &#8216;encrypting&#8217; things with ROT13 is a tradition over there. And the second hint is ROT13 for &#8216;in the face of what?&#8217;</p>
<p>I didn&#8217;t think about it at first, but the author said there that the solution was to take the hints literally. The answer to the riddle can be found in &#8220;Gur Mra bs Clguba, ol Gvz Crgref&#8221;. It looks like a Czech proverb, but it isn&#8217;t. At least that I konw of. After poking into every module, the only undocoumented module -as in &#8216;no a single comment in it&#8217;, not even oneliners!- is the answer to our prayers. It can be found a lot faster by just grepping for &#8216;the face of&#8217;:</p>
<pre class="prettyprint">taher@borg:/usr/lib/python2.5$ grep -i "va gur snpr bs" *
this.py:Va gur snpr bs nzovthvgl, ershfr gur grzcgngvba gb thrff.</pre>
<p>Heh! &#8216;this module is undocumented&#8217;. Nice one. Try importing module &#8216;this&#8217; in your Python interpreter. It&#8217;s amusing. The famous &#8220;proverb&#8221; is attributed to <a title="The Zen of Python" href="http://www.python.org/doc/Humor.html#zen">Tim Peters</a>, who went by the name of UncleTimmy in the forums.</p>
<p>You&#8217;ll find the key to the next level either in the previous link or in the allready mentioned <em>this.py</em>.<br />
Next is <a href="http://unixwars.com/wp-admin/?p=32">Level 24</a>.</p>
<p>There&#8217;s something left in this level:</p>
<blockquote><p>TODO: do you owe someone an apology? now it is a good time to tell him that you are sorry. Please show good manners although it has nothing to do with this level.</p></blockquote>
<p>The only one ever insulted would have been Leopold, and since he doesn&#8217;t like cookies one would figure the second best thing is to simply drop him a line. If you apologize and he&#8217;s in good mood, you&#8217;ll get a response like this one:</p>
<blockquote><p>From: Leopold Mozart &lt;leopold.moz@pythonchall&#8230; &gt;<br />
Subject: Re: sorry<br />
Never mind that.</p>
<p>Have you found my broken zip?<br />
md5: bbb8b499a0eef99b52c7f13f4e78c24b</p>
<p>Can you believe what one mistake can lead to?</p></blockquote>
<p>I guess it&#8217;ll be useful in the future. This was one easy and really nice level. If it&#8217;s the first time you hear of <a title="The Zen of Python" href="http://www.python.org/doc/Humor.html#zen">The Zen of Python</a>, you should take a look. You&#8217;ll like it!</p>
]]></content:encoded>
			<wfw:commentRss>http://unixwars.com/2007/09/29/python-challenge-level-23-what-is-this-module/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python Challenge level 22: &#8220;emulate&#8221;</title>
		<link>http://unixwars.com/2007/09/28/python-challenge-level-22/</link>
		<comments>http://unixwars.com/2007/09/28/python-challenge-level-22/#comments</comments>
		<pubDate>Fri, 28 Sep 2007 21:50:52 +0000</pubDate>
		<dc:creator>Taher Shihadeh</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[python challenge]]></category>

		<guid isPermaLink="false">http://unixwars.com/2007/09/28/python-challenge-level-22/</guid>
		<description><![CDATA[Level 22 got me stuck for a while. Hint 1: or maybe white.gif would be more bright Hint 2: image of a joystick I didn&#8217;t know what to do with this one untill I notices it was a GIF89, which reminded me of animated GIFs. After opening it with Gimp I saw that it had [...]]]></description>
			<content:encoded><![CDATA[<p><a title="Level 22 challenge" href="http://www.pythonchallenge.com/pc/hex/copper.html">Level 22</a> got me stuck for a while.</p>
<p><strong>Hint 1:</strong> or maybe white.gif would be more bright<br />
<strong>Hint 2:</strong> image of a joystick</p>
<p>I didn&#8217;t know what to do with this one untill I notices it was a GIF89, which reminded me of animated GIFs. After opening it with Gimp I saw that it had 133 frames. Now I had something. It turns out one of the pixels is slightly lighter in each frame in one of several locations. Only 9 of them, actually. Just as the number of possible positions for a joystick. The code bellow is anything but pretty. Beware!</p>
<p><strong> Fact 1:</strong> We&#8217;re looking for color 8, as shown below. This can be found using im.getcolors() in every frame</p>
<pre class="prettyprint">#!/usr/bin/env python
import Image,ImageDraw
def get_vectors():
    # Return a list of movement vectors extracted from wiggling pixels
    im = Image.open("white.gif")
    vectors=[]
    try:
        while True:
            pix=list(im.getdata()).index(8)
            y,x=divmod(pix,200)
            v=(x-100,y-100)
            vectors.append(v)
            im.seek(im.tell()+1)
    except EOFError:
        pass # end of sequence
    return vectors

max_x, h, w = 0, 50, 250
im = Image.new('RGB', (w,h))
draw = ImageDraw.Draw(im)
src = (max_x,h//2) # (x,y)
for v in get_vectors():
    if v==(0,0):
        max_x+=30
        src = (max_x,h//2)
        continue
    dst=(src[0]+v[0],src[1]+v[1])
    max_x=max(max_x,dst[0])
    draw.line([src, dst], fill='white')
    src=dst
im.save('22.jpg')</pre>
<p>This renders the following image:</p>
<p><img title="bonus" src="http://unixwars.com/wp-content/2007/09/22.jpg" border="0" alt="bonus" hspace="0" vspace="0" width="250" height="50" align="absmiddle" /></p>
<p>Thats our link for next level: <a href="http://unixwars.com/2007/09/29/python-challenge-level-23-what-is-this-module/">Level 23</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://unixwars.com/2007/09/28/python-challenge-level-22/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python Challenge level 21: &#8220;hidden pack&#8221;</title>
		<link>http://unixwars.com/2007/09/27/python-challenge-level-21-hidden-pack/</link>
		<comments>http://unixwars.com/2007/09/27/python-challenge-level-21-hidden-pack/#comments</comments>
		<pubDate>Thu, 27 Sep 2007 16:11:29 +0000</pubDate>
		<dc:creator>Taher Shihadeh</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[python challenge]]></category>

		<guid isPermaLink="false">http://unixwars.com/2007/09/27/python-challenge-level-21-hidden-pack/</guid>
		<description><![CDATA[There&#8217;s no page for this challenge. From the previous level we get a hidden file that was &#8220;hiding at 1152983631&#8243;. It&#8217;s a zipfile with a password. Luckily back in level 20 we also got a tip &#8220;esrever ni emankcin wen ruoy si drowssap eht&#8221;, and a nickname: invader. After extracting the archive, we get a [...]]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s no page for this challenge. From the previous level we get a hidden file that was <em>&#8220;hiding at 1152983631&#8243;</em>. It&#8217;s a zipfile with a password. Luckily  back in level 20 we also got a tip <em>&#8220;esrever ni emankcin wen ruoy si drowssap eht&#8221;</em>, and a nickname: <strong>invader</strong>.</p>
<p>After extracting the archive, we get a text file with the hints, and a file named <strong>package.pack</strong></p>
<p><strong>Hint 1:</strong> <em>We used to play this game when we were kids.</em><br />
<strong>Hint 2:</strong> <em>When I had no idea what to do, I looked backwards.</em><br />
<strong>Hint 3:</strong> package.pack</p>
<p>The <em>.pack</em> extension suggested something, so after trying several compression modules the winner is <a href="http://www.python.org/doc/lib/module-zlib.html"><strong>zlib</strong></a> . Once extracted the file&#8217;s size is more or less the same. Suspicious. Still unreadable. The second hint comes in handy, and it looks like the tail of the file is a reversed bzip2 header. We already have experience with that thanks to previous levels, isn&#8217;t it? Again unreadable. Again reversible. Again compressed. And the show goes on. We&#8217;ll have to go back and forth several times to extract the content.</p>
<pre class="prettyprint">import zlib,bz2
st=open('21_package.pack').read()
log=''
log_len=len(log)
while True:
    try: #zlib
        st=zlib.decompress(st)
        log+=' '
    except:
        try: #bzip2
            st=bz2.decompress(st)
            log+='#'
        except: #reverse
            if log_len==len(log): break
            st=st[::-1]
            print log[log_len:]
            log_len=len(log)
open('21_package.unpack','wb').write(st)</pre>
<p>After the whole run we get to read what&#8217;s in package.pack:</p>
<blockquote><p>look at your logs</p></blockquote>
<p>Originaly I kept a list with the number of zlib and bzip2 cycles en each run, expecting a banner(ish) run length encoding. I noticed that the sum of cycles needed to complete each direction was allways roughly the same. That is, before I had to reverse the string to start over, the sum of bzip+zip+bzip+&#8230; was more or less 73. And that meant that the output was meant to be directly graphical, so I sticked with a simpler log version that simplifies the code in turn.</p>
<p>The logs in question look like:</p>
<pre>      ###          ###      ########    ########    ##########  ########
    #######      #######    #########   #########   #########   #########
   ##     ##    ##     ##   ##      ##  ##      ##  ##          ##      ##
  ##           ##       ##  ##      ##  ##      ##  ##          ##      ##
  ##           ##       ##  #########   #########   ########    #########
  ##           ##       ##  ########    ########    ########    ########
  ##           ##       ##  ##          ##          ##          ##   ##
   ##     ##    ##     ##   ##          ##          ##          ##    ##
    #######      #######    ##          ##          #########   ##     ##
      ###          ###      ##          ##          ##########  ##      ##</pre>
<p>Will wonders never cease? Very nice level. It took me a while to figure out the representation for the logs and I never made sense of the first hint -something cultural I suppose-, but an excellent level nevertheless.</p>
<p>Copper is the next level. <a title="Solution to level 22" href="http://unixwars.com/2007/09/27/python-challenge-level-21-hidden-pack/">Level 22</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://unixwars.com/2007/09/27/python-challenge-level-21-hidden-pack/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Python Challenge level 20: &#8220;go away!&#8221;</title>
		<link>http://unixwars.com/2007/09/26/python-challenge-level-20-go-away/</link>
		<comments>http://unixwars.com/2007/09/26/python-challenge-level-20-go-away/#comments</comments>
		<pubDate>Wed, 26 Sep 2007 14:10:27 +0000</pubDate>
		<dc:creator>Taher Shihadeh</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[python challenge]]></category>

		<guid isPermaLink="false">http://unixwars.com/2007/09/26/python-challenge-level-20-go-away/</guid>
		<description><![CDATA[Level 20 meant Chaos. Hint 1: &#8216;unreal.jpg&#8217;, an image of a fence with the message &#8220;private property beyond this fence&#8221; Hint 2: but inspecting it carefully is allowed. As I said, this riddle was chaotic. Completely. Very interesting indeed, but it took some serious trial and error. From deeper inspection of the headers I got [...]]]></description>
			<content:encoded><![CDATA[<p><a title="Level 20 challenge" href="http://www.pythonchallenge.com/pc/hex/idiot2.html">Level 20</a> meant Chaos.</p>
<p><strong>Hint 1:</strong> &#8216;unreal.jpg&#8217;, an image of a fence with the message <em>&#8220;private property beyond this fence&#8221;</em><br />
<strong>Hint 2:</strong> <em>but inspecting it carefully is allowed.</em></p>
<p>As I said, this riddle was chaotic. Completely. Very interesting indeed, but it took some serious trial and error. From deeper inspection of the headers I got the following facts:</p>
<p><strong>Fact 1:</strong> One of the headers is &#8216;<em>Content-Range: bytes 0-30202/2123456789</em>&#8216;. I had to look for some info on this subject because I wasn&#8217;t familiar with it. Found some enlightenment in the appropriate <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35">RFC2616</a>.</p>
<p><strong>Fact 2:</strong> beyond the fence would be in the range 30203 &#8211; 2123456789. Such huge size is suspicous, so after trying a retrieval of the whole range at once, and after not getting any meanigful results, I stuck to getting some chunks along the stream. Some at the beginning of the fence boundary, some at the end of the range. There could be more interesting places between the values mentioned, by I do believe the most significant ones are retrieved in the following script.</p>
<p>Obviously I didn&#8217;t start with these values. I merely requested fragments from the beginning and the end of the stream, and selected the ones interesting for your convinience. I know, I know! I&#8217;m a nice guy, don&#8217;t mention it :-D</p>
<pre class="prettyprint">import urllib
url = 'http://butter:fly@www.pythonchallenge.com/pc/hex/unreal.jpg'

##Private info found
for i in [(30237,30337), (30284,30384), (30295,30395), (30313,30413),
            (2123456744,2123456788), (2123456712,2123456743)]:
    opener = urllib.FancyURLopener({})
    opener.addheader("range", "bytes=%d-%d" % i)
    f = opener.open(url)
    print f.read()

##Something hidden in this particular range.
opener = urllib.FancyURLopener({})
opener.addheader("range", "bytes=%d-%d" % (1152983631,1152983671))
f = opener.open(url)
print f.info()
open("20.zip", "w").write(f.read())</pre>
<p>The relevant pieces of information I could come up with were:</p>
<blockquote><p><strong>Content-Range: bytes 30237-30283/2123456789</strong><br />
<em>we can go on in this way for really long time.</em><br />
<strong>Content-Range: bytes 30284-30294/2123456789</strong><br />
<em>stop this!</em><br />
<strong>Content-Range: bytes 30295-30312/2123456789</strong><br />
<em>invader! invader!</em><br />
<strong>Content-Range: bytes 30313-30346/2123456789</strong><br />
<em>ok, invader. you are inside now.</em><br />
<strong>Content-Range: bytes 2123456712-2123456743/2123456789</strong><br />
<em> and it is hiding at 1152983631</em><br />
<strong>Content-Range: bytes  2123456744-2123456788/2123456789</strong><br />
esrever ni emankcin wen ruoy si drowssap eht</p></blockquote>
<p>To &#8216;be in&#8217; must mean that this level has been solved. The catch is we don&#8217;t have an URL to refer to for level 21. Fortunately we do have a ZIP file. Discovering it&#8217;s misteries will be the next riddle, <a title="Solution to level 21" href="http://unixwars.com/2007/09/27/python-challenge-level-21-hidden-pack/">Level 21</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://unixwars.com/2007/09/26/python-challenge-level-20-go-away/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python Challenge level 19: &#8220;please!&#8221;</title>
		<link>http://unixwars.com/2007/09/25/python-challenge-level-19-please/</link>
		<comments>http://unixwars.com/2007/09/25/python-challenge-level-19-please/#comments</comments>
		<pubDate>Tue, 25 Sep 2007 17:13:38 +0000</pubDate>
		<dc:creator>Taher Shihadeh</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[python challenge]]></category>

		<guid isPermaLink="false">http://unixwars.com/2007/09/25/python-challenge-level-19-please/</guid>
		<description><![CDATA[For level 19 I used two scripts. Hint 1: there is an email in the source with an attached file #!/usr/bin/env python import email mail=email.message_from_file(open('19.txt')) for part in mail.walk(): if part.get_content_maintype()=='audio': audio=part.get_payload(decode=1) open('19_indian.wav', 'wb').write(audio) The only understandable thing in the file was the word &#8220;sorry&#8221;, and that page is not really useful. Theres more to [...]]]></description>
			<content:encoded><![CDATA[<p>For <a title="Level 19 challenge" href="http://butter:fly@www.pythonchallenge.com/pc/hex/bin.html">level 19</a> I used two scripts.</p>
<p><strong>Hint 1:</strong> there is an email in the source with an attached file<strong><br />
</strong></p>
<pre class="prettyprint">#!/usr/bin/env python
import email
mail=email.message_from_file(open('19.txt'))
for part in mail.walk():
    if part.get_content_maintype()=='audio':
        audio=part.get_payload(decode=1)
        open('19_indian.wav', 'wb').write(audio)</pre>
<p>The only understandable thing in the file was the word &#8220;sorry&#8221;, and <a href="http://www.pythonchallenge.com/pc/hex/sorry.html">that page</a> is not really useful. Theres more to the riddle than meets the ear.</p>
<p><strong>Hint 2:</strong> the colors of the map seem to be inverted.</p>
<p>After trying reversing the info (utter jibberish), the hint is to be reinterpreted as &#8220;inverted India&#8221;, which I take as &#8220;inverted endian&#8221;. Nice longshot. And correct, for what it&#8217;s worth.</p>
<pre class="prettyprint">#!/usr/bin/env python
import array,wave
wi = wave.open('19_indian.wav','rb')
wo = wave.open('19_indian_inv.wav', 'wb')
wo.setparams(wi.getparams())
a = array.array('i')
a.fromstring(wi.readframes(wi.getnframes()))
a.byteswap()
wo.writeframes(a.tostring())
wi.close(),wo.close()</pre>
<p>This part of the challenge was completely unexpected. I hadn&#8217;t even used the wave module untill today! And we get a nice file with these lyrics:</p>
<blockquote><p>you are an idiot</p></blockquote>
<p>And with a <a href="http://www.pythonchallenge.com/pc/hex/idiot.html">message</a> from Leopold, we go to <a title="Solution to level 20" href="http://unixwars.com/2007/09/26/python-challenge-level-20-go-away/">Level 20</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://unixwars.com/2007/09/25/python-challenge-level-19-please/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Python Challenge level 18: &#8220;can you tell the difference?&#8221;</title>
		<link>http://unixwars.com/2007/09/24/python-challenge-level-18-can-you-tell-the-difference/</link>
		<comments>http://unixwars.com/2007/09/24/python-challenge-level-18-can-you-tell-the-difference/#comments</comments>
		<pubDate>Mon, 24 Sep 2007 21:30:49 +0000</pubDate>
		<dc:creator>Taher Shihadeh</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[python challenge]]></category>

		<guid isPermaLink="false">http://unixwars.com/2007/09/24/python-challenge-level-18-can-you-tell-the-difference/</guid>
		<description><![CDATA[Level 18 is imaginative again. Hint 1: it is more obvious that what you might think. Fact 1: the main difference between images is brightness, we&#8217;ll go to brightness.html which is an almost twin page except for a new hint. Hint 2: maybe consider deltas.gz. After retrieving deltas.gz, we can go on with the script: [...]]]></description>
			<content:encoded><![CDATA[<p><a title="Level 18 challenge" href="http://www.pythonchallenge.com/pc/return/balloons.html">Level 18</a> is imaginative again.</p>
<p><strong>Hint 1:</strong> <em>it is more obvious that what you might think.</em></p>
<p><strong>Fact 1:</strong> the main difference between images is brightness, we&#8217;ll go to <a href="http://www.pythonchallenge.com/pc/return/brightness.html">brightness.html</a> which is an almost twin page except for a new hint.</p>
<p><strong>Hint 2:</strong> <em>maybe consider deltas.gz.</em></p>
<p>After retrieving <a href="http://www.pythonchallenge.com/pc/return/deltas.gz">deltas.gz</a>, we can go on with the script:</p>
<pre class="prettyprint">import gzip,difflib
deltas=gzip.GzipFile('deltas.gz', 'rb').read()
deltas=deltas.splitlines()
left,right,png=[],[],['','','']
for row in deltas:
    left.append(row[:53])
    right.append(row[56:])
diff = list(difflib.ndiff(left,right))

for row in diff:
    bytes = [chr(int(byte,16)) for byte in row[2:].split()]
    if row[0]=='-': png[0]+=''.join(bytes)
    elif row[0]=='+': png[1]+=''.join(bytes)
    elif row[0]==' ': png[2]+=''.join(bytes)

for i in range(3):
    open('18_%d.png' %i,'wb').write(png[i])</pre>
<p>The images created show the following texts:</p>
<blockquote><p>18_0.png: fly<br />
18_1.png: butter<br />
18_2.png: ../hex/bin.html</p></blockquote>
<p>That&#8217;s that. As allways, once you figure out the module you should be using makes the solution pretty straight forward. <a title="Solution to level 19" href="http://unixwars.com/2007/09/25/python-challenge-level-19-please/">Level  19</a> is next.</p>
]]></content:encoded>
			<wfw:commentRss>http://unixwars.com/2007/09/24/python-challenge-level-18-can-you-tell-the-difference/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python Challenge level 17: &#8220;eat?&#8221;</title>
		<link>http://unixwars.com/2007/09/23/python-challenge-level-17-eat/</link>
		<comments>http://unixwars.com/2007/09/23/python-challenge-level-17-eat/#comments</comments>
		<pubDate>Sun, 23 Sep 2007 21:27:15 +0000</pubDate>
		<dc:creator>Taher Shihadeh</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[python challenge]]></category>

		<guid isPermaLink="false">http://unixwars.com/2007/09/23/python-challenge-level-17-eat/</guid>
		<description><![CDATA[Level 17 is cookie related, so urllib usage is needed once again. Hint 1: cookies in the photo. Unambiguous! Hint 2: there&#8217;s a thumbnail of the image from level 4 So, we&#8217;ll have to investiagate the http headers. Interestingly, we find out something in level 4. Fact 1: &#8220;info=you+should+have+followed+busynothing&#8230;;&#8221; is a cookie set by level [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.pythonchallenge.com/pc/return/romance.html">Level 17</a> is cookie related, so urllib usage is needed once again.</p>
<p><strong>Hint 1:</strong> cookies in the photo. Unambiguous!<br />
<strong>Hint 2:</strong> there&#8217;s a thumbnail of the image from level 4</p>
<p>So, we&#8217;ll have to investiagate the http headers. Interestingly, we find out something in level 4.</p>
<p><strong>Fact 1:</strong> &#8220;<em>info=you+should+have+followed+busynothing&#8230;;&#8221;</em> is a cookie set by level 4.<br />
<strong>Fact 2:</strong> busynothing is another linkedlist, and has a chinging cookie!<br />
<strong>Fact 3:</strong> once obtained every piece, the info seems to be a quote_plus string from a BZ2 chunk of data</p>
<p>The code for this part of the riddle would be:</p>
<pre class="prettyprint">import urllib,re,bz2
url='http://www.pythonchallenge.com/pc/def/linkedlist.php?busynothing='
seed="12345"
info=''
while True:
    req=urllib.urlopen(url+seed)
    text=req.read()
    seed=''.join(re.findall(r"busynothing is (\d+)",text))
    cookies=req.info().getheaders('Set-Cookie')[0]
    byte=cookies.split(';')[0].split('=')[1]
    info+=byte
    try :
        int(seed)
        print "   Info:",byte,"t   Next:",seed
    except :
        print "   Info:",byte,"t   Last:",text
        break
print "info:",bz2.decompress(urllib.unquote_plus(info))</pre>
<blockquote><p>is it the 26th already? call his father and inform him that &#8220;the flowers are on their way&#8221;. he&#8217;ll understand.</p></blockquote>
<p>This one is intricate. Lets use level 13&#8242;s phonebook to find Mozart&#8217;s father&#8217;s phone. His name was<a href="http://en.wikipedia.org/wiki/Leopold_Mozart"> Leopold</a> by the way:</p>
<blockquote><p>violin</p></blockquote>
<p>From <a href="http://www.pythonchallenge.com/pc/return/violin.html">there</a> to <a href="http://www.pythonchallenge.com/pc/stuff/violin.php">here</a>, and stuck again. The only hint now is the page title: <em>&#8220;it&#8217;s me. what do you want?&#8221;</em><br />
Now it&#8217;s time to give him the message. After some trial and error and no RPC errors seen, setting a cookie with the message will show itself as the way to go.</p>
<pre class="prettyprint">from urllib2 import Request,urlopen
from urllib import quote_plus
info='the flowers are on their way'
url='http://www.pythonchallenge.com/pc/stuff/violin.php'
req = Request(url, headers={'Cookie': 'info=' + quote_plus(info)})
print urlopen(req).read()</pre>
<blockquote><p>oh well, don&#8217;t you dare to forget the balloons</p></blockquote>
<p>Balloons! Finally <a title="Solution to level 18" href="http://unixwars.com/2007/09/24/python-challenge-level-18-can-you-tell-the-difference/">Level 18</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://unixwars.com/2007/09/23/python-challenge-level-17-eat/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Python Challenge level 16: &#8220;let me get this straight&#8221;</title>
		<link>http://unixwars.com/2007/09/22/python-challenge-level-16-let-me-get-this-straight/</link>
		<comments>http://unixwars.com/2007/09/22/python-challenge-level-16-let-me-get-this-straight/#comments</comments>
		<pubDate>Sat, 22 Sep 2007 21:24:08 +0000</pubDate>
		<dc:creator>Taher Shihadeh</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[python challenge]]></category>

		<guid isPermaLink="false">http://unixwars.com/2007/09/22/python-challenge-level-16-let-me-get-this-straight/</guid>
		<description><![CDATA[In level 16 the title says everything. Hint 1: there are 5 pink pixels in each row Fact 1: pink is color 195 in the image&#8217;s color index (says The Gimp). import urllib, Image,cStringIO def straighten(line): # five equal consecutive pink pixels are the clue idx=0 while line[idx]!=195: idx+=1 return line[idx:]+line[:idx] url = 'http://huge:file@www.pythonchallenge.com/pc/return/mozart.gif' im [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://www.pythonchallenge.com/pc/return/mozart.html">level 16</a> the title says everything.</p>
<p><strong>Hint 1:</strong> there are 5 pink pixels in each row<br />
<strong>Fact 1:</strong> pink is color 195 in the image&#8217;s color index (says <a title="The GNU Image Manipulation Program" href="http://www.gimp.org/">The Gimp</a>).</p>
<pre class="prettyprint">import urllib, Image,cStringIO
def straighten(line): # five equal consecutive pink pixels are the clue
    idx=0
    while line[idx]!=195:
        idx+=1
    return line[idx:]+line[:idx]

url = 'http://huge:file@www.pythonchallenge.com/pc/return/mozart.gif'
im = Image.open(cStringIO.StringIO(urllib.urlopen(url).read()))
for y in range(im.size[1]):
    line=[im.getpixel((x, y)) for x in range(im.size[0])]
    line=straighten(line)
    [im.putpixel((x, y),line[x]) for x in range(len(line))]
im.save('16.gif')</pre>
<p>We don&#8217;t really need &#8220;<strong>Fact 1</strong>&#8221; to solve this problem, but it simplifies the code a bit. Instead of looking for pink pixels my first version looked for five equal pixels, but the result was slightly distorted in the lines where the level number is drawn.</p>
<p>The resulting image shows the word &#8220;romance&#8221;, and that&#8217;s where <a href="http://unixwars.com/2007/09/23/python-challenge-level-17-eat/">Level 17</a> awaits. I must say number 17 looks good. The most promising I&#8217;ve seen until now, and I&#8217;ve loved almost every single one of them. We&#8217;ll see if it can be as easily solved as this one.</p>
]]></content:encoded>
			<wfw:commentRss>http://unixwars.com/2007/09/22/python-challenge-level-16-let-me-get-this-straight/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python Challenge level 15: &#8220;whom?&#8221;</title>
		<link>http://unixwars.com/2007/09/21/python-challenge-level-15-whom/</link>
		<comments>http://unixwars.com/2007/09/21/python-challenge-level-15-whom/#comments</comments>
		<pubDate>Fri, 21 Sep 2007 21:22:23 +0000</pubDate>
		<dc:creator>Taher Shihadeh</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[python challenge]]></category>

		<guid isPermaLink="false">http://unixwars.com/2007/09/21/python-challenge-level-15-whom/</guid>
		<description><![CDATA[Level 15. I didn&#8217;t like this one. Not a bit. I think it&#8217;s the only level not as well designed as the rest. At least up untill now. Either that or my mindset doesn&#8217;t like some types of riddle as much as the rest. We are given a date in a callendar and a couple [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.pythonchallenge.com/pc/return/uzi.html">Level 15</a>. I didn&#8217;t like this one. Not a bit. I think it&#8217;s the only level not as well designed as the rest. At least up untill now. Either that or my mindset doesn&#8217;t like some types of riddle as much as the rest. We are given a date in a callendar and a couple of hints.</p>
<p><strong>Hint 1:</strong> <em>he ain&#8217;t the youngest, he is the second</em><br />
<strong>Hint 2:</strong> <em>todo: buy flowers for tomorrow</em><br />
<strong>Hint 3:</strong> whoever it is has something to do with a leap year, between 1006 and 1996 in which Jan 26 was Monday</p>
<p>I could easily generate some dates with the appropiate constraints, but the problem didn&#8217;t seem narrower. I had to read the forums for ideas. At first I was tricked by the image because it seemed to have just one digit missing in the year. I believe this was intentional. The hint about the flowers could mean many things: a death, a marriage, a birth&#8230;<br />
So to the forums it is. These are excellent by the way, although by the absence of recent posts I think I&#8217;m tha last guy on Earth playing the game. Everybody seems to have finished long ago. The threads are classified by challenge level, no spoilers are allowed and there&#8217;s a lot of valuable hints. After reading the forums, I got some things straight.</p>
<p><strong>Fact 1:</strong> the year is between 1006 and 1996. This narrows the thing a lot.<br />
<strong>Fact 2:</strong> birth day is Jan 27. Better go to Wikipedia to get a list of events that happened that day.</p>
<pre class="prettyprint">#!/usr/bin/env python
import datetime,calendar
for year in range(1006,1996,10):
    d=datetime.date(year, 1, 26)
    if d.isoweekday() == 1 &amp; calendar.isleap(year):
        print d</pre>
<blockquote><p>1176-01-26<br />
1356-01-26<br />
1576-01-26<br />
1756-01-26<br />
1976-01-26</p></blockquote>
<p>The second youngest would have been born on 1756. Since it&#8217;s the next day, 1756-01-27. After going to <a href="http://en.wikipedia.org/wiki/January_27">Wikipedia</a> there is finally an answer, Mozart. And that&#8217;s that. Im glad it&#8217;s over. Now to <a title="Solution to level 16" href="http://unixwars.com/2007/09/22/python-challenge-level-16-let-me-get-this-straight/">Level 16</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://unixwars.com/2007/09/21/python-challenge-level-15-whom/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Python Challenge level 14: &#8220;walk around&#8221;</title>
		<link>http://unixwars.com/2007/09/20/python-challenge-level-14-walk-around/</link>
		<comments>http://unixwars.com/2007/09/20/python-challenge-level-14-walk-around/#comments</comments>
		<pubDate>Thu, 20 Sep 2007 21:20:51 +0000</pubDate>
		<dc:creator>Taher Shihadeh</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[python challenge]]></category>

		<guid isPermaLink="false">http://unixwars.com/2007/09/20/python-challenge-level-14-walk-around/</guid>
		<description><![CDATA[Level 14 is really short once again. Hint 1: image is a spiral. It&#8217;s direction could be meaningful Hint 2: remember: 100*100 = (100+99+99+98) + &#8230;. (3+2+2+1)+1 Fact 1: wire.jpg is 1&#215;10000 pixels = 100*100 I especially liked this level because it was straight forward. You didn&#8217;t have to imagine obscure meanings hidden in the [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://huge:file@www.pythonchallenge.com/pc/return/italy.html">Level 14</a> is really short once again.</p>
<p><strong>Hint 1:</strong> image is a spiral. It&#8217;s direction could be meaningful<br />
<strong>Hint 2:</strong> <em>remember: 100*100 = (100+99+99+98) + &#8230;. (3+2+2+1)+1</em><br />
<strong>Fact 1:</strong> wire.jpg is 1&#215;10000 pixels = 100*100</p>
<p>I especially liked this level because it was straight forward. You didn&#8217;t have to imagine obscure meanings hidden in the hints. The wire.jpg is so streched that it resembles a barcode, so you can automatically know that there is something encoded somehow. Also the 100*100 sequence hint, and the 100*100 pixels couldn&#8217;t be clearer. I think it is the first level I solved in under 5 minutes since the easy ones at the beginning of the game.</p>
<pre class="prettyprint">#!/usr/bin/env python
import Image
im = Image.open("wire.png")
new = Image.new(im.mode,[100,100])
doubled_steps=200
directions=[(1,0), (0,1), (-1,0), (0,-1)] # vectors in [x,y] format
x,y,p=-1,0,0
while doubled_steps//2 > 0:
    for v in directions: # we will be taking steps in 4 directions
        steps=doubled_steps//2
        for s in range(steps):
            x,y=x+v[0],y+v[1]
            new.putpixel((x,y),im.getpixel((p,0)))
            p+=1
        doubled_steps-=1
new.save('14.jpg')</pre>
<p>It&#8217;s a cat.  We&#8217;ll learn its name in <a href="http://www.pythonchallenge.com/pc/return/cat.html">cat.html</a> as well as the place to go if we&#8217;re looking for<a href="http://unixwars.com/2007/09/21/python-challenge-level-15-whom/"> Level 15</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://unixwars.com/2007/09/20/python-challenge-level-14-walk-around/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

