玩python的同学,肯定都知道PythonChallenge这个游戏,既学习了python,又锻炼了智商。今天,我试试用clojure来解决里面的题目。具体的解题思路就省略了,主要谈谈怎么使用clojure。
Level 0: 2的38次方
卧槽,clojure.core里头怎么找不到求乘方的函数!?一开始就这么不顺。那就取个巧吧,谁让这个底数是2呢…
user=> (bit-shift-left 2 38)
549755813888
于是得到下一题的url。
Level 1: 一个简单的解码。
图片已经提示了,是ansic码加2,具体实现需要处理一下非字母表字符和一点边界情况。用map来得最直观:
(def data ".........")
(defn decodec 1
(cond
(not (Character/isLowerCase c)) c
(= c \y) \a
(= c \z) \b
:else (char (+ 2 (int c)))))
(apply str (map decodec data))
Level 2: 找字母
页面源代码中给出了一大坨乱码,并且提示说找出其中的字母,很简单,上filter:
(def data "………")
(apply str (filter #(Character/isLetter %) data))
得到”equality”,进入下一题
Level 3: 找特定字母组合
页面中同样给出一大坨字母,提示很明显了,找出左右被3个大写字母包围的小写字母。这种情况正则处理比较合适,比如re-seq
(def data "………")
(->> (re-seq #"[a-z][A-Z][A-Z][A-Z][a-z][A-Z][A-Z][A-Z][a-z]" data)
(map #(nth % 4))
(apply str))
re-seq返回所有匹配的串,详见clojuredocs: re-seq。
我们得到下一题的链接:linkedlist
Level 4: Follow Web Link
很有意思,大意是要根据页面的提示,跳转到另外一个页面,一直follow到最终的页面。我们需要做两件事情
获取页面推荐使用reader + line-seq的组合。reader函数返回一个java.io.BufferedReader,支持从文件名,String,URL,InputStream,Socket,byte array等方式构造,相当的帅啊!line-seq则是从java.io.BufferedReader返回一个按照换行符切分的字符串lazy sequence。这俩基本上算绝配。剩下的事情就是写个循环了….
(defn get-list [start]
(loop [n start]
(let [url (str "http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing=" n)
data (first (line-seq (clojure.java.io/reader url)))
target (re-seq #"\d+" data)]
(println url data target)
(recur (first target)))))
从”12345″开始,
(get-list "12345")
按照中间的提示:
; 16044 divided by 2
(get-list "8022")
最后进入下一关:peak
Level 5:python反序列化
这个有点坑爹了….完全python的语言特性,你让哥怎么搞!你让哥怎么搞!!
怎么搞?当然用python搞了!
这里使用一个小trick,通过shell调用python,然后….不说了,太猥琐了,上代码吧
(require '1)
(def stdin "import urllib,pickle
obj=pickle.load(urllib.urlopen(\"http://www.pythonchallenge.com/pc/def/banner.p\"))
for line in obj:
print \"\".join(map(lambda pair: pair[0]*pair[1], line))")
(println (:out (sh "python" :in stdin)))
你能在终端上看到答案的….
啥时候试试clojure-py…应该能有不那么猥琐的解决方法..
p.s. 欢迎访问纯爷们的小生活
p.s.s. 原文地址:http://chunyemen.org/archives/769
近期评论