中野's workspace

  • Profile
  • Privacy
  • Contact

2022/04/10

Atcoder ABC042 A,B,CをElixirで解く

  • #atcoder
  • #Elixir

目次

概要

Elixirの練習を兼ねて、Atcoderの過去問を解いてみることにした。

今回解いた問題一覧のリンクは下記。
https://atcoder.jp/contests/abc042

全問解けたわけではなく、ABCのみ。
D - いろはちゃんとマス目 については解き方分らんのでレベル上がってから挑戦することにした。
(勉強ちゃんとしないと…)

Elixir初心者かつ競プロもよわよわなので、よりよい書き方あればどなたか教えて欲しいです。

問題

A - 和風いろはちゃんイージー

defmodule Main do
  def read_single_as_string() do
    IO.gets("") |> String.trim
  end

  def read_split_as_int() do
    read_single_as_string() |> String.split |> Enum.map(&String.to_integer/1)
  end

  def puts(n) do
    IO.puts(n)
  end

  def main() do
    [a, b, c] = read_split_as_int()

    ans(a, b, c)
  end

  def ans(5, 5, 7), do: puts("YES")
  def ans(5, 7, 5), do: puts("YES")
  def ans(7, 5, 5), do: puts("YES")

  def ans(_, _, _), do: puts("NO")
end

575になり得るパターンを全て書き出して、マッチする場合のみYESを出力している。

実際の開発ではこんなコードまず書かないだろうけど、パターンマッチの威力の高さが実感出来る、お気に入りのコード。

B - 文字列大好きいろはちゃんイージー

defmodule Main do
  def read_single_as_string() do
    IO.gets("") |> String.trim
  end

  def read_split_as_string() do
    read_single_as_string() |> String.split
  end

  def read_split_as_int() do
    read_single_as_string() |> String.split |> Enum.map(&String.to_integer/1)
  end

  def read_multi_as_string(n) do
    for _ <- 1..n, do: read_split_as_string()
  end

  def puts(n) do
    IO.puts(n)
  end

  def main() do
   [n, _] = read_split_as_int()

   read_multi_as_string(n) |> Enum.sort() |> puts()
  end
end

単純にソートしたものを出力しただけ。

C - こだわり者いろはちゃん

defmodule Main do
  def read_single_as_string() do
    IO.gets("") |> String.trim
  end

  def read_split_as_string() do
    read_single_as_string() |> String.split
  end

  def read_split_as_int() do
    read_single_as_string() |> String.split |> Enum.map(&String.to_integer/1)
  end

  def puts(n) do
    IO.puts(n)
  end

  def main() do
    [n, _] = read_split_as_int()
    d = read_split_as_string()

    puts_ans(n, d)
  end

  defp puts_ans(n, d) do
    l = n |> to_string |> String.split("")

    cond do
      Enum.any?(l, fn(a) -> Enum.member?(d, a) end) -> puts_ans(n + 1, d)
      true -> puts(n)
    end
  end
end

やりたいことを実現するのに公式ドキュメントとかなりにらめっこしていた。

Nを一桁ずつの配列に分解して、順番にひとつずつDと突き合わせを行い、全てDを含まないものであればその数字を出力している。

Enumの機能が充実しているので、探せばがちゃがちゃ実装しなくてもシンプルに書けた。

感想

自分の実力で解けないものは後回しにしてしまったが、思ったよりも直感的に書きやすい印象。

Enumと仲良くなることが直近の上達の近道な気がしている。

公式のリファレンスを繰り返し読みながら実装しているので、開発の速度はめっちゃ遅いが、いつかはコンテスト出てみたいと思う。

このエントリーをはてなブックマークに追加
  • Copyright © 2019. Makoto Nakano
  • ALL Tags