diff --git a/src/main/java/com/mattrixwv/adventOfCode24/ProblemSelector.java b/src/main/java/com/mattrixwv/adventOfCode24/ProblemSelector.java index 1b2f100..be7b581 100644 --- a/src/main/java/com/mattrixwv/adventOfCode24/ProblemSelector.java +++ b/src/main/java/com/mattrixwv/adventOfCode24/ProblemSelector.java @@ -13,6 +13,8 @@ import com.mattrixwv.adventOfCode24.days.Problem11; import com.mattrixwv.adventOfCode24.days.Problem12; import com.mattrixwv.adventOfCode24.days.Problem13; import com.mattrixwv.adventOfCode24.days.Problem14; +import com.mattrixwv.adventOfCode24.days.Problem15; +import com.mattrixwv.adventOfCode24.days.Problem16; import com.mattrixwv.adventOfCode24.days.Problem2; import com.mattrixwv.adventOfCode24.days.Problem3; import com.mattrixwv.adventOfCode24.days.Problem4; @@ -28,7 +30,7 @@ public class ProblemSelector{ //Holds the valid problem numbers protected static final List PROBLEM_NUMBERS = List.of( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14 + 10, 11, 12, 13, 14, 15, 16 ); @@ -55,6 +57,8 @@ public class ProblemSelector{ case 12 : day = new Problem12(); break; case 13 : day = new Problem13(); break; case 14 : day = new Problem14(); break; + case 15 : day = new Problem15(); break; + case 16 : day = new Problem16(); break; default: throw new InvalidParameterException(); } return day; diff --git a/src/main/java/com/mattrixwv/adventOfCode24/days/Problem15.java b/src/main/java/com/mattrixwv/adventOfCode24/days/Problem15.java new file mode 100644 index 0000000..d4946cd --- /dev/null +++ b/src/main/java/com/mattrixwv/adventOfCode24/days/Problem15.java @@ -0,0 +1,123 @@ +package com.mattrixwv.adventOfCode24.days; + + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Scanner; +import java.util.Set; + +import com.mattrixwv.Stopwatch; +import com.mattrixwv.Triple; + + +public class Problem15 extends Problem{ + private static final String inputFileName = "days/Problem15.txt"; + private List map; + private Set> antiNodes; + + + public Problem15(){ + super(); + description = "Find the number of unique anti-nodes in the bounds of the map."; + 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 inputLine = scanner.next(); + if(inputLine.isBlank()){ + continue; + } + else{ + map.add(inputLine); + } + } + } + + + findAntiNodes(); + + + //Save the results + timer.stop(); + result = "There are " + antiNodes.size() + " anti-nodes in the boundaries of the map.\nIt took " + timer.toString() + " to run this algorithm."; + return result; + } + + private void findAntiNodes(){ + antiNodes = new HashSet<>(); + //Step through the map and find all nodes + Map>> nodes = new HashMap<>(); + nodes.put('.', new ArrayList<>()); + for(String mapRow : map){ + for(char ch : mapRow.toCharArray()){ + if(!nodes.containsKey(ch)){ + nodes.put(ch, findMatchingElements(ch)); + } + } + } + + //Step through the list of nodes and find all anti-nodes + for(Character key : nodes.keySet()){ + List> nodeList = nodes.get(key); + for(int nodeLoc1 = 0;nodeLoc1 < nodeList.size();++nodeLoc1){ + for(int nodeLoc2 = nodeLoc1 + 1;nodeLoc2 < nodeList.size();++nodeLoc2){ + Triple node1 = nodeList.get(nodeLoc1); + Triple node2 = nodeList.get(nodeLoc2); + int rowDifference = node1.getA() - node2.getA(); + int colDifference = node1.getB() - node2.getB(); + //Forwards node + int antiNode1Row = node1.getA() + rowDifference; + int antiNode1Col = node1.getB() + colDifference; + if(isInBounds(antiNode1Row, antiNode1Col)){ + antiNodes.add(new Triple<>(antiNode1Row, antiNode1Col, 'A')); + } + //Backwards node + int antiNode2Row = node2.getA() - rowDifference; + int antiNode2Col = node2.getB() - colDifference; + if(isInBounds(antiNode2Row, antiNode2Col)){ + antiNodes.add(new Triple<>(antiNode2Row, antiNode2Col, 'A')); + } + } + } + } + } + + private List> findMatchingElements(char element){ + List> elements = new ArrayList<>(); + //Step through each row in the map searching for the given character + for(int row = 0;row < map.size();++row){ + char[] mapRow = map.get(row).toCharArray(); + for(int col = 0;col < mapRow.length;++col){ + if(mapRow[col] == element){ + elements.add(new Triple(row, col, element)); + } + } + } + return elements; + } + + private boolean isInBounds(int row, int col){ + return + (row >= 0) && (row < map.size()) && + (col >= 0) && (col < map.get(row).length()); + } +} + + +/* +Find the number of unique anti-nodes in the bounds of the map. +There are 409 anti-nodes in the boundaries of the map. +It took 6.557 milliseconds to run this algorithm. +*/ diff --git a/src/main/java/com/mattrixwv/adventOfCode24/days/Problem16.java b/src/main/java/com/mattrixwv/adventOfCode24/days/Problem16.java new file mode 100644 index 0000000..54884ec --- /dev/null +++ b/src/main/java/com/mattrixwv/adventOfCode24/days/Problem16.java @@ -0,0 +1,130 @@ +package com.mattrixwv.adventOfCode24.days; + + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Scanner; +import java.util.Set; + +import com.mattrixwv.Stopwatch; +import com.mattrixwv.Triple; + + +public class Problem16 extends Problem{ + private static final String inputFileName = "days/Problem15.txt"; + private List map; + private Set> antiNodes; + + + public Problem16(){ + super(); + description = "Find the number of unique anti-nodes in the bounds of the map."; + 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 inputLine = scanner.next(); + if(inputLine.isBlank()){ + continue; + } + else{ + map.add(inputLine); + } + } + } + + findAntiNodes(); + + + //Save the results + timer.stop(); + result = "There are " + antiNodes.size() + " anti-nodes in the boundaries of the map.\nIt took " + timer.toString() + " to run this algorithm."; + return result; + } + + private void findAntiNodes(){ + antiNodes = new HashSet<>(); + //Step through the map and find all nodes + Map>> nodes = new HashMap<>(); + nodes.put('.', new ArrayList<>()); + for(String mapRow : map){ + for(char ch : mapRow.toCharArray()){ + if(!nodes.containsKey(ch)){ + nodes.put(ch, findMatchingElements(ch)); + } + } + } + + //Step through the list of nodes and find all anti-nodes + for(Character key : nodes.keySet()){ + List> nodeList = nodes.get(key); + for(int nodeLoc1 = 0;nodeLoc1 < nodeList.size();++nodeLoc1){ + for(int nodeLoc2 = nodeLoc1 + 1;nodeLoc2 < nodeList.size();++nodeLoc2){ + Triple node1 = nodeList.get(nodeLoc1); + Triple node2 = nodeList.get(nodeLoc2); + //Since there are at least 2 elements add each as a resonance point + antiNodes.add(new Triple<>(node1.getA(), node1.getB(), 'A')); + antiNodes.add(new Triple<>(node2.getA(), node2.getB(), 'A')); + + int rowDifference = node1.getA() - node2.getA(); + int colDifference = node1.getB() - node2.getB(); + //Forwards node + int antiNode1Row = node1.getA() + rowDifference; + int antiNode1Col = node1.getB() + colDifference; + while(isInBounds(antiNode1Row, antiNode1Col)){ + antiNodes.add(new Triple<>(antiNode1Row, antiNode1Col, 'A')); + antiNode1Row += rowDifference; + antiNode1Col += colDifference; + } + //Backwards node + int antiNode2Row = node2.getA() - rowDifference; + int antiNode2Col = node2.getB() - colDifference; + while(isInBounds(antiNode2Row, antiNode2Col)){ + antiNodes.add(new Triple<>(antiNode2Row, antiNode2Col, 'A')); + antiNode2Row -= rowDifference; + antiNode2Col -= colDifference; + } + } + } + } + } + + private List> findMatchingElements(char element){ + List> elements = new ArrayList<>(); + //Step through each row in the map searching for the given character + for(int row = 0;row < map.size();++row){ + char[] mapRow = map.get(row).toCharArray(); + for(int col = 0;col < mapRow.length;++col){ + if(mapRow[col] == element){ + elements.add(new Triple(row, col, element)); + } + } + } + return elements; + } + + private boolean isInBounds(int row, int col){ + return + (row >= 0) && (row < map.size()) && + (col >= 0) && (col < map.get(row).length()); + } +} + + +/* +Find the number of unique anti-nodes in the bounds of the map. +There are 1308 anti-nodes in the boundaries of the map. +It took 8.836 milliseconds to run this algorithm. +*/ diff --git a/src/main/resources/days/Problem15.txt b/src/main/resources/days/Problem15.txt new file mode 100644 index 0000000..f9bb266 --- /dev/null +++ b/src/main/resources/days/Problem15.txt @@ -0,0 +1,50 @@ +........0.......................c................. +........a......................................... +.......0........................................r. +.....W............................................ +..............Z..F.......................c........ +..F....a.....................c.......Lr....5...... +............................v.......L5............ +..................0.....v............r...E........ +...a..........................p..E..5...7L.m...Z.. +......j..0............z.....p.........E........... +...j...S...W.7................J........4.......... +......W........X...............................4.. +W..........................p................M..... +i........Z....................L.............U..... +.....z....j..X..............................b....M +........................Z......m.................. +....f.........X........J................4......H.. +y..................p............X.JvmR.U.......... +.................................................. +................................4................. +.........N........................U............... +........u...q.......5....J..7.................M... +.y..i.F...z..........................9x.....A..... +...i.....2...zw....Y.........................M.... +............Bu.................I...........U...... +..f.....2.......k...........b.........I.......x... +.f............................................G... +.O...o.......f...............7.t..Q.G............. +a.....N....i2.........g..o...RI........G.......... +......oy...q..........N..H........sQ.............. +....y..2............K........b........9...m....... +.......w...............b....Y........G.......A.... +......uO.w............q.k..Y.....v.............A.. +...u...K....O..............I...................... +o.O.........w.......Y.........R.Q..............T.. +......................t...3........k...x...C9..... +.............q........3..6......t............Q.x.. +V......................N..............S........... +..............6....K...............1...n..P....... +......8..........................T....H.........1. +..................s....t.....3....H.......n....... +......K.g6...B...........h..T..l.....P.....9...... +..................l....k..T....h............1....e +............6.........l.......h.....Pe..C......... +...........s.V....................e..........C.... +.....8...V.......s.g...........n......e........... +..V......B.g...........l.8........................ +......B.................R..3...............1.....S +........................h...................S...CP +..................................................