This commit is contained in:
Shadowfacts 2018-12-06 20:12:31 -05:00
parent ad64a23257
commit 7d5f3501c0
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
3 changed files with 186 additions and 0 deletions

132
lib/day6/day6.ex Normal file
View File

@ -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

50
lib/day6/input.txt Normal file
View File

@ -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

4
test/day6_test.exs Normal file
View File

@ -0,0 +1,4 @@
defmodule Day6Test do
use ExUnit.Case
doctest Day6
end