Day 6
This commit is contained in:
parent
ad64a23257
commit
7d5f3501c0
|
@ -0,0 +1,132 @@
|
||||||
|
defmodule Day6 do
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Parses a node from a string.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> Day6.parse_node("1, 6")
|
||||||
|
{1, 6}
|
||||||
|
|
||||||
|
"""
|
||||||
|
def parse_node(s) do
|
||||||
|
[x, y] = String.split(s, ", ")
|
||||||
|
{
|
||||||
|
x |> String.to_integer(),
|
||||||
|
y |> String.to_integer()
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Distance between two coordinates.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> Day6.distance({0, 0}, {3, 7})
|
||||||
|
10
|
||||||
|
"""
|
||||||
|
def distance({x1, y1}, {x2, y2}) do
|
||||||
|
abs(x2 - x1) + abs(y2 - y1)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> Day6.nearest_node({0, 0}, [{-1, -1}, {1, 2}, {0, 1}, {3, 4}])
|
||||||
|
{0, 1}
|
||||||
|
iex> Day6.nearest_node({0, 0}, [{0, -1}, {1, 0}])
|
||||||
|
nil
|
||||||
|
"""
|
||||||
|
def nearest_node(point, all) do
|
||||||
|
nearest =
|
||||||
|
all
|
||||||
|
|> Enum.map(fn other -> {other, distance(point, other)} end)
|
||||||
|
|
||||||
|
{min_pt, min_dist} = nearest |> Enum.min_by(fn {_pt, dist} -> dist end)
|
||||||
|
|
||||||
|
case Enum.count(nearest, fn {_pt, dist} -> dist == min_dist end) do
|
||||||
|
1 -> min_pt
|
||||||
|
_ -> nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def largest_region(nodes, grid_size \\ 1000) do
|
||||||
|
{areas, infinite_area_nodes} =
|
||||||
|
0..grid_size
|
||||||
|
|> Enum.reduce({%{}, []}, fn y, acc ->
|
||||||
|
0..grid_size
|
||||||
|
|> Enum.reduce(acc, fn x, {areas, infinite_area_nodes} ->
|
||||||
|
pt = {x, y}
|
||||||
|
case nearest_node(pt, nodes) do
|
||||||
|
nil ->
|
||||||
|
{areas, infinite_area_nodes}
|
||||||
|
nearest ->
|
||||||
|
if x == 0 or y == 0 or x == grid_size or y == grid_size do
|
||||||
|
{
|
||||||
|
areas,
|
||||||
|
[nearest | infinite_area_nodes]
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Map.update(areas, nearest, 1, &(&1 + 1)),
|
||||||
|
infinite_area_nodes
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
areas
|
||||||
|
|> Enum.reject(fn {node, _area} -> node in infinite_area_nodes end)
|
||||||
|
|> Enum.max_by(fn {_node, area} -> area end)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Sums the distance between the point and each of the nodes.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> Day6.total_distances({0, 0}, [{0, 2}, {-2, 0}, {3, 5}])
|
||||||
|
12
|
||||||
|
"""
|
||||||
|
def total_distances(pt, nodes) do
|
||||||
|
nodes
|
||||||
|
|> Enum.map(fn node -> distance(pt, node) end)
|
||||||
|
|> Enum.sum()
|
||||||
|
end
|
||||||
|
|
||||||
|
def region_near_most(nodes, grid_size \\ 1000, max_dist \\ 10000) do
|
||||||
|
0..grid_size
|
||||||
|
|> Enum.reduce([], fn y, acc ->
|
||||||
|
0..grid_size
|
||||||
|
|> Enum.reduce(acc, fn x, acc ->
|
||||||
|
pt = {x, y}
|
||||||
|
cond do
|
||||||
|
total_distances(pt, nodes) < max_dist ->
|
||||||
|
[pt | acc]
|
||||||
|
true ->
|
||||||
|
acc
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse_input() do
|
||||||
|
File.read!("lib/day6/input.txt")
|
||||||
|
|> String.split("\n", trim: true)
|
||||||
|
|> Enum.map(&parse_node/1)
|
||||||
|
end
|
||||||
|
|
||||||
|
def part1() do
|
||||||
|
parse_input()
|
||||||
|
|> largest_region()
|
||||||
|
end
|
||||||
|
|
||||||
|
def part2() do
|
||||||
|
parse_input()
|
||||||
|
|> region_near_most()
|
||||||
|
|> Enum.count()
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,50 @@
|
||||||
|
227, 133
|
||||||
|
140, 168
|
||||||
|
99, 112
|
||||||
|
318, 95
|
||||||
|
219, 266
|
||||||
|
134, 144
|
||||||
|
306, 301
|
||||||
|
189, 188
|
||||||
|
58, 334
|
||||||
|
337, 117
|
||||||
|
255, 73
|
||||||
|
245, 144
|
||||||
|
102, 257
|
||||||
|
255, 353
|
||||||
|
303, 216
|
||||||
|
141, 167
|
||||||
|
40, 321
|
||||||
|
201, 50
|
||||||
|
60, 188
|
||||||
|
132, 74
|
||||||
|
125, 199
|
||||||
|
176, 307
|
||||||
|
204, 218
|
||||||
|
338, 323
|
||||||
|
276, 278
|
||||||
|
292, 229
|
||||||
|
109, 228
|
||||||
|
85, 305
|
||||||
|
86, 343
|
||||||
|
97, 254
|
||||||
|
182, 151
|
||||||
|
110, 292
|
||||||
|
285, 124
|
||||||
|
43, 223
|
||||||
|
153, 188
|
||||||
|
285, 136
|
||||||
|
334, 203
|
||||||
|
84, 243
|
||||||
|
92, 185
|
||||||
|
330, 223
|
||||||
|
259, 275
|
||||||
|
106, 199
|
||||||
|
183, 205
|
||||||
|
188, 212
|
||||||
|
231, 150
|
||||||
|
158, 95
|
||||||
|
174, 212
|
||||||
|
279, 97
|
||||||
|
172, 131
|
||||||
|
247, 320
|
|
@ -0,0 +1,4 @@
|
||||||
|
defmodule Day6Test do
|
||||||
|
use ExUnit.Case
|
||||||
|
doctest Day6
|
||||||
|
end
|
Loading…
Reference in New Issue