178 lines
5.8 KiB
Java
178 lines
5.8 KiB
Java
package com.mattrixwv.adventOfCode24.days;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.HashSet;
|
|
import java.util.List;
|
|
import java.util.Scanner;
|
|
import java.util.Set;
|
|
|
|
import com.mattrixwv.Stopwatch;
|
|
import com.mattrixwv.Triple;
|
|
|
|
public class Problem19 extends Problem{
|
|
private static final String inputFileName = "days/Problem19.txt";
|
|
private List<List<Integer>> map;
|
|
private List<Triple<Integer, Integer, Integer>> trailHeadScores;
|
|
|
|
|
|
public Problem19(){
|
|
super();
|
|
description = "Find the sum of the trail head scores.";
|
|
result = "Unresolved";
|
|
}
|
|
|
|
|
|
public String runSolution(){
|
|
Stopwatch timer = new Stopwatch();
|
|
timer.start();
|
|
|
|
|
|
//Read the file
|
|
map = new ArrayList<>();
|
|
try(Scanner scanner = new Scanner(this.getClass().getClassLoader().getResourceAsStream(inputFileName))){
|
|
scanner.useDelimiter("\n");
|
|
while(scanner.hasNext()){
|
|
String mapLine = scanner.next();
|
|
if(!mapLine.isBlank()){
|
|
List<Integer> mapArray = new ArrayList<>();
|
|
for(char ch : mapLine.toCharArray()){
|
|
mapArray.add(Integer.parseInt(Character.toString(ch)));
|
|
}
|
|
map.add(mapArray);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//Calculate the trail head scores
|
|
trailHeadScores = new ArrayList<>();
|
|
for(int rowCnt = 0;rowCnt < map.size();++rowCnt){
|
|
for(int colCnt = 0;colCnt < map.get(rowCnt).size();++colCnt){
|
|
if(map.get(rowCnt).get(colCnt) == 0){
|
|
Set<Triple<Integer, Integer, Integer>> foundEndpoints = new HashSet<>();
|
|
foundEndpoints.addAll(checkAllDirections(new Triple<Integer, Integer, Integer>(rowCnt, colCnt, 0)));
|
|
trailHeadScores.add(new Triple<Integer, Integer, Integer>(rowCnt, colCnt, foundEndpoints.size()));
|
|
}
|
|
}
|
|
}
|
|
|
|
//Sum the trail head scores
|
|
int sum = 0;
|
|
for(Triple<Integer, Integer, Integer> trailHeadScore : trailHeadScores){
|
|
sum += trailHeadScore.getC();
|
|
}
|
|
|
|
|
|
|
|
//Save the results
|
|
timer.stop();
|
|
result = "The sum of the trail head scores is " + sum + ".\nIt took " + timer.toString() + " to run this algorithm.";
|
|
return result;
|
|
}
|
|
|
|
|
|
private Set<Triple<Integer, Integer, Integer>> checkAllDirections(Triple<Integer, Integer, Integer> loc){
|
|
Set<Triple<Integer, Integer, Integer>> foundEndpoints = new HashSet<>();
|
|
foundEndpoints.addAll(moveUp(loc));
|
|
foundEndpoints.addAll(moveRight(loc));
|
|
foundEndpoints.addAll(moveDown(loc));
|
|
foundEndpoints.addAll(moveLeft(loc));
|
|
return foundEndpoints;
|
|
}
|
|
|
|
private Set<Triple<Integer, Integer, Integer>> moveUp(Triple<Integer, Integer, Integer> loc){
|
|
//Check the current and next elements are in bounds
|
|
if((loc.getA() <= 0) || (loc.getA() >= map.size()) || (loc.getB() < 0) || (loc.getB() >= map.get(loc.getA()).size())){
|
|
return new HashSet<>();
|
|
}
|
|
|
|
Set<Triple<Integer, Integer, Integer>> finishSet = new HashSet<>();
|
|
//Check if we need to continue looking
|
|
if(map.get(loc.getA() - 1).get(loc.getB()) == (loc.getC() + 1)){
|
|
Triple<Integer, Integer, Integer> newLoc = new Triple<Integer, Integer, Integer>(loc.getA() - 1, loc.getB(), loc.getC() + 1);
|
|
if(newLoc.getC() == 9){
|
|
finishSet.add(newLoc);
|
|
}
|
|
else{
|
|
finishSet.addAll(checkAllDirections(newLoc));
|
|
}
|
|
}
|
|
//If the next value is not correct, then return an empty set
|
|
//Return any values we found
|
|
return finishSet;
|
|
}
|
|
|
|
private Set<Triple<Integer, Integer, Integer>> moveRight(Triple<Integer, Integer, Integer> loc){
|
|
//Check the current and next elements are in bounds
|
|
if((loc.getA() < 0) || (loc.getA() >= map.size()) || (loc.getB() < 0) || (loc.getB() >= (map.get(loc.getA()).size() - 1))){
|
|
return new HashSet<>();
|
|
}
|
|
|
|
Set<Triple<Integer, Integer, Integer>> finishSet = new HashSet<>();
|
|
//Check if we need to continue looking
|
|
if(map.get(loc.getA()).get(loc.getB() + 1) == (loc.getC() + 1)){
|
|
Triple<Integer, Integer, Integer> newLoc = new Triple<Integer, Integer, Integer>(loc.getA(), loc.getB() + 1, loc.getC() + 1);
|
|
if(newLoc.getC() == 9){
|
|
finishSet.add(newLoc);
|
|
}
|
|
else{
|
|
finishSet.addAll(checkAllDirections(newLoc));
|
|
}
|
|
}
|
|
//If the next value is not correct, then return an empty set
|
|
//Return any values we found
|
|
return finishSet;
|
|
}
|
|
|
|
private Set<Triple<Integer, Integer, Integer>> moveDown(Triple<Integer, Integer, Integer> loc){
|
|
//Check the current and next elements are in bounds
|
|
if((loc.getA() < 0) || (loc.getA() >= (map.size() - 1)) || (loc.getB() < 0) || (loc.getB() >= map.get(loc.getA()).size())){
|
|
return new HashSet<>();
|
|
}
|
|
|
|
Set<Triple<Integer, Integer, Integer>> finishSet = new HashSet<>();
|
|
//Check if we need to continue looking
|
|
if(map.get(loc.getA() + 1).get(loc.getB()) == (loc.getC() + 1)){
|
|
Triple<Integer, Integer, Integer> newLoc = new Triple<Integer, Integer, Integer>(loc.getA() + 1, loc.getB(), loc.getC() + 1);
|
|
if(newLoc.getC() == 9){
|
|
finishSet.add(newLoc);
|
|
}
|
|
else{
|
|
finishSet.addAll(checkAllDirections(newLoc));
|
|
}
|
|
}
|
|
//If the next value is not correct, then return an empty set
|
|
//Return any values we found
|
|
return finishSet;
|
|
}
|
|
|
|
private Set<Triple<Integer, Integer, Integer>> moveLeft(Triple<Integer, Integer, Integer> loc){
|
|
//Check the current and next elements are in bounds
|
|
if((loc.getA() < 0) || (loc.getA() >= map.size()) || (loc.getB() <= 0) || (loc.getB() >= map.get(loc.getA()).size())){
|
|
return new HashSet<>();
|
|
}
|
|
|
|
Set<Triple<Integer, Integer, Integer>> finishSet = new HashSet<>();
|
|
//Check if we need to continue looking
|
|
if(map.get(loc.getA()).get(loc.getB() - 1) == (loc.getC() + 1)){
|
|
Triple<Integer, Integer, Integer> newLoc = new Triple<Integer, Integer, Integer>(loc.getA(), loc.getB() - 1, loc.getC() + 1);
|
|
if(newLoc.getC() == 9){
|
|
finishSet.add(newLoc);
|
|
}
|
|
else{
|
|
finishSet.addAll(checkAllDirections(newLoc));
|
|
}
|
|
}
|
|
//If the next value is not correct, then return an empty set
|
|
//Return any values we found
|
|
return finishSet;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
Find the sum of the trail head scores.
|
|
The sum of the trail head scores is 510.
|
|
It took 16.725 milliseconds to run this algorithm.
|
|
*/
|