Day 8. A bit ugly, but got it done quickly

master
Dustin Swan 4 weeks ago
parent f4c72675e2
commit 83aacf70c7
Signed by: dustinswan
GPG Key ID: AB49BD6B2B3A6377

@ -0,0 +1,50 @@
.....................U.........w..................
l.................................................
...........o.a................U...w...............
............................................W.....
..........T....................s.............7....
.............................................W....
.........T..............4....n.d.H.........5......
......T.....oj...U.....n...w......H...........z...
.G..x..........................E.....V..H.........
.........a....................d....s.......7w.....
...j....r.............o.............V.......d...W.
.......r..J.Goa.U...............n................z
.........Jj.........M..........Pv.................
...J...........t..3..M..............sLV...........
...................t................n.............
....r...........X...........M........v............
...x....t......I......a.PM...............W........
...........1.Bj....I........vO.h.dL...............
.........6....Rr......B...X........h..5v.L..z.....
......1G...........x.....3B.......5...............
.................B....0..........4..E.............
.....................X.....5..h....P....f.....D...
.......1........J.....eK..........................
..................I....R....K...........k.........
......G..................O........................
...........H...9...............K8.P.4..k..E.......
............1....3.............8.F.............f..
.........................4........................
.l...........X............9.......................
....N.................R...t.e.....................
...g............3..R.........e....h.........f.....
...........................e......i...............
................2...I.7..9..O.....s.........k.....
....................6...9E.............F..O.......
........................KN........................
.......g......................Z.........F..f...Y..
...........................A....i.................
...........6g...b........8.......y.....S..........
..l.....6.....m...............8...................
....u..m...b...............p...A..................
..............b.p........................k........
....m......2...........Z..y....i..................
........g2.....b.........i....D..ZF...............
......2.0...........p............N..........A.....
...m.............S...y........A...Z...N...........
..S..l..........................................Y.
........S....0u.................y......DY.........
...........0.........................D............
.................u...................p...Y........
.......u..........................................

@ -0,0 +1,129 @@
defmodule Day7 do
def run do
map =
File.read!("data.txt")
|> String.split("\n")
|> Enum.drop(-1)
|> Enum.map(&String.graphemes(&1))
height = length(map)
width = length(hd(map))
dbg(map)
# generate list of antennas
# flatten the map, add indices, if char isn't a dot, grab width and height, stick them in a map
antennas =
Enum.concat(map)
|> Enum.with_index()
|> Enum.reduce(%{}, fn {char, idx}, acc ->
if char != "." do
location = {div(idx, height), rem(idx, width)}
Map.update(acc, char, [location], fn list -> [location | list] end)
else
acc
end
end)
dbg(antennas, charlists: :as_lists)
# generate all possible pairs of locations for this antenna
pairs =
Enum.map(antennas, fn {char, locations} ->
pairs =
for x <- 0..(length(locations) - 2),
y <- (x + 1)..(length(locations) - 1),
x != y,
do: {Enum.at(locations, x), Enum.at(locations, y)}
{char, pairs}
end)
dbg(pairs, charlists: :as_lists)
# find antinodes
antinodes =
Enum.reduce(pairs, MapSet.new(), fn {char, nodes}, acc ->
Enum.reduce(nodes, acc, fn {{x1, y1}, {x2, y2}}, acc2 ->
{dx, dy} = {x2 - x1, y2 - y1}
new_points =
if (dx > 0 and dy > 0) or (dx < 0 and dy < 0) do
# slope \
[
{min(x1, x2) - abs(dx), min(y1, y2) - abs(dy)},
{max(x1, x2) + abs(dx), max(y1, y2) + abs(dy)}
]
else
# slope /
[
{max(x1, x2) + abs(dx), min(y1, y2) - abs(dy)},
{min(x1, x2) - abs(dx), max(y1, y2) + abs(dy)}
]
end
# ensure in bounds
|> Enum.filter(fn {x, y} -> x >= 0 and y >= 0 and x < height and y < width end)
# add each new point to the MapSet
Enum.reduce(new_points, acc2, fn point, acc3 ->
MapSet.put(acc3, point)
end)
end)
end)
dbg(MapSet.size(antinodes))
antinodes2 =
Enum.reduce(pairs, MapSet.new(), fn {char, nodes}, acc ->
Enum.reduce(nodes, acc, fn {{x1, y1}, {x2, y2}}, acc2 ->
{dx, dy} = {x2 - x1, y2 - y1}
# generate points along these lines until out of bounds
# roughly how many times do we need to loop? we'll stop early if both points are out of bounds
loops = trunc(min(abs(width / dy), abs(height / dx)))
new_points =
Enum.reduce_while(1..(loops + 1), [], fn idx, acc ->
points =
if (dx > 0 and dy > 0) or (dx < 0 and dy < 0) do
# slope \
[
{min(x1, x2) - abs(dx) * idx, min(y1, y2) - abs(dy) * idx},
{max(x1, x2) + abs(dx) * idx, max(y1, y2) + abs(dy) * idx}
]
else
# slope /
[
{max(x1, x2) + abs(dx) * idx, min(y1, y2) - abs(dy) * idx},
{min(x1, x2) - abs(dx) * idx, max(y1, y2) + abs(dy) * idx}
]
end
|> Enum.filter(fn {x, y} -> x >= 0 and y >= 0 and x < height and y < width end)
if length(points) == 0 do
{:halt, points ++ acc}
else
{:cont, points ++ acc}
end
end)
# add each new point to the MapSet
Enum.reduce(new_points, acc2, fn point, acc3 ->
MapSet.put(acc3, point)
end)
end)
end)
# add all the original antennae to the MapSet
part2 =
Enum.reduce(antennas, antinodes2, fn {char, points}, acc ->
Enum.reduce(points, acc, fn point, acc2 ->
MapSet.put(acc2, point)
end)
end)
dbg(MapSet.size(part2))
end
end
Day7.run()

@ -0,0 +1,12 @@
............
........0...
.....0......
.......0....
....0.......
......A.....
............
............
........A...
.........A..
............
............

@ -0,0 +1,10 @@
T.........
...T......
.T........
..........
..........
..........
..........
..........
..........
..........
Loading…
Cancel
Save