LoginSignup
2
0

More than 1 year has passed since last update.

ABC244のA, B, C, D問題 を Elixir で解く

Last updated at Posted at 2022-03-22

これに続いて、Elixir 超初心者が AtCoder に挑戦してみました。

御指導よろしくお願いします。

A問題: Last Letter

defmodule Main do
  def main do
    IO.read(:line)
    IO.read(:line) |> String.trim()
    |> String.at(-1)
    |> IO.puts()
  end
end

与えられた文字列の最後の文字を取り出すということで、String.at(str, -1)でいいのですね。負数のインデックスが後ろからの指定になるのは、Ruby と同じです。

B問題: Go Straight and Turn Right

defmodule Main do
  def main do
    IO.read(:line)
    IO.read(:line) |> String.trim()
    |> solve()
    |> IO.puts()
  end
  
  defp solve(str) do
    str
    |> String.codepoints()
    |> Enum.reduce({0, {0, 0}}, &doit/2)
    |> output()
  end
  
  defp doit("S", {0, {x, y}}), do: {0, {x + 1, y}}
  defp doit("S", {1, {x, y}}), do: {1, {x, y - 1}}
  defp doit("S", {2, {x, y}}), do: {2, {x - 1, y}}
  defp doit("S", {3, {x, y}}), do: {3, {x, y + 1}}
  defp doit("R", {dir, tpl}), do: {rem(dir + 1, 4), tpl}
  
  defp output({_, {x, y}}), do: "#{x} #{y}"
end

0, 1, 2, 3 の数字で「右下左上」の方向を表しています。右回転なので 1 を足していけば回転します。

C問題: Yamanote Line Game

defmodule Main do
  def main do
    IO.read(:line) |> String.trim() |> String.to_integer()
    |> solve()
  end
  
  defp solve(n), do: Enum.to_list(1..2 * n + 1) |> doit()
  
  defp doit([x | xs]) do
    IO.puts(x)
    IO.read(:line) |> String.trim() |> String.to_integer()
    |> doit(xs)
  end

  defp doit(0, list), do: nil
  defp doit(i, list), do: List.delete(list, i) |> doit()
end

まさかのインタラクティブ問題。手続き型言語なら無限ループさせておいて終了条件がきたらループを出ればいいだけですが、関数型言語なので工夫が要りました。再帰でやっています。それから、問題にある標準出力のflushはどうすればよいかよくわかりませんでしたが、ここではテキトーにIO.puts/1でよかったようです。

D問題: Swap Hats

defmodule Main do
  def main do
    s = IO.read(:line) |> String.trim()
    t = IO.read(:line) |> String.trim()
    
    solve(s, t) |> IO.puts()
  end
  
  defp solve(s, t), do: judge(s) * judge(t) |> output()
  
  defp judge("R G B"), do: 1
  defp judge("G B R"), do: 1
  defp judge("B R G"), do: 1
  defp judge(_), do: -1
  
  defp output(1), do: "Yes"
  defp output(-1), do: "No"
end

これは対称群の知識があるとよいです。"R G B"からの偶置換を1、奇置換を-1として、s t それぞれについての値の積が1(偶置換)になればよいというのを実装しました。

最後に

Elixir で AtCoder をやる人が少なくて、参考にしたくてもなかなか…。それから、僕の実装が悪いのかも知れませんが、速度的にもきびしいです。コードの改善など、きびしい指摘を待っております。

2
0
0

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
2
0