### re: AoC Day 6: Chronal Coordinates VIEW POST

Here we go, this is my solution in Elixir.

The idea for part one is to first determine the maximum field, based on the min/max values of the x and y coordinates. Then, for each position in the field, determine the distance to each of the input coordinates, keeping track of the coordinate that is the closest to the position in the field. Once this information is calculated, we can determine the size of the largest area within the field.

Part two largely follows the same logic, but takes the sum of a position in the field to all input coordinates, instead of taking only the closest one.

Common:

defmodule AoC.DaySix.Common do
alias AoC.DaySix.{Coordinate, Field}

path
|> File.stream!()
|> Stream.map(&String.trim_trailing/1)
|> Enum.with_index()
|> Enum.map_reduce(%Field{}, fn {line, index}, field -> parse_input(line, index, field) end)
end

defp parse_input(line, index, field) do
coordinate = get_coordinate(line, index)
field = get_field(coordinate, field)
{coordinate, field}
end

defp get_coordinate(line, index) do
[x, y] = String.split(line, ",")
x = get_integer(x)
y = get_integer(y)
%Coordinate{id: index, x: x, y: y}
end

defp get_integer(string) do
string
|> String.trim()
|> String.to_integer()
end

defp get_field(coordinate, field) do
%Field{
min_x: min(coordinate.x, field.min_x),
min_y: min(coordinate.y, field.min_y),
max_x: max(coordinate.x, field.max_x),
max_y: max(coordinate.y, field.max_y)
}
end
end

Part one:

defmodule AoC.DaySix.PartOne do
alias AoC.DaySix.{Coordinate, Common}

def main() do
"lib/day6/input.txt"
|> get_distance()
|> Enum.filter(fn {_k, v} -> v != nil end)
|> Enum.reduce(%{}, fn {_, {[c], _}}, acc ->
Map.update(acc, c.id, 1, &(&1 + 1))
end)
|> Enum.reduce(0, fn {_, v}, acc -> max(v, acc) end)
end

defp get_distance({coordinates, field}) do
Enum.reduce(field.min_x..field.max_x, %{}, fn x, acc ->
Enum.reduce(field.min_y..field.max_y, acc, fn y, acc ->
get_field_distances(x, y, coordinates, field, acc)
end)
end)
end

defp get_field_distances(x, y, coordinates, field, acc) do
field_coordinate = %Coordinate{x: x, y: y}
max_distance = get_max_distance(field)

{result, distance} =
Enum.reduce(coordinates, {[], max_distance}, fn input_coordinate, {result, distance} ->
get_distance_to_coordinate(input_coordinate, field_coordinate, result, distance)
end)

result_distance =
case length(result) do
1 -> {result, distance}
_ -> nil
end

Map.put(acc, {x, y}, result_distance)
end

defp get_max_distance(field) do
get_manhattan_distance(%Coordinate{x: field.min_x, y: field.min_y}, %Coordinate{
x: field.max_x,
y: field.max_y
})
end

defp get_distance_to_coordinate(input_coordinate, field_coordinate, result, distance) do
distance_total = get_manhattan_distance(input_coordinate, field_coordinate)

cond do
distance_total == distance -> {[input_coordinate | result], distance}
distance_total < distance -> {[input_coordinate], distance_total}
true -> {result, distance}
end
end

defp get_manhattan_distance(c1, c2) do
abs(c1.x - c2.x) + abs(c1.y - c2.y)
end
end

Part two:

defmodule AoC.DaySix.PartTwo do
alias AoC.DaySix.{Common}

@max_region_size 10000

def main() do
"lib/day6/input.txt"
|> get_distance()
|> Enum.filter(fn {_k, v} -> v < @max_region_size end)
|> Enum.count()
end

defp get_distance({coordinates, field}) do
Enum.reduce(field.min_x..field.max_x, %{}, fn x, acc ->
Enum.reduce(field.min_y..field.max_y, acc, fn y, acc ->
result =
Enum.reduce(coordinates, 0, fn coordinate, result ->
get_total_distance(coordinate, x, y, result)
end)

Map.put(acc, {x, y}, result)
end)
end)
end

defp get_total_distance(coordinate, x, y, result) do
result + abs(coordinate.x - x) + abs(coordinate.y - y)
end
end
code of conduct - report abuse