LoginSignup
7
3

More than 3 years have passed since last update.

AtCoder に登録したら解くべき精選過去問 10 問を私も"Elixir"で解いてみた

Last updated at Posted at 2020-10-14

はじめに

準備

  • Elixirをインストールしましょう
  • プロジェクトを作っておきます
$ mix new at_coder
$ cd at_coder

問題A - Product

  • 問題文はリンク先をご参照くださいませ :bow:
lib/abc_086_a.ex
defmodule Abc086A do
  def main do
    [a, b] =
      IO.read(:line) |> String.trim() |> String.split(" ") |> Enum.map(&String.to_integer/1)

    solve(a, b)
    |> IO.puts()
  end

  @doc ~S"""
  https://atcoder.jp/contests/abc086/tasks/abc086_a

  ## Examples

      iex> Abc086A.solve(3, 4)
      "Even"
      iex> Abc086A.solve(1, 21)
      "Odd"

  """
  def solve(a, b) when rem(a, 2) == 0 or rem(b, 2) == 0, do: "Even"

  def solve(_, _), do: "Odd"
end
  • ## Examplesのところに書いてあるものは、Doctestsと呼ばれるものでしてテストができます
  • 解答のキモとなる関数について、問題に書いてある入力例をインプットして出力例の通りアウトプットされるかを確かめています
  • test/at_coder_test.exsに設定を足しておきましょう
test/at_coder_test.exs
defmodule AtCoderTest do
  use ExUnit.Case
  doctest Abc086A
$ mix test
..........

Finished in 0.2 seconds
9 doctests, 1 test, 0 failures
  • 提出の際にはモジュール名はMainにしておいてください
  • :tada::tada::tada:
  • この調子で以下、他の問題を解いていきます

問題A - Placing Marbles

  • 問題文はリンク先をご参照くださいませ :bow:
lib/abc_086_a.ex
defmodule Abc081A do
  def main do
    IO.read(:line)
    |> String.trim()
    |> solve()
    |> IO.puts()
  end

  @doc ~S"""
  https://atcoder.jp/contests/abc081/tasks/abc081_a

  ## Examples

      iex> Abc081A.solve("101")
      2
      iex> Abc081A.solve("000")
      0

  """
  def solve(s) do
    String.codepoints(s)
    |> Enum.count(&(&1 == "1"))
  end
end
  • 提出の際にはモジュール名はMainにしておいてください
  • :tada::tada::tada:

問題B - Shift only

  • 問題文はリンク先をご参照くださいませ :bow:
lib/abc_081_b.ex
defmodule Abc081B do
  def main do
    IO.read(:line)

    IO.read(:line)
    |> String.trim()
    |> String.split(" ")
    |> Enum.map(&String.to_integer/1)
    |> solve()
    |> IO.puts()
  end

  @doc ~S"""
  https://atcoder.jp/contests/abc081/tasks/abc081_b

  ## Examples

      iex> Abc081B.solve([8, 12, 40])
      2
      iex> Abc081B.solve([5, 6, 8, 10])
      0
      iex> Abc081B.solve([382253568, 723152896, 37802240, 379425024, 404894720, 471526144])
      8

  """
  def solve(list) do
    Enum.reduce_while(list, 10_000_000_000, fn a, acc ->
      cnt = do_solve(a, 0)
      new_acc = if cnt < acc, do: cnt, else: acc
      if new_acc == 0, do: {:halt, 0}, else: {:cont, new_acc}
    end)
  end

  defp do_solve(a, acc) when rem(a, 2) == 1, do: acc

  defp do_solve(a, acc), do: do_solve(div(a, 2), acc + 1)
end
  • 提出の際にはモジュール名はMainにしておいてください
  • :tada::tada::tada:

問題B - Coins

  • 問題文はリンク先をご参照くださいませ :bow:
