day 8
Me ha llevado más trabajo en si leer y comprender correctamente el problema que luego la implementación en si.
Código
public class ResonantCollinearity {
private static final char EMPTY = '.';
private final int rows;
private final int cols;
private final Map<Character, List<Vector2>> antennasPerFrequency = new HashMap<>();
private Set<Vector2> antinodes;
public ResonantCollinearity(char[][] input) {
rows = input.length;
cols = input[0].length;
for(int row = 0; row < rows; row++){
for(int col = 0; col < cols; col++) {
if(input[row][col] != EMPTY) {
char frequency = input[row][col];
List<Vector2> antennaPositions = antennasPerFrequency.getOrDefault(frequency, new ArrayList<>());
antennaPositions.add(new Vector2(col, row));
antennasPerFrequency.putIfAbsent(frequency, antennaPositions);
}
}
}
}
public int solve(boolean countHarmonics) {
antinodes = new HashSet<>();
for(Map.Entry<Character,List<Vector2>> frequency : antennasPerFrequency.entrySet()) {
List<Vector2> antennas = frequency.getValue();
for(List<Vector2> pair : CollectionUtils.permutations(antennas)) {
findAntinodes(countHarmonics, pair.get(0), pair.get(1));
findAntinodes(countHarmonics, pair.get(1), pair.get(0));
}
}
return antinodes.size();
}
private void findAntinodes(boolean countHarmonics, Vector2 antennaA, Vector2 antennaB) {
Vector2 direction = Vector2.direction(antennaA, antennaB);
Vector2 antinode = new Vector2(antennaA);
do {
antinode.transform(direction);
if (isInbounds(antinode)) {
antinodes.add(new Vector2(antinode));
}
} while(isInbounds(antinode) && countHarmonics);
if(countHarmonics) {
antinodes.add(antennaA);
}
}
private boolean isInbounds(Vector2 antinodePos) {
return antinodePos.getY() >= 0 && antinodePos.getY() < rows && antinodePos.getX() >= 0 && antinodePos.getX() < cols;
}
}
He decidido probar esta vez a usar el método CollectionUtil.permutations de Apache Commons Collections4 para poder hacer un poco las veces de esas librerías tan chulis que tenéis en Python.
Así, en vez de un doble bucle para generar todas las permutaciones de antena de una misma frecuencia (lo que conlleva un check además para evitar coger cualquier antena consigo mismo), puedo generar automáticamente ese listado de permutaciones con ese método y ya trabajar desde ahí.