Created
December 9, 2018 21:18
-
-
Save jemmyw/d70f6c0e2614e1761a50f640f9078d35 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule Danger do | |
def parse(str) when is_bitstring(str) do | |
str | |
|> String.split("\n") | |
|> parse() | |
|> Enum.with_index() | |
|> Enum.map(fn {c, i} -> | |
{c, [?a + i] |> to_string} | |
end) | |
end | |
def parse([]), do: [] | |
def parse([str | t]) do | |
[ | |
str |> String.split(~r/, /) |> Enum.map(&String.to_integer(&1)) |> List.to_tuple() | |
| parse(t) | |
] | |
end | |
def unindex({c, _}), do: c | |
def distance({x1, y1}, {x2, y2}) do | |
abs(x1 - x2) + abs(y1 - y2) | |
end | |
def total_distance(_, []), do: 0 | |
def total_distance(c, [h | t]) do | |
distance(c, h |> unindex) + total_distance(c, t) | |
end | |
# Get the owning coordinate of a coord | |
def coord_id(coord, list, closest \\ {nil, -1}) | |
# no list, return acc | |
def coord_id(_, [], {c, _}), do: c | |
# self return self | |
def coord_id(coord, [{coord, index} | _], _), do: {coord, index |> String.upcase()} | |
# no acc, recurse with head | |
def coord_id(coord, [h | t], {nil, -1}) do | |
coord_id(coord, t, {h, distance(coord, h |> unindex)}) | |
end | |
# acc, calc if next distance is shorter | |
def coord_id(coord, [h | t], {c, d}) do | |
new_distance = distance(coord, h |> unindex) | |
# IO.inspect([coord, h |> unindex, d, new_distance]) | |
cond do | |
new_distance < d -> coord_id(coord, t, {h, new_distance}) | |
new_distance > d -> coord_id(coord, t, {c, d}) | |
new_distance == d -> coord_id(coord, t, {nil, d}) | |
end | |
end | |
def grid_size(list) do | |
list | |
|> Enum.map(&unindex/1) | |
|> Enum.reduce({0, 0}, fn {x1, y1}, {x2, y2} -> | |
{max(x1, x2), max(y1, y2)} | |
end) | |
end | |
def infinite?({_, i}, list) do | |
{w, h} = Danger.grid_size(list) | |
Enum.any? [ | |
{-1..w+1, [-1]}, | |
{-1..w+1, [h+1]}, | |
{[-1], -1..h+1}, | |
{[w+1], -1..h+1} | |
], fn {xr, yr} -> | |
Enum.any? xr, fn x -> | |
Enum.any? yr, fn y -> | |
case coord_id({x, y}, list) do | |
{_, ^i} -> true | |
_ -> false | |
end | |
end | |
end | |
end | |
end | |
def size({_, i}, list) do | |
{w, h} = Danger.grid_size(list) | |
Enum.reduce 0..h, 1, fn y, s -> | |
Enum.reduce 0..w, s, fn x, s -> | |
case coord_id({x, y}, list) do | |
{_, ^i} -> s + 1 | |
_ -> s | |
end | |
end | |
end | |
end | |
def size_region_lower_than(list, l) do | |
{w, h} = Danger.grid_size(list) | |
Enum.reduce 0..h, 0, fn y, s -> | |
Enum.reduce 0..w, s, fn x, s -> | |
d = total_distance({x, y}, list) | |
cond do | |
d < l -> s + 1 | |
true -> s | |
end | |
end | |
end | |
end | |
def biggest(out_of, list) do | |
Enum.reduce out_of, {nil, 0}, fn c, {p, s} -> | |
next_size = Danger.size(c, list) | |
cond do | |
next_size > s -> {c, next_size} | |
true -> {p, s} | |
end | |
end | |
end | |
def draw_grid(list) do | |
{w, h} = Danger.grid_size(list) | |
Enum.each(0..(h + 1), fn y -> | |
Enum.each(0..(w + 1), fn x -> | |
owner = Danger.coord_id({x, y}, list) | |
case owner do | |
nil -> IO.write(".") | |
{_, i} -> IO.write(i) | |
end | |
end) | |
IO.write("\n") | |
end) | |
end | |
end | |
list = File.read("6.txt") |> elem(1) |> Danger.parse() | |
# Part 1 | |
list |> Enum.reject(&(Danger.infinite?(&1, list))) |> Danger.biggest(list) |> IO.inspect() | |
# Part 2 | |
list |> Danger.size_region_lower_than(10000) |> IO.inspect |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment