Powered by AppSignal & Oban Pro

ABC133D - Rain Flows into Dams

submit_1.livemd

ABC133D - Rain Flows into Dams

問題

回答

defmodule Main do
  def main do
    :stdio
    |> IO.read(:all)
    |> solve()
    |> IO.puts()
  end

  defp split_lines(lines) do
    lines
    |> String.trim()
    |> String.split("\n")
  end

  defp split_words(words) do
    String.split(words, " ")
  end

  defp renew_table(objects, table_name) do
    if :ets.info(table_name) != :undefined do
      :ets.delete(table_name)
    end

    :ets.new(table_name, [:set, :protected, :named_table])
    :ets.insert(table_name, objects)
  end

  defp lookup(table_name, key) do
    case :ets.lookup(table_name, key) do
      [{_, value}] -> value
      _ -> 0
    end
  end

  def solve(input) do
    [[n], a] =
      input
      |> split_lines()
      |> Enum.map(fn line ->
        line
        |> split_words()
        |> Enum.map(&String.to_integer/1)
      end)

    a
    |> Enum.with_index()
    |> Enum.map(fn {a_i, i} -> {i, a_i} end)
    |> renew_table(:a)

    s = Enum.sum(a)

    x_0 =
      0..(n - 1)
      |> Enum.reduce(s, fn i, acc ->
        case rem(i, 2) do
          0 -> acc
          _ -> acc - 2 * lookup(:a, i)
        end
      end)

    renew_table({0, x_0}, :x)

    1..(n - 1)
    |> Enum.each(fn i ->
      :ets.insert(:x, {i, 2 * lookup(:a, i - 1) - lookup(:x, i - 1)})
    end)

    :x
    |> :ets.tab2list()
    |> Enum.sort_by(&elem(&1, 0))
    |> Enum.map(fn {_, x_i} -> Integer.to_string(x_i) end)
    |> Enum.join(" ")
  end
end
"""
3
2 2 4
"""
|> Main.solve()
|> then(&(&1 == "4 0 4"))
"""
5
3 8 7 5 5
"""
|> Main.solve()
|> then(&(&1 == "2 4 12 2 8"))
"""
3
1000000000 1000000000 0
"""
|> Main.solve()
|> then(&(&1 == "0 2000000000 0"))