From 83aacf70c7f7727cff202eae9ca1a080698c93ea Mon Sep 17 00:00:00 2001 From: Dustin Swan Date: Sun, 8 Dec 2024 00:12:12 -0700 Subject: [PATCH] Day 8. A bit ugly, but got it done quickly --- day8/data.txt | 50 +++++++++++++++++++ day8/main.exs | 129 +++++++++++++++++++++++++++++++++++++++++++++++++ day8/test.txt | 12 +++++ day8/test2.txt | 10 ++++ 4 files changed, 201 insertions(+) create mode 100644 day8/data.txt create mode 100644 day8/main.exs create mode 100644 day8/test.txt create mode 100644 day8/test2.txt diff --git a/day8/data.txt b/day8/data.txt new file mode 100644 index 0000000..e99bc0a --- /dev/null +++ b/day8/data.txt @@ -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.......................................... diff --git a/day8/main.exs b/day8/main.exs new file mode 100644 index 0000000..fcf04f4 --- /dev/null +++ b/day8/main.exs @@ -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() diff --git a/day8/test.txt b/day8/test.txt new file mode 100644 index 0000000..78a1e91 --- /dev/null +++ b/day8/test.txt @@ -0,0 +1,12 @@ +............ +........0... +.....0...... +.......0.... +....0....... +......A..... +............ +............ +........A... +.........A.. +............ +............ diff --git a/day8/test2.txt b/day8/test2.txt new file mode 100644 index 0000000..023061c --- /dev/null +++ b/day8/test2.txt @@ -0,0 +1,10 @@ +T......... +...T...... +.T........ +.......... +.......... +.......... +.......... +.......... +.......... +.......... \ No newline at end of file