0%

Python Challenge (Level 14)

第14关
一个螺旋状的面包,网页title是walk around, 再加上大图的下面有一张100*100的小图。小图看不出是什么东西,只有竖条纹。把小图保存到本地,放大后发现很长的一条线,也就是说它并不是100*100的,而是10000*1的。只是在网页上被reshape成100*100而已。看来我们需要将这10000个像素,按照面包螺旋的形状,把它重新排列成100*100的大小。

比如[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]排列成

1  12  11  10
2  13  16   9
3  14  15   8
4   5   6   7

现在的问题就是怎么把得到的一列pixel,按螺旋形式reshape成100*100大小的图片。

Page Source里有这么一行提示

remember: 100*100 = (100+99+99+98) + (…

100*100自然就是图片大小了,那后面的一串数是什么?为什么四个一组?原来。四个数正好是转一圈的步数。(100, 99, 99, 98)就是向下100, 再向右99, 再向上99, 再向左98. 这就绕了100*100大小的最外面一圈. 接着就是(98, 97, 97, 96),以此类推,直到填满整个100*100的大小。很容易可以得到所有的步数。

1
allSteps = [[i, i-1, i-1, i-2] for i in range(100, 0, -2)]

有了步数后,再定义一个前进N步,获取坐标的方法,就基本可以实现把一行pixel变成方形图片了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# -*- coding:utf-8 -*- 

from PIL import Image

def moveForward(startPos, direction, nStep):
""" 返回从startPos开始, 按照drection前进nStep依次得到的坐标,
包含startPos.

:type startPos: (int, int)
:param startPos: 开始坐标, (x, y)

:type direction: (int, int)
:param direction: 前进方向, 每个方向的取值只能为-1, 0, 1,
分别表示坐标减小、不变、增加。
不同的组合可以得到上下左右四个方向, 例如(0, 1)表示向右。

:type nStep: int
:param nStep: 前进步数, >=0
"""
pos = [None, None]
for i in range(len(startPos)):
if direction[i] == 0:
pos[i] = [startPos[i]] * nStep
elif direction[i] < 0:
pos[i] = range(startPos[i], startPos[i] - nStep, direction[i])
else:
pos[i] = range(startPos[i], startPos[i] + nStep, direction[i])
return zip(pos[0], pos[1])

def getPos(allSteps):
""" 给定以4个整数为一组的多组步数, 返回从(0, 0)开始,
以此按下、右、上、左前进所得到的所有坐标

:type allSteps: 2D int array, the second dimension is 4
[[int, int, int, int], ..., [int, int, int, int]]
:param allSteps: 多组步数, 每一组都包含上下左右四个方向的步数.
"""
start_pos = (0, 0)
pos = []
for steps in allSteps:
# down
if pos:
start_pos = (pos[-1][0] + 1, pos[-1][1])
else:
start_pos = (0, 0)
pos += moveForward(start_pos, (1, 0), steps[0])

# right
start_pos = (pos[-1][0], pos[-1][1] + 1)
pos += moveForward(start_pos, (0, 1), steps[1])

# up
start_pos = (pos[-1][0] - 1, pos[-1][1])
pos += moveForward(start_pos, (-1, 0), steps[2])

# left
if steps[3] <= 0:
break
else:
start_pos = (pos[-1][0], pos[-1][1] - 1)
pos += moveForward(start_pos, (0, -1), steps[3])

return pos

def main():
im = Image.open('wire.png')
imdata = list(im.getdata())
allSteps = [[i, i-1, i-1, i-2] for i in range(100, 0, -2)]
pos = getPos(allSteps)
newIm = Image.new(im.mode, (100, 100))
for i in range(len(pos)):
newIm.putpixel(pos[i], imdata[i])
newIm.show()

if __name__ == "__main__" : main()

最后,会得到一张猫的图片,输入cat会跳到一个网页,告诉你这只猫叫做uzi,并且, you will hear from him later. http://www.pythonchallenge.com/pc/return/uzi.html