naoki86star

インターネットの片隅でなにかしら書いてみる

ProjectEulerの67番をclojureで書いてみる

clojureへのネイティブ感ないままに書き下してみる*1

(2020/1/27) timeを覚えたのでupdate

(def input-file "p067_triangle.txt")
(def numbers
  (map (fn [x] (map (fn [x] (int (bigint x))) (clojure.string/split x #" ")))
       (reverse (clojure.string/split-lines (slurp input-file)))))
(println input-file "has been load, " (count numbers) "lines")

(defn processoneline [a1 a2]
  (loop [ p a1 q a2 r [] ]
    (if (second p)
        (recur (next p)
               (next q)
               (conj r (if (< (first p) (second p))
                           (+ (first q) (second p))
                           (+ (first q) (first p)))))
        r))
)

(defn calc-answer [n]
  (loop [ asums (first n) line (drop 1 n) ]
    (if (first line)
        (recur (processoneline asums (first line))
               (next line)
    )
    (first asums))
))

(time (println "ans=" (calc-answer numbers)))

実行結果

$ clojure
Clojure 1.10.1
user=> (clojure.main/load-script "p067.clj")
p067_triangle.txt has been load,  100 lines
ans= 7273
"Elapsed time: 208.648846 msecs"

pythonで書くとファイルread込みで同じPCで10msec以下、きっともっと速くできるはず...
slurp はURLも引数にとれるみたいなのがfine

#昨日ubuntu16のclojure1.6だとreplコマンドラインだとreadline(すなわち入力履歴の意)が効いていたが、自PCのubuntu18の1.10だと効かない ビルド時の違いってあるんだろうかJLineみたいなの組み込んであるものとそうでないものとか...*2

*1:本当はpythonとかでも変なしゃべり方してるんでしょうが。。。

*2:リリース時時点のライセンス事情とかで変わってしまう可能性あるし