JuliaでABS(AtCoder Beginners Selection)の10問を解いてみた

# はじめに
AtCoder Beginners Selection(以下ABS)をご存知でしょうか？  
AtCoderを始めるにあたって、入り口として[APG4b](https://atcoder.jp/contests/APG4b)と[精選10問](https://qiita.com/drken/items/fd4e5e3630d0f5859067)を耳にする機会が多いと思います。そのうちの、精選10問を常駐化させたコンテストがABSになります。  

普段はPythonitaなので、Juliaという動的な言語は比較的扱いやすいはずです()

## [ABC086A - Product](https://atcoder.jp/contests/abs/tasks/abc086_a)
```abc086a.jl
function main()
    a,b = parse.(Int, split(readline()))

    calc = a * b
    if calc % 2 == 0
        println("Even")
    else
        println("Odd")
    end
end

main()
```

## [ABC081A - Placing Marbles](https://atcoder.jp/contests/abs/tasks/abc081_a)
```abc081a.jl
function main()
    s = readline()

    cnt = 0
    for i = 1:3
        if s[i] == '1'
            cnt += 1
        end
    end

    println(cnt)
end

main()
```

## [ABC081B - Shift only](https://atcoder.jp/contests/abs/tasks/abc081_b)
```abc081b.jl
function main()
    N = parse(Int, readline())
    A = parse.(Int, split(readline()))

    ans = 10^9
    for a = A
        cnt = 0
        while a % 2 == 0
            a ÷= 2
            cnt += 1
        end
        ans = min(ans, cnt)
    end

    println(ans)
end

main()
```

## [ABC087B - Coins](https://atcoder.jp/contests/abs/tasks/abc087_b)
```abc087b.jl
function main()
    A = parse(Int, readline())
    B = parse(Int, readline())
    C = parse(Int, readline())
    X = parse(Int, readline())

    ans = 0
    for a = 0:A
        for b = 0:B
            for c = 0:C
                total = 500*a + 100*b + 50*c
                
                if total == X
                    ans += 1
                end
            end
        end
    end

    println(ans)
end

main()
```

## [ABC083B - Some Sums](https://atcoder.jp/contests/abs/tasks/abc083_b)
```abc083b.jl
function main()
    N,A,B = parse.(Int, split(readline()))

    ans = 0
    for i = 1:N
        str_i = string(i)
        total = 0
        for j = str_i
            total += parse(Int, j)
        end

        if A <= total <= B
            ans += i
        end
    end

    println(ans)
end

main()
```

## [ABC088B - Card Game for Two](https://atcoder.jp/contests/abs/tasks/abc088_b)
```abc088b.jl
function main()
    N = parse(Int, readline())
    a = parse.(Int, split(readline()))

    sort!(a, rev=true)
    alice,bob = 0,0
    for (i,j) in enumerate(a)
        if i % 2 == 1
            alice += j
        else
            bob += j
        end
    end

    ans = alice - bob
    println(ans)
end

main()
```

## [ABC085B - Kagami Mochi](https://atcoder.jp/contests/abs/tasks/abc085_b)
```abc085b.jl
function main()
    N = parse(Int, readline())
    d = Set()
    for _ = 1:N
        push!(d, parse(Int, readline()))
    end

    println(length(d))
end

main()
```

## [ABC085C - Otoshidama](https://atcoder.jp/contests/abs/tasks/abc085_c)
```abc085c.jl
function main()
    N,Y = parse.(Int, split(readline()))

    ans = [-1, -1, -1]
    for i = 0:N
        for j = 0:N
            calc = Y - (10000*i + 5000*j)
            cnt = N - (i + j + calc÷1000)
            if calc >= 0 && cnt == 0
                ans = [i, j, calc÷1000]
            end
        end
    end

    for i = ans
        println(i)
    end
end

main()
```

## [ABC049C - 白昼夢](https://atcoder.jp/contests/abs/tasks/arc065_a)
```abc049c.jl
function main()
    S = readline()

    cand = Set(["dream", "dreamer", "erase", "eraser"])
    S = S[end:-1:1]
    now = ""
    for s = S
        now = s * now
        if in(now, cand)
            now = ""
        end
    end

    if now == ""
        println("YES")
    else
        println("NO")
    end
end

main()
```

## [ABC086C - Traveling](https://atcoder.jp/contests/abs/tasks/arc089_a)
```abc086c.jl
function main()
    N = parse(Int, readline())

    ans = "Yes"
    prev_t, prev_x, prev_y = 0, 0, 0
    for _ = 1:N
        t,x,y = parse.(Int, split(readline()))

        calc_t = t - prev_t
        calc_x = abs(x - prev_x)
        calc_y = abs(y - prev_y)
        judge1 = calc_t % 2 == (calc_x+calc_y) % 2
        judge2 = calc_t >= (calc_x+calc_y)
        if !judge1 || !judge2
            ans = "No"
        end

        prev_t, prev_x, prev_y = t, x, y
    end

    println(ans)
end

main()
```

## おまけ
Pythonitaとして、JuliaとPythonの速度とメモリを比較してみたくなったので、この精選10問で速度比較してみました(ついでにC++も)。  
問題|PyPy|Julia|C++|
|-|-|-|-|
|ABC086A - Product|85 ms / 61752 KB|250 ms / 167908 KB|4 ms / 3536 KB|
|ABC081A - Placing Marbles|79 ms / 61740 KB|215 ms / 158496 KB|3 ms / 3516 KB|
|ABC081B - Shift only|98 ms / 62868 KB	|263 ms / 173380 KB|8 ms / 3532 KB|
|ABC087B - Coins|66 ms / 66996 KB|222 ms / 158684 KB|6 ms / 3604 KB|
|ABC083B - Some Sums|71 ms / 73460 KB|261 ms / 174144 KB|8 ms / 3740 KB|
|ABC088B - Card Game for Two|92 ms / 61808 KB|333 ms / 183064 KB|8 ms / 3648 KB|
|ABC085B - Kagami Mochi|61 ms / 62320 KB|240 ms / 162472 KB|8 ms / 3572 KB|
|ABC085C - Otoshidama|324 ms / 81532 KB|270 ms / 177460 KB|13 ms / 3608 KB|
|ABC049C - 白昼夢|1502 ms / 10260 KB(Python)|1226 ms / 215940 KB|104 ms / 3808 KB|
|ABC086C - Traveling|185 ms / 88328 KB|302 ms / 203872 KB|60 ms / 3600 KB|

最適化できているかは不安ですが、少なくとも実装の仕様は統一したつもりです。そして、上表のような結果になりました。
Juliaは、Pythonと違ってコンパイルするため速いと聞いていましたが、全体的にはPythonの方が早く、省メモリでした。PyPyで比較していることが間違いかもしれませんが。まぁ、AtCoder側でJuliaが最適化されていない説があると思っておきます。  

上表のうち、2つほどJuliaがPythonよりも高速な問題がありますね。その結果だけから推察すると、多重for文と文字列結合はJuliaに軍配が上がるっぽいですね。正式にそうであるかは不明ですが...()

## おまけ2
余談ですが、Juliaでの除算の種類は、`/`と`%`と`÷`の3つを使い分けます。  
`/`が除算で、`%`が余り、`÷`は除算の整数部分となります(Pythonでは`//`に相当)。  

`÷`をMacのキーボードで出力する際には、`option + fn + ?`を押すことで出力できます。Juliaを使う際には、覚えておいて損はないと思いました。

# おわりに
Juliaは、インデックス番号が1から始まる点に気をつければ、比較的学習難易度は低めの言語かな〜、と感じました。  
また、for文が結構すっきりと書ける点が、個人的には好みです。  
静的な言語のfor文は書くこと多い...。静的な言語でfor文が簡単に書ける言語あったら、教えて欲しいです。