aoc2024

Advent of Code 2024
Log | Files | Refs | README

commit b1aab78ac3d97cc2c4ccf5cfdc7de126278e1f2f
parent 7968d9cf758aa41788c775127ff3bfd74129de41
Author: Martin Ashby <martin@ashbysoft.com>
Date:   Tue, 31 Dec 2024 00:11:19 +0000

Day 8 pt2

Diffstat:
Asrc/main/java/day8_pt2.java | 107+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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; + } +}