Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

--- Day 5: Hydrothermal Venture ---

2021/elixir/day-05/day-05.livemd

— Day 5: Hydrothermal Venture —

Mix.install([
  {:kino, "~> 0.9.4"}
])

Section

# https://adventofcode.com/2021/day/5
input = Kino.Input.textarea("put you input here")
input2 = Kino.Input.textarea("")
path_to_tuples = fn [start, finish] ->
  {x1, y1} = String.split(start, ",") |> Enum.map(&String.to_integer/1) |> List.to_tuple()
  {x2, y2} = String.split(finish, ",") |> Enum.map(&String.to_integer/1) |> List.to_tuple()
  {{x1, y1}, {x2, y2}}
end
# filter horizontal/vertical lines only
filter_straight_lines = fn {{x1, y1}, {x2, y2}} ->
  x1 == x2 or y1 == y2
end
expand_path = fn 
  ({{x1, y1}, {x2, _y2}}) when x1 != x2->
    for x <- x1..x2, do: {x, y1}
  ({{x1, y1}, {_x2, y2}})  ->
    for y <- y1..y2, do: {x1, y}
end
# answer 6710
count_overlaps = fn list ->
  Enum.frequencies(list) |> Map.values() |> Enum.filter(&amp;(&amp;1 >= 2)) |> Enum.count()
end
a =
  Kino.Input.read(input2)
  |> String.split("\n", trim: true)
  |> Enum.map(&amp;String.split(&amp;1, " -> ", trim: true))
  |> Enum.map(&amp;path_to_tuples.(&amp;1))
  |> Enum.filter(&amp;filter_straight_lines.(&amp;1))
  |> Enum.map(&amp;expand_path.(&amp;1))
  |> List.flatten()
  |> count_overlaps.()

Part 2

filter_diagonal_lines = fn {{x1, y1}, {x2, y2}} ->
  x1 != x2 and y1 != y2
end
straights =
  Kino.Input.read(input2)
  |> String.split("\n", trim: true)
  |> Enum.map(&amp;String.split(&amp;1, " -> ", trim: true))
  |> Enum.map(&amp;path_to_tuples.(&amp;1))
  |> Enum.filter(fn x -> filter_straight_lines.(x) end)
  |> Enum.map(&amp;expand_path.(&amp;1))
  |> List.flatten()
expand_diagonal_path = fn {{x1, y1}, {x2, y2}} = var ->
  # IO.inspect(var)
  cond do
    x1 == y1 and x2 == y2 ->
      for x <- x1..x2, do: {x, x}

    x1 == y2 and y1 == x2 ->
      Enum.zip(x1..x2, y1..y2)

    x1 - y1 == x2 - y2 ->
      Enum.zip(x1..x2, y1..y2)

    y1 - x1 == y2 - x2 ->
      Enum.zip(x1..x2, y1..y2)

    x1 - x2 == y1 - y2 ->
      Enum.zip(x1..x2, y1..y2)

    x2 - x1 == y2 - y1 ->
      Enum.zip(x1..x2, y1..y2)

    (x1 == y1 or x2 == y2) and abs(x2 - x1) == abs(y2 - x1) ->
      Enum.zip(x1..x2, y1..y2)

    x1 + y1 == x2 + y2 ->
      Enum.zip(x1..x2, y1..y2)
  end
end

expand_diagonal_path.({{98, 891}, {972, 17}})
diagonals =
  Kino.Input.read(input2)
  |> String.split("\n", trim: true)
  |> Enum.map(&amp;String.split(&amp;1, " -> ", trim: true))
  |> Enum.map(&amp;path_to_tuples.(&amp;1))
  |> Enum.filter(fn x -> filter_diagonal_lines.(x) end)
  |> Enum.map(&amp;expand_diagonal_path.(&amp;1))
  |> List.flatten()
(straights ++ diagonals)
|> count_overlaps.()