Advent of Code 2023 - Day 11

Hello, awesome community! Ukrainian Erlanger checking in on this marvelous Monday :metal:. It’s Day 11 in the intriguing journey of Advent of Code, and a fresh puzzle awaits your problem-solving prowess. As you delve into today’s challenge, share your brilliant code solutions in the comments below - let’s inspire and learn from each other. Here’s to a productive Monday filled with coding triumphs. Happy coding, folks! :blush:

2 Likes

My day 11 solution:

defmodule Aoc.Eleven do
  def parse(string) do
    string
    |> String.split("\n", trim: true)
    |> Enum.map(&String.graphemes/1)
    |> load()
  end

  def load(data) do
    for {line, y} <- Enum.with_index(data), {i, x} <- Enum.with_index(line), into: %{} do
      {{x, y}, i}
    end
  end

  def part_one(input) do
    input
    |> expand(2)
    |> distance_sum()
  end

  def part_two(input) do
    input
    |> expand(1_000_000)
    |> distance_sum()
  end

  def distance_sum(map) do
    map
    |> Map.filter(fn {i, v} -> v != "." end)
    |> Map.keys()
    |> pairs()
    |> Enum.map(fn {a, b} -> distance(a, b) end)
    |> Enum.sum()
  end

  def expand(map, factor) do
    {ys, xs} = map |> Map.keys() |> Enum.max()

    empty_rows = for y <- 0..ys, Enum.all?(0..xs, &(Map.get(map, {&1, y}) == ".")), do: y
    empty_cols = for x <- 0..xs, Enum.all?(0..ys, &(Map.get(map, {x, &1}) == ".")), do: x

    for y <- 0..ys, x <- 0..ys, into: %{} do
      {{x + (factor - 1) * after_n(x, empty_cols), y + (factor - 1) * after_n(y, empty_rows)},
       Map.get(map, {x, y})}
    end
  end

  def after_n(n, list) do
    Enum.reduce_while(list, 0, fn x, acc ->
      if x < n do
        {:cont, acc + 1}
      else
        {:halt, acc}
      end
    end)
  end

  def pairs([]), do: []

  def pairs([a | rest] = list) do
    for b <- rest do
      {a, b}
    end ++ pairs(rest)
  end

  def distance({x1, y1}, {x2, y2}) do
    abs(x1 - x2) + abs(y1 - y2)
  end
end

input = File.read!("priv/11.txt") |> Aoc.Eleven.parse()

input |> Aoc.Eleven.part_one() |> IO.inspect(label: "part 1")
input |> Aoc.Eleven.part_two() |> IO.inspect(label: "part 2")

1 Like
2 Likes