【Elixir】ABC362CをACできる入力処理

# はじめに

ABC362CをElixirで解いてみたのですが、TLEでした。
データを読み取るだけのプログラムにしてもTLE。
私がテンプレートにしている入力処理があまりにも遅すぎるので改善することにしました

# ためしてみた事

## IO.binread

[昔Qiitaの記事に同じような事](https://qiita.com/GeekMasahiro/items/6fb5bf571860e603cb8d)を書いてました。試して見ます。

```Elixir
defmodule Main do
    def main() do
        input_data = IO.binread(:stdio, :eof)
    end
end
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/083f6062-5b9c-d83e-06de-9f366b022cd2.png)

全体を読み込むだけで2秒かかる場合がある。間に合いません。

## IO.read

```Elixr
defmodule Main do
    def main() do
        input = IO.read(:stdio, :all)
    end
end
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/2cb6e12b-e4c4-fe70-bdff-834b8e55b63f.png)

IO.readはIO.binreadと同じ感じ。

## File.read

ABC362CをElixirでACしている[slimepettanさんの回答](https://atcoder.jp/contests/abc362/submissions/56440770)がFile.readでした。File.readを試して見ます。

```Elixir
defmodule Main do
    def main() do
        {_ok, input_data} = File.read("/dev/stdin")
    end
end
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/b65edf94-be68-ebcb-10a9-64155d594629.png)

最速です！

## File.stream!

```Elixir
defmodule Main do
    def main() do
        File.stream!("/dev/stdin")
    end
end
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/44d8736c-7628-a0ab-b8c9-4d12eedfe380.png)

File.streamも、File.readと同じ傾向。

## erlangのio

```Elixir
defmodule Main do
    def main() do
        n = :io.get_line("")|> String.trim|>String.to_integer()
        xy = for i <- 1..n do
            :io.get_line("")
        end
        # IO.inspect(xy)
    end
end
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/2e0aeaed-791e-d7e0-537f-63792c5f85b4.png)

解決にならず

# まとめ

今回の観察の結果最速な読み込み

```Elixir
defmodule Main do
    def main() do
        {_ok, input_data} = File.read("/dev/stdin")
        _lines = input_data |> String.split("\n", trim: true)
    end
end
```
読み込みだけの処理で、処理時間は、1400msくらいです。

600msしか余裕ないですが、ABC362Cの本体の処理は軽かったので、[ACできました](https://atcoder.jp/contests/abc362/submissions/56507133)。

整数や整数のリスト、整数のリストのリストを読み込む事はよくあるので、読みだす関数も作ってみました。


```Elixir
defmodule Main do

    def stdin() do
        {_ok, input_data} = File.read("/dev/stdin")
        input_data |> String.split("\n", trim: true)
    end
    def input(stream) do
        stream
        |> IO.read(:line)
        |> String.trim()
    end

    def ii(input_data) do
        [line | rest] = input_data
        {rest, line |> String.to_integer()}
    end

    def li(input_data) do
        # input_dataの先頭の一行を取り出し、整数のリストに変換して返す
        [line | rest] = input_data
        {rest, line |> String.split(" ") |> Enum.map(&String.to_integer/1)}
    end

    def li(input_data,n) do
        # input_dataの先頭のn行を取り出し、整数のリストのリストに変換して返す
        {lines,rest} = Enum.split(input_data, n)
        {rest, lines |> Enum.map(fn line -> String.split(line, " ") |> Enum.map(&String.to_integer/1) end)}
    end

    def main() do
        lines = stdin()
        {lines, n} = ii(lines)
        {lines, lr} = li(lines, n)
        solve(n, lr)
    end

    def solve(n, lr) do
        # ～～～省略～～～
    end
end

```



# 参考

slimepettanさんの回答　https://atcoder.jp/contests/abc362/submissions/56440770