Python Challenge(7)

続いてレベル7
特にヒントとか無いので、画像の灰色の部分をデコードすると文章になるんだろう。
PILは3.0対応してないようなので今回は2.6で。

といっても灰色の部分を抜粋するとか、どうやんのか分からないので色々ググってみると、

RGB (128, 128, 128)

灰色 - Wikipedia

とあるので、更にググる

それぞれ色を同じ値にすると、黒または灰色になります。

http://www.coara.or.jp/~ynakamra/iro/rgbcolor.html

これでできそう。

http://www.panopticon.jp/blog/2008/02/160859.htmlによると、Image#getdata()でRGB値のリストを取得できる。

>>> im = Image.open('oxygen.png')
>>> list(im.getdata())
[(79, 92, 23, 255), (72, 87, 18, 255), (61, 77, 6, 255), (55, 70, 3, 255), (58, 69, 9, 255), (40, 48, 1, 255),
...
, (106, 117, 57, 255), (92, 99, 47, 255), (100, 104, 53, 255), (100, 101, 44, 255), (106, 105, 48, 255)]

タプルの要素が4つなのはRGBAだから。

>>> im.mode
'RGBA'

全部使う必要はないのでImage#load()を使うと、

#coding:utf-8
import Image

im = Image.open('oxygen.png')
x = 0
y = 0
pixels = im.load()
ans = []

while True:
    r, g, b, a = pixels[x, y]
    if (r == g == b):
        break
    else:
        y = y + 1

ans_value = 0
while True:
    try:
        r, g, b, a = pixels[x, y]
        #同じボックスの値を除外
        if (r == g == b) and (r != ans_value):
            ans_value = r
            ans.append(chr(ans_value))
        x = x + 1
    except IndexError:
        break

print(''.join(ans))
$ python challenge07.py
smart guy, you made it. the next level is [105, 10, 16, 101, 103, 14, 105, 16, 121]
$ python
>>> ''.join([chr(c) for c in [105, 10, 16, 101, 103, 14, 105, 16, 121]])
'i\n\x10eg\x0ei\x10y'

間違っているみたいなので、2番目のループでRGB値をprintしてみると、

...
(44, 44, 44)
(44, 44, 44)
(32, 32, 32)
(32, 32, 32)
(32, 32, 32)
(32, 32, 32)
(32, 32, 32)
(32, 32, 32)
(32, 32, 32)
(49, 49, 49)
(49, 49, 49)
(49, 49, 49)
(49, 49, 49)
(49, 49, 49)
(49, 49, 49)
(49, 49, 49)
(49, 49, 49)
(49, 49, 49)
(49, 49, 49)
(49, 49, 49)
(49, 49, 49)
(49, 49, 49)
(49, 49, 49)
(54, 54, 54)
(54, 54, 54)
...

隣り合ったブロックでも同じ色があるみたいなので修正。
ブロックの長さは↑によると7らしいので、

import Image

im = Image.open('oxygen.png')
x = 0
y = 0
pixels = im.load()
ans = []
BLOCK_WIDTH = 7

while True:
    r, g, b, a = pixels[x, y]
    if (r == g == b):
        break
    else:
        y = y + 1

while True:
    try:
        r, g, b, a = pixels[x, y]
        if (r == g == b):
            ans.append(chr(r))
        x = x + BLOCK_WIDTH
    except IndexError:
        break

print(''.join(ans))
$ python challenge07.py
smart guy, you made it. the next level is [105, 110, 116, 101, 103, 114, 105, 116, 121]
$ python
>>> ''.join([chr(c) for c in [105, 110, 116, 101, 103, 114, 105, 116, 121]])
'integrity'