Created
December 13, 2012 14:56
-
-
Save bouzuya/4276901 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;; Project Euler #8 | |
;;; http://projecteuler.net/problem=8 | |
;;; http://odz.sakura.ne.jp/projecteuler/index.php?cmd=read&page=Problem%208 | |
(use 'clojure.test) | |
(def input | |
(str | |
"73167176531330624919225119674426574742355349194934" | |
"96983520312774506326239578318016984801869478851843" | |
"85861560789112949495459501737958331952853208805511" | |
"12540698747158523863050715693290963295227443043557" | |
"66896648950445244523161731856403098711121722383113" | |
"62229893423380308135336276614282806444486645238749" | |
"30358907296290491560440772390713810515859307960866" | |
"70172427121883998797908792274921901699720888093776" | |
"65727333001053367881220235421809751254540594752243" | |
"52584907711670556013604839586446706324415722155397" | |
"53697817977846174064955149290862569321978468622482" | |
"83972241375657056057490261407972968652414535100474" | |
"82166370484403199890008895243450658541227588666881" | |
"16427171479924442928230863465674813919123162824586" | |
"17866458359124566529476545682848912883142607690042" | |
"24219022671055626321111109370544217506941658960408" | |
"07198403850962455444362981230987879927244284909188" | |
"84580156166097919133875499200524063689912560717606" | |
"05886116467109405077541002256983155200055935729725" | |
"71636269561882670428252483600823257530420752963450")) | |
(defn char->int | |
[c] | |
(Integer/parseInt (str c))) | |
(defn string->int-seq | |
[s] | |
(map char->int s)) | |
(defn problem-8 | |
([] (problem-8 input)) | |
([s] (->> | |
(string->int-seq s) | |
(partition 5 1) | |
(map #(apply * %)) | |
(reduce max 0)))) | |
(is (= (char->int \0) 0)) | |
(is (= (char->int \9) 9)) | |
(is (= (string->int-seq "1") [1])) | |
(is (= (string->int-seq "12345") [1 2 3 4 5])) | |
(is (= (problem-8 "123789") 3024)) | |
(is (= (problem-8) 40824)) |
やはり、Clojure を有効に使うには Java API の知識が必要になりますね……。
そうですね.といっても,Project Euler を解くだけであれば,Clojure の基本型にもなっている Long
, Double
, Character
と String
. それに Math
といった java.lang
のごくごく一部の知識があれば十分です.
今,Java API の知識が必要になるもの = clojure.jar
で提供されていないものを思いつきで列挙してみます.
- Mutable なデータ型
- プリミティブ型のラッパクラス
(java.lang (Long Double Character))
- 文字列操作
java.lang.String
- 数学関数
java.lang.Math
- 実行環境へのアクセス
java.lang.System
- 低レベルの I/O
java.io
などなど結構ありますね.
最初に戻って,「有効」というのがどの程度なのかにもよるのですが,
- 速く・効率のよいプログラムを書く
- コード量を減らす
という目的であれば,Java interop は必須かと思います.Java interop が無い Clojure は,言語仕様だけを見ていると末尾呼出最適化も継続も無い劣化 Scheme のように思えてしまいます.しかし,Clojure は Java を書けたり Java の豊富なライブラリを使えたりすので,プロダクションコードを書こうとする分にはその欠点を自覚することはありません.むしろ,Java interop があるおかげで,実績のあるライブラリを使うことでバグが減ったり,コーディングに使う時間を減らせる分十分に設計を検討できたり,と非 JVM 言語にはない恩恵を受けられます.Scheme や CL から来た人や理論派の人が Clojure を触ると何か物足りないと思い,Java で実践的に開発しているプログラマが Clojure を触ると何かいいなと思うのも,このあたりに理由があると考えています.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Clojure は文字列も(文字の)シーケンスとして扱えるのがよいですね。
文字列を分配束縛できることを知った時は、軽い衝撃を受けた覚えがあります。(シーケンスなので当然の動作なのですが)
char->int
相当の処理は、僕も @bouzuya さんと同じ方法で行なっていましたが、@tnoda さんの提示した、
#(Character/digit (char %) 10)
,#(Character/digit ^char % 10)
というコードの方が良いと思うので、次からはそちらを使おうと思います。やはり、Clojure を有効に使うには Java API の知識が必要になりますね……。