Skip to content

Instantly share code, notes, and snippets.

@cleaver
Created December 12, 2023 19:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cleaver/bbc1d81eb57e252152dd45ce32e2d3a4 to your computer and use it in GitHub Desktop.
Save cleaver/bbc1d81eb57e252152dd45ce32e2d3a4 to your computer and use it in GitHub Desktop.
Advent of Code 2023, Day 11 - Elixir
import AOC
import InputHelpers
aoc 2023, 11 do
@moduledoc """
https://adventofcode.com/2023/day/11
"""
@row_coord 0
@column_coord 1
@doc """
iex> p1(example_string())
"""
def p1(input) do
input
|> parse_input()
|> parse_galaxy_chart()
|> expand_universe()
|> calculate_distances()
|> Enum.sum()
end
def parse_galaxy_chart(input) do
input
|> Enum.with_index()
|> Enum.flat_map(fn {row, row_number} ->
find_galaxy_coords(row_number, row)
end)
end
def find_galaxy_coords(row_number, row) do
Regex.scan(~r/#/, row, return: :index)
|> Enum.map(fn [{index, _}] ->
{row_number, index}
end)
end
def expand_universe(galaxy_chart, expansion_amount \\ 1) do
galaxy_chart
|> expand_dimension(@column_coord, expansion_amount)
|> expand_dimension(@row_coord, expansion_amount)
end
def expand_dimension(galaxy_chart, coord_direction, expansion_amount) do
galaxy_chart
|> find_empty_space(coord_direction, expansion_amount)
|> Enum.reduce(galaxy_chart, fn empty_dimension, galaxy_chart ->
Enum.map(galaxy_chart, fn galaxy ->
case elem(galaxy, coord_direction) do
dimension when dimension > empty_dimension ->
move_galaxy(galaxy, coord_direction, expansion_amount)
_ ->
galaxy
end
end)
end)
end
def find_empty_space(galaxy_chart, coord, expansion_amount) do
populated_coords =
galaxy_chart
|> Enum.map(&elem(&1, coord))
|> Enum.uniq()
((Range.new(0, Enum.max(populated_coords))
|> Enum.to_list()) --
populated_coords)
|> expand_empty_space(expansion_amount)
end
def move_galaxy({row, column}, @column_coord, expansion_amount) do
{row, column + expansion_amount}
end
def move_galaxy({row, column}, @row_coord, expansion_amount) do
{row + expansion_amount, column}
end
def expand_empty_space(empty_space_list, expansion_amount, count \\ 0)
def expand_empty_space([empty_space | rest], expansion_amount, count) do
[empty_space + count | expand_empty_space(rest, expansion_amount, count + expansion_amount)]
end
def expand_empty_space([], _, _), do: []
def calculate_distances([galaxy | rest]) do
galaxy_distances =
calculate_distance(galaxy, rest)
galaxy_distances ++ calculate_distances(rest)
end
def calculate_distances([]), do: []
def calculate_distance(galaxy, [galaxy_2 | rest]) do
{row_1, column_1} = galaxy
{row_2, column_2} = galaxy_2
distance = abs(row_1 - row_2) + abs(column_1 - column_2)
[distance | calculate_distance(galaxy, rest)]
end
def calculate_distance(_, []), do: []
@doc """
iex> p2(example_string())
"""
def p2(input) do
input
|> parse_input()
|> parse_galaxy_chart()
|> expand_universe(999_999)
|> calculate_distances()
|> Enum.sum()
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment