5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

paiza×Qiita記事投稿キャンペーン「プログラミング問題をやってみて書いたコードを投稿しよう!」

paiza Aランク問題「じゃんけんの手の出し方」を Elixir で解いてみた

Last updated at Posted at 2024-08-19

はじめに

paiza A ランク問題を Elixir で解いてみます

じゃんけんの手の出し方

相手の出す手が全て分かっているとき、開いた指の合計数を指定数に合わせ、最も勝利数が多くなるようにします

defmodule Paiza do
  def main do
    [n, m] =
      :stdio
      |> IO.read(:line)
      |> String.trim()
      |> String.split(" ")
      |> Enum.map(&String.to_integer(&1))

    # 相手のGCP毎の手数
    f =
      :stdio
      |> IO.read(:line)
      |> String.trim()
      |> String.codepoints()
      |> Enum.frequencies()

    # P(パー)が 0 〜 最大まで、全てのパターンを計算する
    0..(div(m, 5))
    |> Enum.map(fn p ->
      c = div(m - p * 5, 2) # C(チョキ)の数
      g = n - p - c # G(グー)の数
      
      {g, c, p}
    end)
    |> Enum.filter(fn {g, c, p} ->
       # 条件を満たす場合だけを抽出
      g >= 0 and m == p * 5 + c * 2
    end)
    |> Enum.map(fn {g, c, p} ->
      # 勝利数を計算
      g_win = min(g, Map.get(f, "C", 0))
      c_win = min(c, Map.get(f, "P", 0))
      p_win = min(p, Map.get(f, "G", 0))
      Enum.sum([g_win, c_win, p_win])
    end)
    |> Enum.max()
    |> IO.puts()
  end
end

Paiza.main()

解説

手数と指の合計数が決まっているため、パーの数が決まったとき、残りの指はチョキで賄うしかありません(グーは 0 なので)

パーの数が 0 のときから、最大のときまで、全てのパターンに対して、グーチョキパーの手数を計算します

そのうち、条件を満たすケースだけを抽出し、勝利数の最大値を求めます

まとめ

パーが決まればチョキが決まる、ということにさえ気付けば単純ですが、途中無駄にややこしく考えてしまいました

最終的に map |> filter |> map |> max になって、パイプがいい感じです( reduce にすることもできますが)

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?