JuliaでProject Euler(1)
JuilaというPython対抗っぽい言語があるらしいので試してみる。
PyPyより速いらしい。
準備
ここからGeneric Linux Binaries for x86 64bit をダウンロード。
https://julialang.org/downloads/
$ tar xvfz julia-1.1.1-linux-x86_64.tar.gz
あと、パスを通す
Problem 1
https://projecteuler.net/problem=1
まず、Pythonで次のように書く。
import sys N = int(sys.argv[1]) s = 0 for n in xrange(1, N): if n%3 == 0 or n%5 == 0: s += n print s
これをPython2とPyPyで実行すると、
$ time python2 e001.py 1000000000 233333333166666668 real 1m25.532s user 1m25.484s sys 0m0.016s $ time pypy e001.py 1000000000 233333333166666668 real 0m2.928s user 0m2.891s sys 0m0.031s
Juliaに翻訳するとこうなる。
N = parse(Int, ARGS[1]) s = 0 for n in 1:(N-1) if n%3 == 0 || n%5 == 0 global s += n end end println(s)
まず、parseは文字列を数値に変換する。Intは環境依存で、ここではInt64。
ループや関数にはコロン(:)をつけずに(いつも間違える)、最後にendをつける。
1:N-1はPython2のxrangeみたいなもの。ただし、これで1からN-1まで排出する。
論理演算子のorは||に。こういう記号は排除するのがプログラミング言語の流れだと思っていたのだが。今どきはC++にもand/orが導入されているのに(Microsoftは知らない)。
globalはなくすとs not definedとなってしまう。forの中は別のスコープらしい。globalをつければ、グローバルスコープのsだと解釈されるらしい。
これを実行すると、
$ time julia e001.jl 1000000000 233333333166666668 real 1m41.669s user 1m41.938s sys 0m0.313s
Python並みなのだが。
そういえば、Pythonでもglobal変数を参照すると時間がかかるという話があるので、関数化してみた。
import sys def e001a(N): s = 0 for n in xrange(1, N): if n%3 == 0 or n%5 == 0: s += n return s N = int(sys.argv[1]) print e001a(N)
function e001a(N) s = 0 for n in 1:(N-1) if n%3 == 0 || n%5 == 0 s += n end end return s end N = parse(Int, ARGS[1]) println(e001a(N))
実行すると、
time python2 e001a.py 1000000000 233333333166666668 real 0m53.546s user 0m53.438s sys 0m0.031s time pypy e001a.py 1000000000 233333333166666668 real 0m3.143s user 0m3.109s sys 0m0.031s time julia e001a.jl 1000000000 233333333166666668 real 0m1.642s user 0m1.797s sys 0m0.344s
PyPyよりも速くなった。
関数型っぽい書き方もできる。
import sys def e001(N): return sum(n for n in xrange(1, N) if n%3 == 0 or n%5 == 0) N = int(sys.argv[1]) print e001(N)
同様に、
function e001(N) return sum(n for n in 1:N-1 if n%3 == 0 || n%5 == 0) end N = parse(Int, ARGS[1]) println(e001(N))
実行すると、
$ time pypy e001b.py 1000000000 233333333166666668 real 0m8.691s user 0m8.641s sys 0m0.047s time julia e001b.jl 1000000000 233333333166666668 real 0m2.305s user 0m2.375s sys 0m0.516s
遅くなる。