はじめに
What is AtCoder?
- 世界最高峰の競技プログラミングサイトです
- だいたい毎週土曜や日曜の21時すぎにコンテストが行われているようです
- 出題された問題の答えを出力するプログラムを書いて提出することで自動的に採点されます
- 実行時間が長かったり、メモリの使用量が多いとパスできません
- 競技プログラミングというもの自体に私は馴染みがなかったのですが、最近はじめました
はじめての方は
-
ElixirでAtCoderにはじめて取り組まれる方は、手前味噌ですが、「AtCoderをElixirでやってみる」をご参照ください
- インプットの読み取り方などのTipsを書いています
-
Elixir自体がはじめての方はまずインストールしましょう
- 手前味噌ですがインストールなどをご参照ください
便利なツール
-
tamanugi/ex_at_coder
- @tamanugiさん作
- AtCoder用のmixタスクを作ってみた
- @tamanugiさんのex_at_coderを使ってみる (Elixir)
- 本日はこちらを使います
- g-kenkun/kyopuro
プロジェクト作成
$ mkdir awesome_at_coder
$ cd awesome_at_coder
$ asdf local elixir 1.10.2-otp-22
$ mix new .
mix.exs
defp deps do
[
# {:dep_from_hexpm, "~> 0.3.0"},
# {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
{:ex_at_coder, ">0.0.0"}
]
end
$ mix deps.get
ABC193A
$ mix atcoder.open abc193 a
- 問題文のページがブラウザで開けます
- 問題をご確認ください
$ mix atcoder.new abc193
- 問題文のページからテストケースや回答モジュールの雛形が作られます
ソースコードを書く
- 自分を信じてがんばって解きましょう
lib/abc193/a.ex
defmodule Abc193.A.Main do
def main() do
[a, b] =
IO.read(:line) |> String.trim() |> String.split(" ") |> Enum.map(&String.to_integer/1)
IO.puts((a - b) * 100 / a)
end
end
テストする
$ mix atcoder.test abc193 a
- おーっとテストが落っこちました
- この問題は答えが小数なので誤差が生じているようです
- 期待結果のほうをElixirが出した答えに置き換えちゃってもよさそうです
- そういう細工をしたうえで
$ mix atcoder.test abc193 a
abc193 a
running 3 test...
-------------------------------------
sample1 AC 0ms
actual:
20.0
expected:
20.0
-------------------------------------
sample2 AC 0ms
actual:
14.285714285714286
expected:
14.285714285714286
-------------------------------------
sample3 AC 0ms
actual:
0.001000010000100001
expected:
0.001000010000100001
自信をもって提出しましょう。
提出の際にはモジュール名をMain
にして提出します。
この調子でどんどん行きます
ABC193B
$ mix atcoder.open abc193 b
- 問題文のページがブラウザで開けます
- 問題をご確認ください
ソースコードを書く
- 自分を信じてがんばって解きましょう
lib/abc193/b.ex
defmodule Abc193.B.Main do
def main() do
n = IO.read(:line) |> String.trim() |> String.to_integer()
for _ <- 1..n do
IO.read(:line) |> String.trim() |> String.split(" ") |> Enum.map(&String.to_integer/1)
end
|> Enum.filter(fn [a, _p, x] ->
x - a > 0
end)
|> Enum.min_by(fn [_, p, _] -> p end, fn -> [nil, -1, nil] end)
|> Enum.at(1)
|> IO.puts()
end
end
テストする
$ mix atcoder.test abc193 b
abc193 b
running 3 test...
-------------------------------------
sample1 AC 1ms
actual:
8
expected:
8
-------------------------------------
sample2 AC 0ms
actual:
-1
expected:
-1
-------------------------------------
sample3 AC 0ms
actual:
861648772
expected:
861648772
自信をもって提出しましょう。
提出の際にはモジュール名をMain
にして提出します。
ABC193C
$ mix atcoder.open abc193 c
- 問題文のページがブラウザで開けます
- 問題をご確認ください
ソースコードを書く
- 自分を信じてがんばって解きましょう
lib/abc193/c.ex
defmodule Abc193.C.Main do
def main() do
n = IO.read(:line) |> String.trim() |> String.to_integer()
do_solve(n)
|> IO.puts()
end
defp do_solve(n) when n in [1, 2], do: n
defp do_solve(n) do
2..(:math.sqrt(n) |> round())
|> Enum.reduce(%{}, fn a, acc ->
Enum.reduce_while(2..34, acc, fn b, acc ->
z = pow(a, b)
if z <= n, do: {:cont, Map.update(acc, z, true, & &1)}, else: {:halt, acc}
end)
end)
|> Enum.count()
|> Kernel.-(n)
|> Kernel.*(-1)
end
def pow(a, b), do: do_pow(a, b, 1)
defp do_pow(_, 0, acc), do: acc
defp do_pow(a, b, acc), do: do_pow(a, b - 1, a * acc)
end
テストする
$ mix atcoder.test abc193 c
abc193 c
running 2 test...
-------------------------------------
sample1 AC 3ms
actual:
6
expected:
6
-------------------------------------
sample2 AC 0ms
actual:
99634
expected:
99634
自信をもって提出しましょう。
提出の際にはモジュール名をMain
にして提出します。
Wrapping Up
- Enjoy Elixir