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> map; private List> 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 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> foundEndpoints = new HashSet<>(); foundEndpoints.addAll(checkAllDirections(new Triple(rowCnt, colCnt, 0))); trailHeadScores.add(new Triple(rowCnt, colCnt, foundEndpoints.size())); } } } //Sum the trail head scores int sum = 0; for(Triple 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> checkAllDirections(Triple loc){ Set> foundEndpoints = new HashSet<>(); foundEndpoints.addAll(moveUp(loc)); foundEndpoints.addAll(moveRight(loc)); foundEndpoints.addAll(moveDown(loc)); foundEndpoints.addAll(moveLeft(loc)); return foundEndpoints; } private Set> moveUp(Triple 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> finishSet = new HashSet<>(); //Check if we need to continue looking if(map.get(loc.getA() - 1).get(loc.getB()) == (loc.getC() + 1)){ Triple newLoc = new Triple(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> moveRight(Triple 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> finishSet = new HashSet<>(); //Check if we need to continue looking if(map.get(loc.getA()).get(loc.getB() + 1) == (loc.getC() + 1)){ Triple newLoc = new Triple(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> moveDown(Triple 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> finishSet = new HashSet<>(); //Check if we need to continue looking if(map.get(loc.getA() + 1).get(loc.getB()) == (loc.getC() + 1)){ Triple newLoc = new Triple(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> moveLeft(Triple 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> finishSet = new HashSet<>(); //Check if we need to continue looking if(map.get(loc.getA()).get(loc.getB() - 1) == (loc.getC() + 1)){ Triple newLoc = new Triple(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. */