====== Day 8: Resonant Collinearity ====== Die heutige Schwierigkeit hängt stark vom individuellen Wissenstand von Java ab. Für eine effiziente Lösung ist es einerseits wichtig, sich vom zweidimensionalen Karten-Modell zu lösen und alles nur auf "Zahlenebene" zu lösen. Zum anderen sollte man am besten eine **HashMap** und ein **Set** (Menge) als Datenstrukturen nutzen. Durch diese Vielzahl an komplexeren Datenstrukturen würde ich die durchschnittliche Schwierigkeit dieses Tages recht hoch einschätzen. ===== Teil 1 ===== Es sei hier nur die (kommentierte) Lösung gezeigt: ++++ Lösungsvorschlag | public void partOne() { int width = inputLines.get(0).length(); int height = inputLines.size(); // Eine HashMap, die pro Character alle zugehörigen Antennen-Koordinaten (je als zweistelliges Array) speichert HashMap> antennas = new HashMap(); // speichere direkt jede Antenne in der HashMap for (int y = 0; y < height; y++) { String line = inputLines.get(y); for (int x = 0; x < width; x++) { char c = line.charAt(x); if (c != '.') { if (!antennas.containsKey(c)) { antennas.put(c, new ArrayList()); } antennas.get(c).add(new int[]{x,y}); } } } //Speichere die Antinodes-Koordinaten in einem Set (erlaubt keine Dopplungen) Set> antinodes = new HashSet(); // Greife dir der Reihe nach je alle Antennen, die zusammengehören (derselbe Name) for (ArrayList coords: antennas.values()) { // Iteriere in einer doppelten Schleife über alle paarweisen Kombiationen aller Antennen desselben Namens for (int i = 0; i < coords.size(); i++) { for (int j = i+1; j < coords.size(); j++) { int[] antA = coords.get(i); int[] antB = coords.get(j); // Berechne die Distanz der zwei Antennen int diffX = antA[0] - antB[0]; int diffY = antA[1] - antB[1]; // Berechne, ob die erste benachbare Koordinate erlaubt ist int newX1 = antA[0]+diffX; int newY1 = antA[1]+diffY; if (newX1 >= 0 && newX1 < width && newY1 >= 0 && newY1 < height) { antinodes.add(Arrays.asList(newX1, newY1)); } // Berechne, ob die zweite benachbare Koordinate erlaubt ist int newX2 = antB[0]-diffX; int newY2 = antB[1]-diffY; if (newX2 >= 0 && newX2 < width && newY2 >= 0 && newY2 < height) { antinodes.add(Arrays.asList(newX2, newY2)); } } } } System.out.println(antinodes.size()); } ++++ ===== Teil 2 ===== Für Teil 2 sind nur wenige Änderungen nötig. In der Lösung befinden sich Kommentare nur dort, wo eine Änderung/Erweiterung nötig ist. ++++ Lösungsvorschlag | public void partTwo() { int width = inputLines.get(0).length(); int height = inputLines.size(); HashMap> antennas = new HashMap(); for (int y = 0; y < height; y++) { String line = inputLines.get(y); for (int x = 0; x < width; x++) { char c = line.charAt(x); if (c != '.') { if (!antennas.containsKey(c)) { antennas.put(c, new ArrayList()); } antennas.get(c).add(new int[]{x,y}); } } } Set> antinodes = new HashSet(); for (ArrayList coords: antennas.values()) { for (int i = 0; i < coords.size(); i++) { for (int j = i+1; j < coords.size(); j++) { int[] antA = coords.get(i); int[] antB = coords.get(j); // nun zählen auch die Antennenkoordinaten selbst als Antinodes antinodes.add(Arrays.asList(antA[0], antA[1])); antinodes.add(Arrays.asList(antB[0], antB[1])); int diffX = antA[0] - antB[0]; int diffY = antA[1] - antB[1]; // von antA positiv laufen // laufe solange, bis man sich außerhalb der Map befindet int mult = 1; while(true) { int newX = antA[0]+(diffX*mult); int newY = antA[1]+(diffY*mult); if (newX >= 0 && newX < width && newY >= 0 && newY < height) { antinodes.add(Arrays.asList(newX, newY)); } else { break; } mult++; } // von antB negativ laufen mult = 1; while(true) { int newX = antB[0]-(diffX*mult); int newY = antB[1]-(diffY*mult); if (newX >= 0 && newX < width && newY >= 0 && newY < height) { antinodes.add(Arrays.asList(newX, newY)); } else { break; } mult++; } } } } System.out.println(antinodes.size()); } ++++