Powered by AppSignal & Oban Pro

Day 5: Hydrothermal Venture

2021/day05.livemd

Day 5: Hydrothermal Venture

Section

defmodule Setup do
  def get_input(prompt) do
    case IO.gets(prompt) do
      :eof -> ""
      line -> line <> get_input(prompt)
    end
  end
end
Setup.get_input("Input")
|> String.split("\n", trim: true)
|> Enum.map(&amp;String.split(&amp;1, [",", " -> "]))
|> Enum.map(fn [x1, y1, x2, y2] ->
  {
    {String.to_integer(x1), String.to_integer(y1)},
    {String.to_integer(x2), String.to_integer(y2)}
  }
end)
|> Enum.filter(fn {{x1, y1}, {x2, y2}} -> x1 == x2 or y1 == y2 end)
|> Enum.flat_map(fn {{x1, y1}, {x2, y2}} ->
  for x <- x1..x2, y <- y1..y2, do: {x, y}
end)
|> Enum.frequencies()
|> Enum.count(fn {_, count} -> count > 1 end)
input =
  Setup.get_input("Input")
  |> String.split("\n", trim: true)
  |> Enum.map(&amp;String.split(&amp;1, [",", " -> "]))
  |> Enum.map(fn [x1, y1, x2, y2] ->
    {
      {String.to_integer(x1), String.to_integer(y1)},
      {String.to_integer(x2), String.to_integer(y2)}
    }
  end)

defmodule Part2 do
  def go(input) do
    input
    |> Enum.flat_map(fn
      {{x1, y1}, {x2, y2}} when x1 == x2 or y1 == y2 ->
        for x <- x1..x2, y <- y1..y2, do: {x, y}

      {{x1, y1}, {x2, y2}} ->
        step = abs(x2 - x1)
        {dx, dy} = {div(x2 - x1, step), div(y2 - y1, step)}

        for i <- 0..step, do: {x1 + i * dx, y1 + i * dy}
    end)
    |> Enum.frequencies()
    |> Enum.count(fn {_, count} -> count > 1 end)
  end
end
Part2.go(input)