Skip to content

Latest commit

 

History

History
99 lines (76 loc) · 2.13 KB

day05.livemd

File metadata and controls

99 lines (76 loc) · 2.13 KB

Advent of Code 2021 - Day 5

Puzzle description

Hydrothermal Venture

You come across a field of hydrothermal vents on the ocean floor

They tend to form in lines.

vent_lines =
  File.read!("inputs/day05.txt")
  |> String.split("\n", trim: true)
  |> Enum.map(fn line ->
    [point1, point2] = String.split(line, " -> ")
    [x1, y1] = String.split(point1, ",")
    [x2, y2] = String.split(point2, ",")

    {[String.to_integer(x1), String.to_integer(y1)],
     [String.to_integer(x2), String.to_integer(y2)]}
  end)

Avoid the most dangerous areas

For now, only consider horizontal and vertical lines: lines where either y1 = y2 or x1 = x2.

defmodule Line do
  def horizontal_or_vertical?({[x1, y1], [x2, y2]}), do: y1 == y2 or x1 == x2
end

orthogonal_lines = Enum.filter(vent_lines, &Line.horizontal_or_vertical?/1)

Determine the number of points where at least two lines overlap.

defmodule Vents do
  def points([{[x1, y1], [x2, y2]} | lines], points) do
    new_points = for x <- x1..x2, y <- y1..y2, do: [x, y]
    points(lines, points ++ new_points)
  end

  def points([], points) do
    points
  end
end

defmodule Lines do
  def count_overlapping(lines) do
    lines
    |> Enum.frequencies()
    |> Enum.filter(fn {_point, count} -> count >= 2 end)
    |> Enum.count()
  end
end

overlapping_orthogonal =
  orthogonal_lines
  |> Vents.points([])
  |> Lines.count_overlapping()

Now consider diagonal lines as well

defmodule Vents2 do
  def points([{[x1, y1], [x2, y2]} | lines], points) do
    new_points =
      if y1 == y2 or x1 == x2 do
        for x <- x1..x2, y <- y1..y2, do: [x, y]
      else
        Enum.zip_with(x1..x2, y1..y2, fn x, y -> [x, y] end)
      end

    points(lines, points ++ new_points)
  end

  def points([], points) do
    points
  end
end

overlapping_with_diagonal =
  vent_lines
  |> Vents2.points([])
  |> Lines.count_overlapping()

Check that my answers are still correct after refactoring

overlapping_orthogonal == 4728 && overlapping_with_diagonal == 17717