Day 6: Chronal Coordinates - Advent of Code 2018

I did the Advent of Code 2018 day 6 challenge in Elixir! Parts one and two are as follows:

defmodule Day6 do
  def part1(input) do
    {_infinites, finites} =
      input
      |> read_input()
      |> create_grid()
      |> group_by_infinites()

    {_coordinates, layout} =
      finites
      |> Enum.group_by(fn {x, y, _dist} -> {x, y} end)
      |> Enum.max_by(fn {_, v} -> length(v) end)

    length(layout)
  end

  def part2(input) do
    {max_x, max_y, coordinates} =
      input
      |> read_input()

    for x <- 0..max_x,
        y <- 0..max_y do
      coordinates
      |> Enum.reduce(0, fn {point_x, point_y}, acc ->
        distance = abs(x - point_x) + abs(y - point_y)
        distance + acc
      end)
    end
    |> Enum.filter(&(&1 < 10_000))
    |> Enum.count()
  end

  defp read_input(input) do
    {max_x, max_y, coordinates} =
      input
      |> File.read!()
      |> String.trim()
      |> String.split("\n", trim: true)
      |> Enum.reduce({-1, -1, []}, fn line, {max_x, max_y, coordinates} ->
        [x, y] = String.split(line, ", ")
        x = String.to_integer(x)
        y = String.to_integer(y)
        coordinate = {x, y}
        max_x = if x > max_x, do: x, else: max_x
        max_y = if y > max_y, do: y, else: max_y
        {max_x, max_y, [coordinate | coordinates]}
      end)

    {max_x, max_y, Enum.reverse(coordinates)}
  end

  defp create_grid({max_x, max_y, coordinates}) do
    for x <- 0..max_x,
        y <- 0..max_y do
      [{px, py, dist1}, {_, _, dist2} | _] =
        Enum.map(coordinates, fn {point_x, point_y} ->
          distance = abs(x - point_x) + abs(y - point_y)
          {point_x, point_y, distance}
        end)
        |> Enum.sort_by(fn {_, _, distance} -> distance end)

      if dist1 == dist2 do
        nil
      else
        cond do
          x == 0 ->
            {:infinite, px, py}

          x == max_x ->
            {:infinite, px, py}

          y == 0 ->
            {:infinite, px, py}

          y == max_y ->
            {:infinite, px, py}

          true ->
            {px, py, dist1}
        end
      end
    end
  end

  defp group_by_infinites(grid) do
    Enum.reduce(grid, {MapSet.new(), []}, fn
      nil, acc ->
        acc

      {:infinite, px, py}, {infinites, finites} ->
        {MapSet.put(infinites, {px, py}), finites}

      {px, py, dist}, {infinites, finites} ->
        if MapSet.member?(infinites, {px, py}) do
          {infinites, finites}
        else
          {infinites, [{px, py, dist} | finites]}
        end
    end)
  end
end

# r Day6; :aoc2018 |> :code.priv_dir() |> Path.join("day6.txt") |> Day6.part1()
# r Day6; :aoc2018 |> :code.priv_dir() |> Path.join("day6.txt") |> Day6.part2()
 

 

Simon Escobar Benitez
Author

Simon Escobar Benitez

Colombian Software Engineer (Erlang Solutions)

ARTICLES: 8

Day 11: Chronal Charge - Advent of Code 2018

I did the Advent of Code 2018 day 11 challenge in Elixir! Parts one and two are as follows:

READ MORE

Day 10: The Stars Align - Advent of Code 2018

I did the Advent of Code 2018 day 10 challenge in Elixir! Parts one and two are as follows:

READ MORE

Day 7: The Sum of Its Parts - Advent of Code 2018

I did the Advent of Code 2018 day 7 challenge in Elixir! Parts one and two are as follows:

READ MORE

Day 5: Alchemical Reduction - Advent of Code 2018

I did the Advent of Code 2018 day 5 challenge in Elixir! Parts one and two are as follows:

READ MORE

Day 4: Repose Record - Advent of Code 2018

I did the Advent of Code 2018 day 4 challenge in Elixir! Parts one and two are as follows:

READ MORE

Day 3: No matter how you slice it - Advent of Code 2018

I did the Advent of Code 2018 day 3 challenge in Elixir! Parts one and two are as follows:

READ MORE

Day 2: Inventory Management System - Advent of Code 2018

I did the Advent of Code 2018 day 2 challenge in Elixir! Parts one and two are as follows:

READ MORE

Day 1: Chronal Calibration - Advent of Code 2018

Advent of Code 2018 - Day 1 solution in Elixir! #AdventOfBEAM

READ MORE