前面关卡的解题报告在这里http://blog.csdn.net/richytang/article/details/12249507(第2-3关)
第4关:http://www.pythonchallenge.com/pc/def/linkedlist.php
这关的名字叫做follow the chain。关名往往时能提供很多帮助的。关卡只有一张图片,结果发现图片是能点击的。网页的源代码中的注释有点提示:使用urllib,还有不要手动尝试。回头看点击图片后跳转的网页,过关的方法呼之欲出了,用网页给出的nothing值换掉url中的nothing。代码如下:
import urllib.request,re
p = re.compile(r'the next nothing is ([0-9]+)')
nothing = '12345'
url = 'http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing='+nothing
while True:
response = urllib.request.urlopen(url)
html = response.read().decode('utf-8')
nothing = p.search(html).group(1)
print(nothing)
if nothing==None:
print('you need to check manually')
break
url = 'http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing='+nothing
上面的代码中的提示就可以看出来点东西。当程序运行到某一个节点时,就会提示需要手动check,然后回到程序中修改nothing的初始值。
这个版本的程序当然不是一遍就好的,经历了两次“试错”的过程。找出端倪之后调整。这里提一句,我用的是正则提取。另外也可以直接将字符串以空格分隔,然后按位置-1索引。但是游戏设计者也设计了一个陷阱,就是最后一个页面只有peak.html字样,将这个字样作为nothing的值竟然还可以继续跳转下去。。。所以第4关是处处陷阱啊(中间还有一个页面要你除2,另一个页面给了两个值混淆你,这也是我将正则完整地包含”the next...“字样的缘故)。看了一下解题报告,发现中间都需要手动check,没什么更好的解法了。好了,下一关吧~
第5关:http://www.pythonchallenge.com/pc/def/peak.html
关卡一看有种不太好的感觉。一个是题目:peak hell;另一个pronounce it;源代码中有一句话peak hell sound familiar?;源代码中给了一个banner.p文件。线索就是这些。
想啊想啊想,源代码那句话是关键。peak hell发音很想python里的一个模块:pickle(这也行?)。那么这个模块是干什么的呢?学习一下pickle模块,官方文档还有一个很推荐快速学习python3的地方。这个模块是处理序列化二进制串的东西。那么处理的应该就是banner.p文件了吧。把文件保存下来,然后我们就可以处理了。先看一下文件打开后是什么吧:
import pickle
with open('banner.p','rb') as fp:
print(pickle.load(fp))
结果是: [[(' ', 95)], [(' ', 14), ('#', 5), (' ', 70), ('#', 5), (' ', 1)], [(' ', 15), ('#', 4), (' ', 71), ('#', 4), (' ', 1)], [(' ', 15), ('#', 4), (' ', 71), ('#', 4), (' ', 1)],...等一堆令人迷糊的东西。
这是什么呢?下面就是分析这堆东西了。首先,这是一个列表(list)。那么继续下去,它的每一个元素是什么,元素类型是什么?我们看下面的结果:
>>> type(t)
<class 'list'>
>>> t[0]
[(' ', 95)]
>>> type(t[0])
<class 'list'>
>>> t[1]
[(' ', 14), ('#', 5), (' ', 70), ('#', 5), (' ', 1)]
>>> t[1][0]
(' ', 14)
>>> type(t[1][0])
<class 'tuple'>
发现了点什么,最后是一个tuple组。每一个tuple都是一个字符跟着一个数。好吧,下面天马行空地想,寻找一下运气。于是让我碰到了,便有了下面这个程序:
import pickle
with open('banner.p','rb') as fp:
t = pickle.load(fp)
for item in t:
for tu in item:
print(tu[0]*tu[1],end = "")
然后遇到一个很有喜感的问题,打出来的东西我看不懂,后来不断地调窗口大小调出来了:
好吧,其实可以将输出重定向到文件里(py3k可以在print里指明file参数重定向),然后打开一看,就好了...后来不甘心,感觉从解法到输出都一点也不pythonic。于是在网上查到了一个很帅气的解法,我这个弱菜只有膜拜之:
import pickle
with open('banner.p','rb') as fp:
t = pickle.load(fp)
for item in t:
print(''.join([x[0] * x[1] for x in item]))
高大上了。还有更帅气的,load函数之后,两个列表解析一起:
print(''.join(["".join([i[0]*i[1] for i in b]) for b in t]))
好吧,下一关就是
http://www.pythonchallenge.com/pc/def/channel.html