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()
 

 

Author

Simon Escobar Benitez

Colombian Software Engineer (Erlang Solutions)

Upcoming conferences

Start booking your calendar with more Code Sync conferences happening across the globe. We will be slowly releasing more dates, in the meantime here is what we’ve planned already:

All conferences

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