lib/abc_087_b.ex
defmodule Abc087B do
  def main do
    a = IO.read(:line) |> String.trim() |> String.to_integer()
    b = IO.read(:line) |> String.trim() |> String.to_integer()
    c = IO.read(:line) |> String.trim() |> String.to_integer()
    x = IO.read(:line) |> String.trim() |> String.to_integer()

    solve(a, b, c, x)
    |> IO.puts()
  end

  @doc ~S"""
  https://atcoder.jp/contests/abc087/tasks/abc087_b

  ## Examples

      iex> Abc087B.solve(2, 2, 2, 100)
      2
      iex> Abc087B.solve(5, 1, 0, 150)
      0
      iex> Abc087B.solve(30, 40, 50, 6000)
      213

  """
  def solve(a, b, c, x) do
    for(i <- 0..a, j <- 0..b, k <- 0..c, 500 * i + 100 * j + 50 * k == x, do: {i, j, k})
    |> Enum.count()
  end
end
  • 提出の際にはモジュール名はMainにしておいてください
  • :tada::tada::tada:

問題B - Some Sums

  • 問題文はリンク先をご参照くださいませ :bow:
lib/abc_083_b.ex
defmodule Abc083B do
  def main do
    [n, a, b] =
      IO.read(:line) |> String.trim() |> String.split(" ") |> Enum.map(&String.to_integer/1)

    solve(n, a, b)
    |> IO.puts()
  end

  @doc ~S"""
  https://atcoder.jp/contests/abc083/tasks/abc083_b

  ## Examples

      iex> Abc083B.solve(20, 2, 5)
      84
      iex> Abc083B.solve(10, 1, 2)
      13
      iex> Abc083B.solve(100, 4, 16)
      4554

  """
  def solve(n, a, b) do
    for(i <- 1..n, sum = digit_sum(i, 0), a <= sum, sum <= b, do: i)
    |> Enum.sum()
  end

  defp digit_sum(i, acc) when i < 10, do: acc + i

  defp digit_sum(i, acc), do: digit_sum(div(i, 10), acc + rem(i, 10))
end
  • 提出の際にはモジュール名はMainにしておいてください
  • :tada::tada::tada:

問題B - Card Game for Two

  • 問題文はリンク先をご参照くださいませ :bow:
lib/abc_088_b.ex
defmodule Abc088B do
  def main do
    IO.read(:line)

    IO.read(:line)
    |> String.trim()
    |> String.split(" ")
    |> Enum.map(&String.to_integer/1)
    |> solve()
    |> IO.puts()
  end

  @doc ~S"""
  https://atcoder.jp/contests/abc088/tasks/abc088_b

  ## Examples

      iex> Abc088B.solve([3, 1])
      2
      iex> Abc088B.solve([2, 7, 4])
      5
      iex> Abc088B.solve([20, 18, 2, 18])
      18

  """
  def solve(list) do
    sorted_list = Enum.sort(list, :desc)
    alice_list = Enum.take_every(sorted_list, 2)
    Enum.sum(alice_list) * 2 - Enum.sum(list)
  end
end
  • 提出の際にはモジュール名はMainにしておいてください
  • :tada::tada::tada:

問題B - Kagami Mochi

  • 問題文はリンク先をご参照くださいませ :bow:
lib/abc_085_b.ex
defmodule Abc085B do
  def main do
    n = IO.read(:line) |> String.trim() |> String.to_integer()

    for(_ <- 1..n, do: IO.read(:line) |> String.trim() |> String.to_integer())
    |> solve()
    |> IO.puts()
  end

  @doc ~S"""
  https://atcoder.jp/contests/abc085/tasks/abc085_b

  ## Examples

      iex> Abc085B.solve([10, 8, 8, 6])
      3
      iex> Abc085B.solve([15, 15, 15])
      1
      iex> Abc085B.solve([50, 30, 50, 100, 50, 80, 30])
      4

  """
  def solve(list), do: MapSet.new(list) |> MapSet.size()
end
  • 提出の際にはモジュール名はMainにしておいてください
  • :tada::tada::tada:

問題C - Otoshidama

  • 問題文はリンク先をご参照くださいませ :bow:
