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

Day 5 me

livebook/day-05.livemd

Day 5 me

Setup

Mix.install(
  [
    {:kino, "~> 0.4.1"}
  ],
  consolidate_protocols: false
)
input = Kino.Input.textarea("Please paste your input:")
# convert lines to list of tuples with four intergers
# [{0, 1, 2, 3},...]
lines =
  input
  |> Kino.Input.read()
  |> String.split("\n", trim: true)
  |> Enum.map(fn line ->
    line
    |> String.split([" -> ", ","])
    |> Enum.map(&String.to_integer/1)
    |> List.to_tuple()
  end)
defmodule Line do
  def generate_points({x1, y, x2, y}) do
    Enum.map(x1..x2, fn x -> {x, y} end)
  end

  def generate_points({x, y1, x, y2}) do
    Enum.map(y1..y2, fn y -> {x, y} end)
  end

  def generate_points({x1, y1, x2, y2}) do
    Enum.zip(x1..x2, y1..y2)
  end

  def is_diagonal({x1, y1, x2, y2}) when x1 != x2 and y1 != y2 do
    false
  end

  def is_diagonal({_, _, _, _}) do
    true
  end
end

lines =
  lines
  |> Enum.filter(&Line.is_diagonal/1)
  |> Enum.map(&Line.generate_points/1)
  |> Enum.reduce([], fn points, new_list ->
    Enum.concat(points, new_list)
  end)
  |> Enum.reduce(%{}, fn point, acc -> Map.update(acc, point, 1, &(&1 + 1)) end)

lines
Enum.each(0..9, fn y ->
  line =
    Enum.reduce(0..9, "", fn x, acc ->
      overlaps = Map.get(lines, {x, y})

      if overlaps == nil do
        Enum.join([acc, "."], " ")
      else
        # Enum.join([acc, " "], " ")
        Enum.join([acc, Integer.to_string(overlaps)], " ")
      end
    end)

  IO.puts(line)
end)

Part 1

lines
|> Map.to_list()
|> Enum.map(fn {_, x} ->
  if x > 1 do
    true
  end
end)
|> Enum.count(fn x ->
  if x do
    true
  end
end)

Part 2

lines =
  input
  |> Kino.Input.read()
  |> String.split("\n", trim: true)
  |> Enum.map(fn line ->
    line
    |> String.split([" -> ", ","])
    |> Enum.map(&String.to_integer/1)
    |> List.to_tuple()
  end)
lines =
  lines
  |> Enum.map(&Line.generate_points/1)
  |> Enum.reduce([], fn points, new_list ->
    Enum.concat(points, new_list)
  end)
  |> Enum.reduce(%{}, fn point, acc -> Map.update(acc, point, 1, &(&1 + 1)) end)
Enum.each(0..9, fn y ->
  line =
    Enum.reduce(0..9, "", fn x, acc ->
      overlaps = Map.get(lines, {x, y})

      if overlaps == nil do
        Enum.join([acc, "."], " ")
      else
        # Enum.join([acc, " "], " ")
        Enum.join([acc, Integer.to_string(overlaps)], " ")
      end
    end)

  IO.puts(line)
end)
lines
|> Map.to_list()
|> Enum.map(fn {_, x} ->
  if x > 1 do
    true
  end
end)
|> Enum.count(fn x ->
  if x do
    true
  end
end)