はてブロ@ama_ch

https://twitter.com/ama_ch

Python Challenge Level1

※ネタバレ有り


Pythonの入門書は読み終えたので、暇な時にThe Python Challengeをやっています。
Level1からのメモを・・・というか、解答に至るまでの流れを載せます。解答=次のレベルのURLなので、これから自力で解きたい方は見ない方がいいと思います。

問題

level0を2 ** 38でさっくりやっつけるとわかります。
http://www.pythonchallenge.com/pc/def/map.html

考え方

画像を見ると、アルファベットが2文字ずれてるみたい。
画像の下に

everybody thinks twice before solving this.

と書いてある。「みんなこれを解決する前に2回考えるよ」? よくわからない。
でもその下には

g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyrq ufyr amknsrcpq ypc dmp. bmgle gr gl zw fylb gq glcddgagclr ylb rfyr'q ufw rfgq rcvr gq qm jmle. sqgle qrpgle.kyicrpylq() gq pcamkkclbcb. lmu ynnjw ml rfc spj.

こんなにいかにも怪しい文字列がありますね。とりあえずこいつを画像通りに2個ずつずらしてみよう!

回答

その1

#!/usr/bin/env python
#! -*- coding: utf-8 -*-
""" level 1
http://www.pythonchallenge.com/pc/def/map.html
"""
import sys

str = "g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyrq ufyr amknsrcpq ypc dmp. bmgle gr gl zw fylb gq glcddgagclr ylb rfyr'q ufw rfgq rcvr gq qm jmle. sqgle qrpgle.kyicrpylq() gq pcamkkclbcb. lmu ynnjw ml rfc spj."

for i in range(len(str)):
    if str[i].isalpha():
        sys.stdout.write(chr(ord(str[i])+2))
    else:
        sys.stdout.write(str[i])
print ""

実行結果

i hope you didnt tr{nsl{te it |y h{nd. th{ts wh{t computers {re for. doing it in |y h{nd is inefficient {nd th{t's why this text is so long. using string.m{ketr{ns() is recommended. now {pply on the url.

ん、それっぽくなった?けど変な記号が沢山あるなぁ。どうやらアルファベットの範囲を飛び出してるみたいだ。
y→aとかにしないといけなさそう。


その2

#!/usr/bin/env python
#! -*- coding: utf-8 -*-
""" level 1
http://www.pythonchallenge.com/pc/def/map.html
"""
import sys

str = "g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyrq ufyr amknsrcpq ypc dmp. bmgle gr gl zw fylb gq glcddgagclr ylb rfyr'q ufw rfgq rcvr gq qm jmle. sqgle qrpgle.kyicrpylq() gq pcamkkclbcb. lmu ynnjw ml rfc spj."

for i in range(len(str)):
    if str[i].isalpha():
        num = ord(str[i]) + 2
        if num >= 123:
            num -= 26
        sys.stdout.write(chr(num))
    else:
        sys.stdout.write(str[i])
print ""

実行結果

i hope you didnt translate it by hand. thats what computers are for. doing it in by hand is inefficient and that's why this text is so long. using string.maketrans() is recommended. now apply on the url.

修正版。キャラクタコード+2した時にアルファベットの範囲を超えたら、26を引いてまたaから始まるようにしました。
なんかよさげですね!えーと、、
「手で変換することを望みません。コンピュータがやるべきことです。手でそれをやることは非効率だし、なぜテキストはこんなに長いのか。string.maketrans()を使うことが推奨されます。それではURLに当てはめてください。」
英語はあまり得意じゃないけど、こう解釈しました。
URL*1を同じように変換してあげれば次の問題に進めます。でもその前に、推奨されているstring.maketrans()で書き直してみました。


その3

#!/usr/bin/env python
#! -*- coding: utf-8 -*-
""" level 1
http://www.pythonchallenge.com/pc/def/map.html
"""
import sys

str = "g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyrq ufyr amknsrcpq ypc dmp. bmgle gr gl zw fylb gq glcddgagclr ylb rfyr'q ufw rfgq rcvr gq qm jmle. sqgle qrpgle.kyicrpylq() gq pcamkkclbcb. lmu ynnjw ml rfc spj."

s1 = "abcdefghijklmnopqrstuvwxyz"
s2 = "cdefghijklmnopqrstuvwxyzab"
t = string.maketrans(s1, s2)
print str.translate(t)

こんな感じでいいのかな?でもs1とs2をいちいち全部書くのはカッコ悪い気もする。

*1:***.htmlの***部分