paiza Cランク問題を Elixir で解いてみた

## はじめに

前回の記事で D ランク問題を解いたので、 C ランク問題を解いていきます

https://qiita.com/RyoWakabayashi/private/7e65bd490677e069c54b

## 宝くじ

当選番号と各くじの番号を比較して当選結果を出力する

https://paiza.jp/works/mondai/c_rank_skillcheck_archive/lottery

ガード構文を使って場合分けしています

```elixir
defmodule Paiza do
  def main do
    [b | [_n | a]] =
      :stdio
      |> IO.read(:all)
      |> String.trim()
      |> String.split("\n")
      |> Enum.map(&String.to_integer(&1))

    a
    |> Enum.map(fn a_n ->
        solve(b, a_n) |> IO.puts()
    end)
  end

  defp solve(b, b), do: "first"
  defp solve(b, a) when b == a + 1, do: "adjacent"
  defp solve(b, a) when b == a - 1, do: "adjacent"
  defp solve(b, a) when rem(b, 10000) == rem(a, 10000), do: "second"
  defp solve(b, a) when rem(b, 1000) == rem(a, 1000), do: "third"
  defp solve(b, a), do: "blank"
end

Paiza.main()
```

## 野球の審判

投球結果に応じたコールを返します

https://paiza.jp/works/mondai/c_rank_skillcheck_archive/umpire

`Enum.reduce` でストライクとボールをカウントしながらループします

```elixir
defmodule Paiza do
  def main do
    [_n | c] =
      :stdio
      |> IO.read(:all)
      |> String.trim()
      |> String.split("\n")

    c
    |> Enum.reduce({0, 0}, fn c_n, {num_s, num_b} ->
        {call, num} = solve(c_n, {num_s, num_b})
        
        IO.puts(call)

        num
    end)
  end

  defp solve("strike", {2, num_b}), do: {"out!", {3, num_b}}
  defp solve("strike", {num_s, num_b}), do: {"strike!", {num_s + 1, num_b}}
  defp solve("ball", {num_s, 3}), do: {"fourball!", {num_s, 4}}
  defp solve("ball", {num_s, num_b}), do: {"ball!", {num_s, num_b + 1}}
end

Paiza.main()
```

## みかんの仕分け

重さに応じてみかんを箱に仕分けます

https://paiza.jp/works/mondai/c_rank_skillcheck_archive/mikan

剰余を単位数で割って 0.5 以上なら重い方に近く、 0.5 未満なら軽い方に近くなっています

```elixir
defmodule Paiza do
  def main do
    [n_m | w] =
      :stdio
      |> IO.read(:all)
      |> String.trim()
      |> String.split("\n")

    [n, _m] =
      n_m
      |> String.split(" ")
      |> Enum.map(&String.to_integer(&1))

    w = Enum.map(w, &String.to_integer(&1))

    w
    |> Enum.map(fn w_k ->
        solve(w_k, n) |> IO.puts()
    end)
  end

  defp solve(w_k, n) when w_k <= n , do: n
  defp solve(w_k, n) when rem(w_k, n) / n >= 0.5, do: (div(w_k, n) + 1) * n
  defp solve(w_k, n), do: div(w_k, n) * n
end

Paiza.main()
```

## Fizz Buzz

3 の倍数のとき Fizz になり、 5 の倍数のとき Buzz になり、 3 と 5 の公倍数のとき Fizz Buzz になります

https://paiza.jp/works/mondai/c_rank_skillcheck_sample/fizz-buzz

`1..n` で 1 から n まで繰り返します

```elixir
defmodule Paiza do
  def main do
    n =
      :stdio
      |> IO.read(:all)
      |> String.trim()
      |> String.to_integer()

    1..n
    |> Enum.map(fn n_k ->
        solve(n_k) |> IO.puts()
    end)
  end

  defp solve(n_k) when rem(n_k, 3) == 0 and rem(n_k, 5) == 0 , do: "Fizz Buzz"
  defp solve(n_k) when rem(n_k, 3) == 0, do: "Fizz"
  defp solve(n_k) when rem(n_k, 5) == 0, do: "Buzz"
  defp solve(n_k), do: Integer.to_string(n_k)
end

Paiza.main()
```

## 残り物の量

初期値 m kg から p % 売れ、残りのうち q % が売れたときの残りが何 kg か計算します

https://paiza.jp/works/mondai/c_rank_skillcheck_archive/leftover

単純な計算問題です

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

    IO.puts(m * (100 - p) * (100 - q) / 10000)
  end
end

Paiza.main()
```

## まとめ

C ランクまでは小手調べですね

reduce を使う問題が出てきた辺りは面白いです