はてブロ@ama_ch

https://twitter.com/ama_ch

Python Challenge Level4

※ネタバレ有り

問題

前回の答えより、
http://www.pythonchallenge.com/pc/def/linkedlist.html
へアクセスすると、

linkedlist.php

とだけ書いてあるので、拡張子をphpに書き換えてみます。
http://www.pythonchallenge.com/pc/def/linkedlist.php
問題のページにたどり着きました。

考え方

今回は説明がありませんね。その代わり画像がリンクになっているのでクリック。

and the next nothing is 92512

http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing=12345

とだけ書かれたページが表示されます。
この数字はアドレスの最後の部分ぽいですね。試しに入力してみましょう。

and the next nothing is 64505

http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing=92512

やっぱりそうみたいです。これを追っていくコードをPythonで書くという問題のようです!

回答

#!/usr/bin/env python
#! -*- coding: utf-8 -*-
""" level 4
http://www.pythonchallenge.com/pc/def/linkedlist.php
"""
import re
import urllib

def urlchain(url, num):
    src = urllib.urlopen(url+num).read()
    print src
    number = re.findall("[0-9]+", src)
    if number:
        urlchain(url, number[0])

if __name__ == "__main__":
    number = "12345"
    url = "http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing="
    urlchain(url, number)

実行結果

$ python level4.py
and the next nothing is 92512
and the next nothing is 64505
<font color=red>Your hands are getting tired </font>and the next nothing is 50010
and the next nothing is 29193
and the next nothing is 89924
and the next nothing is 65471
and the next nothing is 69977
and the next nothing is 6306
and the next nothing is 16460
and the next nothing is 15222
and the next nothing is 48564
and the next nothing is 7359
and the next nothing is 53915
and the next nothing is 26258
and the next nothing is 55683
and the next nothing is 37852
and the next nothing is 61066
There maybe misleading numbers in the 
text. One example is 61067. Look only for the next nothing and the next nothing is 53522
You've been misleaded to here. Go to previous 
one and check.

あれ、失敗だ。


えーと、61066の時、

There maybe misleading numbers in the text. One example is 61067. Look only for the next nothing and the next nothing is 53522

こう表示されていて、最初の61067に行くと間違いみたい。
このコードだとre.findallで見つけた数値列の最初の値を次のアドレスにしているから間違ったのか。


正規表現で見つけた最後の値を次のアドレスにしてみた

#!/usr/bin/env python
#! -*- coding: utf-8 -*-
""" level 4
http://www.pythonchallenge.com/pc/def/linkedlist.php
"""
import re
import urllib

def urlchain(url, num):
    src = urllib.urlopen(url+num).read()
    print src
    number = re.findall("[0-9]+", src)
    if number:
        urlchain(url, number[-1])  # ここだけ0から-1に変えた

if __name__ == "__main__":
    number = "12345"
    url = "http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing="
    urlchain(url, number)

実行結果

$ python level4.py
and the next nothing is 92512
and the next nothing is 64505
<font color=red>Your hands are getting tired </font>and the next nothing is 50010
and the next nothing is 29193
--- 中略 ---
and the next nothing is 19337
and the next nothing is 21122
and the next nothing is 92118
Yes. Divide by two and keep going.

200個ほどURLを追いかけ、最後に何か言われました。
「2で割って続けなさい」か、コードのnumber = "12345"をnumber = "46059"に書き換えて再開。

$ python level4.py
and the next nothing is 33110
and the next nothing is 17675
and the next nothing is 8511
and the next nothing is 89456
and the next nothing is 43502
and the next nothing is 45605
and the next nothing is 12970
and the next nothing is 91060
and the next nothing is 27719
and the next nothing is 65667
peak.html

無事に答えまでたどり着きました!

感想

"Yes. Divide by two and keep going."と表示された時、これが何回も出てくるならこれをコードで処理するしかないのか*1と心配していたんですが1回きりで助かりました。
あと、ページのソースも見やすいようにタグなど殆どなかったので、親切な問題だったと思います。多分、最初の方の「You are tired」のとこも、フォントカラーの設定でカラーコードを使わないようにしてくれてたんだと思います!

*1:単語と数字を認識して演算するの?メンドクセー!