この記事を見てElixirという言語でコードを書いてみたくなりました。
Elixirがまったく初めてなので、コンパイル・実行の仕方から調べながらです。コードは上記記事を手本にして書きました。
Elixirソースのコンパイルと実行の方法
$ elixirc sample.ex
$ elixir -e Main.main
AtCoderに提出したコードはこちら。AC取れました。
defmodule Main do
@divisor 1_000_000_007
def main do
IO.read(:line)
|> String.trim()
|> String.to_integer()
|> solve()
|> IO.puts()
end
def solve(n) do
rem(2 * @divisor + pow(10, n) - 2 * pow(9, n) + pow(8, n), @divisor)
end
def pow(m, n), do: pow(m, n, 1)
def pow(_, 0, acc), do: acc
def pow(m, n, acc) do
if rem(n, 2) == 1 do
pow(rem(m * m, @divisor), div(n, 2), rem(m * acc, @divisor))
else
pow(rem(m * m, @divisor), div(n, 2), acc)
end
end
end
書いたコードこれだけの段階での感想ですが、Elixirは関数型でScalaに似た雰囲気があって、ひょっとしたら自分にも合うかも。
AtCoderコンテスト当日はScalaで書きましたが、あまりイケてないコードだったので、今回の記事を機に書き直しました。
object Main extends App {
val m = 1_000_000_007;
def pow(a: Int, b: Int): Int = {
@scala.annotation.tailrec
def sub(a: Long, b: Int, result: Long): Int = {
if (b == 0) {
result.toInt;
} else {
val result2 = if (b % 2 == 1) result * a % m else result;
sub(a * a % m, b / 2, result2);
}
}
sub(a, b, 1);
}
val sc = new java.util.Scanner(System.in);
val n = sc.nextInt();
val answer = (2L * m + pow(10, n) - 2L * pow(9, n) + pow(8, n)) % m;
println(answer);
}