lib/abc_085_b.ex
defmodule Abc085C do
  def main do
    [n, y] =
      IO.read(:line) |> String.trim() |> String.split(" ") |> Enum.map(&String.to_integer/1)

    solve(n, y)
    |> IO.puts()
  end

  @doc ~S"""
  https://atcoder.jp/contests/abc085/tasks/abc085_b

  ## Examples

      iex> Abc085C.solve(9, 45000)
      "0 9 0"
      iex> Abc085C.solve(20, 196000)
      "-1 -1 -1"
      iex> Abc085C.solve(1000, 1234000)
      "2 54 944"
      iex> Abc085C.solve(2000, 20000000)
      "2000 0 0"

  """
  def solve(n, y) do
    for(
      i <- 0..n,
      j <- 0..(n - i),
      k = n - i - j,
      j >= 0,
      k >= 0,
      10000 * i + 5000 * j + 1000 * k == y,
      do: "#{i} #{j} #{k}"
    )
    |> Enum.at(0, "-1 -1 -1")
  end
end
  • 提出の際にはモジュール名はMainにしておいてください
  • :tada::tada::tada:

問題C - 白昼夢

  • 問題文はリンク先をご参照くださいませ :bow:
lib/abc_049_c.ex
defmodule Abc049C do
  @words ~w(dream dreamer erase eraser) |> Enum.map(&String.reverse/1)

  def main do
    IO.read(:line)
    |> String.trim()
    |> solve()
    |> IO.puts()
  end

  @doc ~S"""
  https://atcoder.jp/contests/abc085/tasks/abc085_b

  ## Examples

      iex> Abc049C.solve("erasedream")
      "YES"
      iex> Abc049C.solve("dreameraser")
      "YES"
      iex> Abc049C.solve("dreamerer")
      "NO"

  """
  def solve(s) do
    String.reverse(s) |> do_solve()
  end

  defp do_solve(""), do: "YES"

  defp do_solve(nil), do: "NO"

  defp do_solve(s) do
    @words
    |> Enum.reduce_while(nil, fn word, acc ->
      if String.starts_with?(s, word) do
        {:halt, String.slice(s, String.length(word)..-1)}
      else
        {:cont, acc}
      end
    end)
    |> do_solve()
  end
end
  • 提出の際にはモジュール名はMainにしておいてください
  • :tada::tada::tada:

問題ABC086C - Traveling

  • 問題文はリンク先をご参照くださいませ :bow:
lib/lib/arc089_a.ex
defmodule Arc089A do
  def main do
    n = IO.read(:line) |> String.trim() |> String.to_integer()

    1..n
    |> Enum.reduce([], fn _, acc ->
      list =
        IO.read(:line) |> String.trim() |> String.split(" ") |> Enum.map(&String.to_integer/1)

      [list | acc]
    end)
    |> Enum.reverse()
    |> solve()
    |> IO.puts()
  end

  @doc ~S"""
  https://atcoder.jp/contests/abc172/tasks/abc172_b

  ## Examples

      iex> Arc089A.solve([[3, 1, 2], [6, 1, 1]])
      "Yes"
      iex> Arc089A.solve([[2, 100, 100]])
      "No"
      iex> Arc089A.solve([[5, 1, 1], [100, 1, 1]])
      "No"

  """
  def solve(list_of_lists) do
    list_of_lists
    |> Enum.reduce_while([0, 0, 0, "No"], fn next, acc ->
      do_solve(next, acc)
    end)
    |> Enum.at(-1)
  end

  defp do_solve([next_t, next_x, next_y], [t, x, y, _])
       when abs(next_x - x) + abs(next_y - y) > next_t - t,
       do: {:halt, [next_t, next_x, next_y, "No"]}

  defp do_solve([next_t, next_x, next_y], [t, x, y, _])
       when rem(next_t - t - (abs(next_x - x) + abs(next_y - y)), 2) == 1,
       do: {:halt, [next_t, next_x, next_y, "No"]}

  defp do_solve([next_t, next_x, next_y], _),
    do: {:cont, [next_t, next_x, next_y, "Yes"]}
end
  • 提出の際にはモジュール名はMainにしておいてください
  • :tada::tada::tada:

Wrapping Up :qiita-fabicon:

7
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
3