肥嘟嘟(Fatbobman)的学习笔记Rss Feed

上学的时候懒不愿意做笔记,但确实了解笔记的重要性。现在想做笔记了,但是还是懒,当然对于重要性的认识丝毫没有动摇。

2005/11/29

Python Challenge 答案 (6-10)

[http://www.pythonchallenge.com/]

The Python Challenge

第6题: zip 模块
title提示是一对。
源代码中出现〈!-- 〈-- zip --〉字样
从http://www.pythonchallenge.com/pc/def/channel.zip 下载zip文件
(提示够变态吧)
打开zip文件中的readme.txt 可以看到
welcome to my zipped list.

hint1: start from 90052
hint2: answer is inside the zip
感觉解题思路基本上和上面那个反复调用url的题一样
r=re.compile(r'(\d+)$')
nextnothing='90052'

while(1):
try:
f=open('./python challenge/%s.txt' % nextnothing)
result=f.read()
f.close()
print result
oldnextnothing=nextnothing
nextnothing=r.search(result).group()
except:
break

执行后最后显示
collect the comments

有点昏吧,哪里来的comments。其实就在zip文件里。这道题最后还是需要用zip模块来完成
import re
r=re.compile(r'(\d+)$')

import zipfile
comment=[]
nextnothing='90052'
f=zipfile.ZipFile('./python challenge/channel.zip')
while(1):
try:
comment.append(f.getinfo('%s.txt' % nextnothing).comment)
nextnothing=r.search(f.read('%s.txt' % nextnothing)).group()
except:
print ''.join(comment)
break

运行屏幕显示一个由字符组成的图片,可以看出图案是HOCKEY
进入http://www.pythonchallenge.com/pc/def/hockey.html
什么?还没结束!
上面显示it's in the air. look at the letters.
此时,再次注意观察前面出现的hockey图片发现,每个字母的图案都是由一个单独的字母组成,得到最终答案oxygey
下题入口http://www.pythonchallenge.com/pc/def/oxygen.html

第7题: pil出场。颜色拾取
屏幕上显示一幅图,图片的中间部分是由规律的灰度块组成。猜测信息应该是由这些灰度提供。
通过gimp进一步分析可获得整个区域灰度块长度为608,除第一小块外,其他间隔都是7个象素点。也就是说每隔7个点可以获得一个颜色数据。由于图片是彩色的(RGBA模式),而只有灰度的颜色数据应该是255级以内,推测可能会是ascii。

import Image
im = Image.open('./python challenge/oxygen.png')
ilist = im.convert('L').getdata() #将色彩转换为灰度,这样只获得一个值
result=[]
for i in range(0,608,7):
result.append(chr(ilist[im.size[0]*50+i]))
print ''.join(result)

果然,运行程序显示:smart guy, you made it. the next level is [105, 110, 116,
101, 103, 114, 105, 116, 121]
再次处理可得到答案
hint=[105, 110, 116, 101, 103, 114, 105, 116, 121]
answer=[]
for c in hint:
answer.append(chr(c))
print ''.join(answer)

最终答案:integrity
下题入口:http://www.pythonchallenge.com/pc/def/integrity.html

第8题:bz2解码
屏幕显示一个蜜蜂图片。查看页面源代码可以看到里面提示有加过密的用户名、密码。
点击蜜蜂可进入一个需要输入口令的页面,说明此题应该就是解开用户名、密码
说实话,这道题我始终没有找到破解加密算法的思路,直到看到网上有人说google以下BZh91AY。这个字符串时用户名和密码最开始相同的部分。google后可以看到介绍python
bz2模块,得到解题思路。
import bz2

un = 'BZh91AY&SYA\xaf\x82\r\x00\x00\x01\x01\x80\x02\xc0\x02\x00
\x00!\x9ah3M\x07<]\xc9\x14\xe1BA\x06\xbe\x084'
pw = 'BZh91AY&SY\x94$|\x0e\x00\x00\x00\x81\x00\x03$
\x00!\x9ah3M\x13<]\xc9\x14\xe1BBP\x91\xf08'

un=bz2.decompress(un)
pw=bz2.decompress(pw)

print un
print pw

运行得到答案
huge
file
登录即可进入下题

下题入口http://www.pythonchallenge.com/pc/return/good.html

第9题:pil再度出马,描点
屏幕上显示一幅风景画,上面有很多小黑点。
title提示,连接点
page source中可以看到两组数据 first second 并提示 first+second=?
起初我真的在gimp上把图片上面的点用画笔描了起来,看看是否有什么提示,不过一无所获。
后来观察first和second的数据,发现其值均在该图片的x,y size之内,并且两组数据的个数都为偶数,获得灵感是否是坐标数据
import Image
first=[
146,399,163,403,170,393,... snip]
second=[
156,141,165,135,169,...snip]
im=Image.open('./python challenge/good.jpg')
f=[]
for i in range(0,len(first),2):
f.append((first[i],first[i+1]))
print f
for xy in f:
im.putpixel(xy,(255,0,0))

f=[]
for i in range(0,len(second),2):
f.append((second[i],second[i+1]))
print f
for xy in f:
im.putpixel(xy,(255,0,0))
im.show()

呵呵,可以隐约在图片上面由红色的点组成了一头牛的图案。
first是外缘轮廓,second是头的轮廓
赶紧进入http://www.pythonchallenge.com/pc/return/cow.html
结果发现提示hmm. it's a male.
唉,分得还挺细。。
得到最后结果:bull

下题入口:http://www.pythonchallenge.com/pc/return/bull.html

第10题: 数字列表
屏幕下方提示 :len(a[30]) = ?
点击图片可获得数据:
a = [1, 11, 21, 1211, 111221,
知道应该是根据这个提示找出规律,扩充列表获得答案。
不过规律何在?解此题。。。。耗时超过2小时。。。。主要是笨呀。
最后终于明白值之间的规律。就是每个值都是对前一个值得文字描述。
什么?文字描述,不错,念起来就知道了
比如说第一个是 1
第二个就是 1个1 (11)
第三个就是 2个1 (21)
第4个就是 1个2 1个1 (1211)
第5个就使 1个1 1个2 2个1 (111221)
一次类推。。。。说实话,开始总是想数字之间是否有什么数学运算上的关系,所以总也推算不出。

olda = [1, 11, 21, 1211, 111221]

def _index(c,list):
for i in range(len(list)):
if list[i]!=c:
return i
return -1

while len(olda)<31:
result=''
resultlist=[]
a=str(olda[-1])
while len(a)>0:
firstdiffindex = _index(a[0],a[1:])
if firstdiffindex==-1:
resultlist.append(a)
break
else:
resultlist.append(a[0:firstdiffindex+1])
a=a[firstdiffindex+1:]
for l in resultlist:
result +=str(len(l))+str(l[0])

olda.append(int(result))

print len(str(olda[30]))

得到答案:5808
下题入口:http://www.pythonchallenge.com/pc/return/5808.html

--
Posted by fatbobman to 肥嘟嘟的闲言碎语 at 11/29/2005 01:58:15 下午

2 Comments:

At 9:28 下午, Blogger fatbobman said...

第10题用正则解,很简单

x="1"
for each in range(30):
x="".join([str(len(i+j))+i for i,j in re.findall(r"(\d)(\1*)", x)])
print len(x)

 
At 3:44 下午, Blogger 黄毅 said...

楼主这样可不太好啊, 你得为那些没过关的兄弟考虑啊, 你把答案贴出来,那其他人玩得有啥意思啊.

 

发表评论

<< Home