Skip to content

Latest commit

 

History

History
137 lines (104 loc) · 2.58 KB

day5.livemd

File metadata and controls

137 lines (104 loc) · 2.58 KB

Day 5

Setup

Mix.install([
  {:kino, "~> 0.4.1"}
])
input = Kino.Input.textarea("Input:")

Modules

defmodule Vents do
  def init(string, only_hz_vt \\ false) do
    vectors =
      string
      |> String.split("\n")
      |> Enum.map(fn elem ->
        [_, sx, sy, ex, ey] = Regex.run(~r/(\d*),(\d*) -> (\d*),(\d*)/, elem)

        {
          {String.to_integer(sx), String.to_integer(sy)},
          {String.to_integer(ex), String.to_integer(ey)}
        }
      end)

    if only_hz_vt do
      Enum.reject(vectors, fn {{sx, sy}, {ex, ey}} -> sx != ex and sy != ey end)
    else
      vectors
    end
  end

  def get_dims(list_of_vectors) do
    list_of_vectors
    |> Enum.reduce({0, 0}, fn {{start_x, start_y}, {finish_x, finish_y}}, {max_x, max_y} ->
      new_max_x = Enum.max([start_x, finish_x, max_x])
      new_max_y = Enum.max([start_y, finish_y, max_y])

      {new_max_x, new_max_y}
    end)
  end

  def empty_grid(dim_x, dim_y) do
    for x <- 0..dim_x, y <- 0..dim_y, into: %{} do
      {{x, y}, 0}
    end
  end

  def print_grid(dim_x, dim_y, grid) do
    for x <- 0..dim_x, y <- 0..dim_y do
      if grid[{x, y}] == 0, do: IO.write("."), else: IO.write(grid[{x, y}])
      if y == dim_y, do: IO.puts("")
    end
  end

  def process(grid, []), do: grid

  def process(grid, [vector | rest]) do
    grid
    |> update_grid_with_vector(vector)
    |> process(rest)
  end

  def update_grid_with_vector(grid, {{sx, sy}, {sx, sy}}) do
    Map.update!(grid, {sx, sy}, fn v -> v + 1 end)
  end

  def update_grid_with_vector(grid, {{sx, sy}, {ex, ey}}) do
    new_grid = Map.update!(grid, {sx, sy}, fn v -> v + 1 end)

    new_sx =
      cond do
        sx > ex -> sx - 1
        sx < ex -> sx + 1
        sx == ex -> sx
      end

    new_sy =
      cond do
        sy > ey -> sy - 1
        sy < ey -> sy + 1
        sy == ey -> sy
      end

    new_vector = {{new_sx, new_sy}, {ex, ey}}

    update_grid_with_vector(new_grid, new_vector)
  end
end

Part 1

vents =
  input
  |> Kino.Input.read()
  |> Vents.init(true)

{dim_x, dim_y} = Vents.get_dims(vents)

grid = Vents.empty_grid(dim_x, dim_y)

# Vents.print_grid(dim_x, dim_y, grid)
# IO.puts("")

new_grid = Vents.process(grid, vents)

# Vents.print_grid(dim_x, dim_y, new_grid)

Map.values(new_grid)
|> Enum.count(fn i -> i > 1 end)

Part 2

vents =
  input
  |> Kino.Input.read()
  |> Vents.init(false)

{dim_x, dim_y} = Vents.get_dims(vents)

grid = Vents.empty_grid(dim_x, dim_y)

new_grid = Vents.process(grid, vents)

Map.values(new_grid)
|> Enum.count(fn i -> i > 1 end)