commit b1aab78ac3d97cc2c4ccf5cfdc7de126278e1f2f
parent 7968d9cf758aa41788c775127ff3bfd74129de41
Author: Martin Ashby <martin@ashbysoft.com>
Date: Tue, 31 Dec 2024 00:11:19 +0000
Day 8 pt2
Diffstat:
1 file changed, 107 insertions(+), 0 deletions(-)
diff --git a/src/main/java/day8_pt2.java b/src/main/java/day8_pt2.java
@@ -0,0 +1,107 @@
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.io.IOException;
+import java.io.BufferedReader;
+import java.io.StringReader;
+import java.util.Arrays;
+import java.util.List;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.ArrayList;
+
+public class day8_pt2 {
+ record Point(int x, int y) {
+ Vec diff(Point other) {
+ return new Vec(this.x - other.x, this.y - other.y);
+ }
+ }
+ record Vec(int x, int y) {
+ Vec mul(int scalar) {
+ return new Vec(this.x * scalar, this.y * scalar);
+ }
+ record DivRes(int scalar, boolean valid){}
+ // Divide one vector by another
+ // to return an exact integer result. Otherwise valid=false
+ DivRes div(Vec other) {
+ if (other.x == 0 && this.x != 0) {
+ return new DivRes(0, false);
+ } else if (other.y == 0 && this.y != 0) {
+ return new DivRes(0, false);
+ } else if (other.x == 0) {
+ return new DivRes(this.y / other.y, this.y % other.y == 0);
+ } else if (other.y == 0) {
+ return new DivRes(this.x / other.x, this.x % other.x == 0);
+ } else {
+ var my = this.y / other.y;
+ var mx = this.x / other.x;
+ return new DivRes(my, my == mx && this.y % other.y == 0 && this.x % other.x == 0);
+ }
+ }
+ }
+
+
+ public static void main(String[] args) throws IOException {
+ var input = Files.readString(Path.of(args[0]));
+ var grid = new BufferedReader(new StringReader(input))
+ .lines()
+ .toList();
+ // Just gonna do this the naïve way
+ // First pass get the sets of antennas
+ var height = grid.size();
+ var width = grid.getFirst().length();
+ var antennas = new HashMap<Character, ArrayList<Point>>();
+ for (var x = 0; x < width; x++) {
+ for (var y = 0; y < height; y++) {
+ var ch = grid.get(y).charAt(x);
+ if (ch != '.') {
+ var al = antennas.computeIfAbsent(ch, ignored -> new ArrayList<>());
+ al.add(new Point(x, y));
+ }
+ }
+ }
+ //System.out.printf("antennas = %s\n", antennas);
+ // Second pass calculate the distance to each antenna and check if we're an antinode
+ var ans = new HashSet<Point>();
+ var antss = antennas.values();
+ for (var x = 0; x < width; x++) {
+ for (var y = 0; y < height; y++) {
+ var pt = new Point(x, y);
+ for (var ants: antss) {
+ if (isAn(ants, pt)) {
+ ans.add(pt);
+ break; // no need to test other antenna sets
+ }
+ }
+ }
+ }
+
+ for (var y = 0; y < height; y++) {
+ for (var x = 0; x < width; x++) {
+ if (ans.contains(new Point(x, y))) {
+ System.out.print('#');
+ } else {
+ System.out.print(grid.get(y).charAt(x));
+ }
+ }
+ System.out.print('\n');
+ }
+ System.out.printf("day8, pt2 = %d\n", ans.size());
+ }
+
+ static boolean isAn(List<Point> ants, Point pt) {
+ for (var i=0; i<ants.size(); i++) {
+ for (var j=0; j<ants.size(); j++) {
+ if (i == j) continue;
+ var ant1 = ants.get(i);
+ var ant2 = ants.get(j);
+ var va = ant1.diff(ant2);
+ var v1 = pt.diff(ant1);
+ var dr = v1.div(va);
+ if (dr.valid) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}