Day 6 (almost) solved
This commit is contained in:
@@ -9,6 +9,8 @@ import java.util.StringJoiner;
|
||||
import com.mattrixwv.adventOfCode24.days.Problem;
|
||||
import com.mattrixwv.adventOfCode24.days.Problem1;
|
||||
import com.mattrixwv.adventOfCode24.days.Problem10;
|
||||
import com.mattrixwv.adventOfCode24.days.Problem11;
|
||||
import com.mattrixwv.adventOfCode24.days.Problem12;
|
||||
import com.mattrixwv.adventOfCode24.days.Problem2;
|
||||
import com.mattrixwv.adventOfCode24.days.Problem3;
|
||||
import com.mattrixwv.adventOfCode24.days.Problem4;
|
||||
@@ -22,7 +24,10 @@ import com.mattrixwv.adventOfCode24.days.Problem9;
|
||||
public class ProblemSelector{
|
||||
private static final Scanner input = new Scanner(System.in);
|
||||
//Holds the valid problem numbers
|
||||
protected static final List<Integer> PROBLEM_NUMBERS = List.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
|
||||
protected static final List<Integer> PROBLEM_NUMBERS = List.of(
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||
10, 11, 12
|
||||
);
|
||||
|
||||
|
||||
private ProblemSelector(){
|
||||
@@ -44,6 +49,8 @@ public class ProblemSelector{
|
||||
case 8 : day = new Problem8(); break;
|
||||
case 9 : day = new Problem9(); break;
|
||||
case 10 : day = new Problem10(); break;
|
||||
case 11 : day = new Problem11(); break;
|
||||
case 12 : day = new Problem12(); break;
|
||||
default: throw new InvalidParameterException();
|
||||
}
|
||||
return day;
|
||||
|
||||
214
src/main/java/com/mattrixwv/adventOfCode24/days/Problem11.java
Normal file
214
src/main/java/com/mattrixwv/adventOfCode24/days/Problem11.java
Normal file
@@ -0,0 +1,214 @@
|
||||
package com.mattrixwv.adventOfCode24.days;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.mattrixwv.Stopwatch;
|
||||
import com.mattrixwv.Triple;
|
||||
|
||||
|
||||
public class Problem11 extends Problem{
|
||||
private static final String inputFileName = "days/Problem11.txt";
|
||||
private List<String> map;
|
||||
|
||||
|
||||
public Problem11(){
|
||||
super();
|
||||
description = "Find the number of distinct positions the guard will visit.";
|
||||
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()){
|
||||
map.add(scanner.next());
|
||||
}
|
||||
}
|
||||
|
||||
//Find the current location of the guard
|
||||
Triple<Integer, Integer, Character> currentLocation = findInitialLocation();
|
||||
//Loop while the guard is still on the map
|
||||
boolean inBounds = true;
|
||||
while(inBounds){
|
||||
//Move in the direction the guard is facing as far as possible, then turn right
|
||||
if(currentLocation.getC() == '^'){
|
||||
currentLocation = moveUp(currentLocation);
|
||||
}
|
||||
else if(currentLocation.getC() == '>'){
|
||||
currentLocation = moveRight(currentLocation);
|
||||
}
|
||||
else if(currentLocation.getC() == 'v'){
|
||||
currentLocation = moveDown(currentLocation);
|
||||
}
|
||||
else if(currentLocation.getC() == '<'){
|
||||
currentLocation = moveLeft(currentLocation);
|
||||
}
|
||||
else{
|
||||
throw new RuntimeException("There was an error in the location: " + currentLocation);
|
||||
}
|
||||
//Determine if the guard is still on the map
|
||||
if(currentLocation.getC() == '\0'){
|
||||
inBounds = false;
|
||||
}
|
||||
}
|
||||
|
||||
//Count the number of distinct locations visited
|
||||
int count = 0;
|
||||
Pattern xPattern = Pattern.compile("X");
|
||||
for(String mapLine : map){
|
||||
Matcher xMatcher = xPattern.matcher(mapLine);
|
||||
while(xMatcher.find()){
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Save the results
|
||||
timer.stop();
|
||||
result = "The number of distinct positions the guard will visit is " + count + ".\nIt took " + timer.toString() + " to run the algorithm.";
|
||||
return result;
|
||||
}
|
||||
|
||||
private Triple<Integer, Integer, Character> findInitialLocation(){
|
||||
for(int row = 0;row < map.size();++row){
|
||||
String mapLine = map.get(row);
|
||||
int startIndex = mapLine.indexOf("^");
|
||||
if(startIndex != -1){
|
||||
return new Triple<>(row, startIndex, '^');
|
||||
}
|
||||
}
|
||||
|
||||
//If it gets this far it was not found
|
||||
return new Triple<>(-1, -1, '\0');
|
||||
}
|
||||
|
||||
private Triple<Integer, Integer, Character> moveUp(Triple<Integer, Integer, Character> currentLocation){
|
||||
while(true){
|
||||
String currentMapString = map.get(currentLocation.getA());
|
||||
//If the current Y value is == 0 then the guard left the area
|
||||
if(currentLocation.getA() == 0){
|
||||
currentMapString = currentMapString.replace("^", "X");
|
||||
map.set(currentLocation.getA(), currentMapString);
|
||||
return new Triple<>(-1, -1, '\0');
|
||||
}
|
||||
String nextMapString = map.get(currentLocation.getA() - 1);
|
||||
//If the next Y value contains a # then the guard needs to move to the next stage
|
||||
if(nextMapString.charAt(currentLocation.getB()) == '#'){
|
||||
currentMapString = currentMapString.replace("^", ">");
|
||||
map.set(currentLocation.getA(), currentMapString);
|
||||
return new Triple<>(currentLocation.getA(), currentLocation.getB(), '>');
|
||||
}
|
||||
//If the next Y value is a . or X then move to the new location and mark the current location with an X
|
||||
else{
|
||||
currentMapString = currentMapString.replace("^", "X");
|
||||
map.set(currentLocation.getA(), currentMapString);
|
||||
StringBuilder newMapString = new StringBuilder(nextMapString);
|
||||
newMapString.setCharAt(currentLocation.getB(), '^');
|
||||
map.set(currentLocation.getA() - 1, newMapString.toString());
|
||||
currentLocation = new Triple<>(currentLocation.getA() - 1, currentLocation.getB(), '^');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Triple<Integer, Integer, Character> moveRight(Triple<Integer, Integer, Character> currentLocation){
|
||||
while(true){
|
||||
String currentMapString = map.get(currentLocation.getA());
|
||||
//If the current X value is == the length of the string then the guard left the area
|
||||
if(currentLocation.getB() == (currentMapString.length() - 1)){
|
||||
currentMapString = currentMapString.replace(">", "X");
|
||||
map.set(currentLocation.getA(), currentMapString);
|
||||
return new Triple<>(-1, -1, '\0');
|
||||
}
|
||||
String nextMapString = map.get(currentLocation.getA());
|
||||
//If the next X value contains a # then the guard needs to move to the next stage
|
||||
if(nextMapString.charAt(currentLocation.getB() + 1) == '#'){
|
||||
currentMapString = currentMapString.replace(">", "v");
|
||||
map.set(currentLocation.getA(), currentMapString);
|
||||
return new Triple<>(currentLocation.getA(), currentLocation.getB(), 'v');
|
||||
}
|
||||
//If the next X value is a . or X then move to the new location and mark the current location with an X
|
||||
else{
|
||||
currentMapString = currentMapString.replace(">", "X");
|
||||
map.set(currentLocation.getA(), currentMapString);
|
||||
StringBuilder newMapString = new StringBuilder(nextMapString);
|
||||
newMapString.setCharAt(currentLocation.getB() + 1, '>');
|
||||
map.set(currentLocation.getA(), newMapString.toString());
|
||||
currentLocation = new Triple<>(currentLocation.getA(), currentLocation.getB() + 1, '>');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Triple<Integer, Integer, Character> moveDown(Triple<Integer, Integer, Character> currentLocation){
|
||||
while(true){
|
||||
String currentMapString = map.get(currentLocation.getA());
|
||||
//If the current Y value is == the length of the string then the guard left the area
|
||||
if(currentLocation.getA() == (map.size() - 1)){
|
||||
currentMapString = currentMapString.replace("v", "X");
|
||||
map.set(currentLocation.getA(), currentMapString);
|
||||
return new Triple<>(-1, -1, '\0');
|
||||
}
|
||||
String nextMapString = map.get(currentLocation.getA() + 1);
|
||||
//If the next Y value contains a # then the guard needs to move to the next stage
|
||||
if(nextMapString.charAt(currentLocation.getB()) == '#'){
|
||||
currentMapString = currentMapString.replace("v", "<");
|
||||
map.set(currentLocation.getA(), currentMapString);
|
||||
return new Triple<>(currentLocation.getA(), currentLocation.getB(), '<');
|
||||
}
|
||||
//If the next Y value is a . or X then move to the new location and mark the current location with an X
|
||||
else{
|
||||
currentMapString = currentMapString.replace("v", "X");
|
||||
map.set(currentLocation.getA(), currentMapString);
|
||||
StringBuilder newMapString = new StringBuilder(nextMapString);
|
||||
newMapString.setCharAt(currentLocation.getB(), 'v');
|
||||
map.set(currentLocation.getA() + 1, newMapString.toString());
|
||||
currentLocation = new Triple<>(currentLocation.getA() + 1, currentLocation.getB(), 'v');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Triple<Integer, Integer, Character> moveLeft(Triple<Integer, Integer, Character> currentLocation){
|
||||
while(true){
|
||||
String currentMapString = map.get(currentLocation.getA());
|
||||
//If the current X value is == 0 then the guard left the area
|
||||
if(currentLocation.getB() == 0){
|
||||
currentMapString = currentMapString.replace("<", "X");
|
||||
map.set(currentLocation.getA(), currentMapString);
|
||||
return new Triple<>(-1, -1, '\0');
|
||||
}
|
||||
String nextMapString = map.get(currentLocation.getA());
|
||||
//If the next X value contains a # then the guard needs to move to the next stage
|
||||
if(nextMapString.charAt(currentLocation.getB() - 1) == '#'){
|
||||
currentMapString = currentMapString.replace("<", "^");
|
||||
map.set(currentLocation.getA(), currentMapString);
|
||||
return new Triple<>(currentLocation.getA(), currentLocation.getB(), '^');
|
||||
}
|
||||
//If the next X value is a . or X then move to the new location and mark the current location with an X
|
||||
else{
|
||||
currentMapString = currentMapString.replace("<", "X");
|
||||
map.set(currentLocation.getA(), currentMapString);
|
||||
StringBuilder newMapString = new StringBuilder(nextMapString);
|
||||
newMapString.setCharAt(currentLocation.getB() - 1, '<');
|
||||
map.set(currentLocation.getA(), newMapString.toString());
|
||||
currentLocation = new Triple<>(currentLocation.getA(), currentLocation.getB() - 1, '<');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Find the number of distinct positions the guard will visit.
|
||||
The number of distinct positions the guard will visit is 4647.
|
||||
It took 14.695 milliseconds to run the algorithm.
|
||||
*/
|
||||
408
src/main/java/com/mattrixwv/adventOfCode24/days/Problem12.java
Normal file
408
src/main/java/com/mattrixwv/adventOfCode24/days/Problem12.java
Normal file
@@ -0,0 +1,408 @@
|
||||
package com.mattrixwv.adventOfCode24.days;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.mattrixwv.Stopwatch;
|
||||
import com.mattrixwv.Triple;
|
||||
|
||||
|
||||
public class Problem12 extends Problem{
|
||||
private static final String inputFileName = "days/Problem11.txt";
|
||||
private List<String> map;
|
||||
private List<Triple<Integer, Integer, Character>> patrolHistory;
|
||||
private List<Triple<Integer, Integer, Character>> loopLocations;
|
||||
//private int loopCounter = 0;
|
||||
//private int LOOP_MAX = 7;
|
||||
//private int LOOP_MAX = 100;
|
||||
|
||||
|
||||
public Problem12(){
|
||||
super();
|
||||
description = "Find the number of places that a new obstacle could be placed that creates a patrol loop.";
|
||||
result = "Unresolved";
|
||||
}
|
||||
|
||||
|
||||
public String runSolution(){
|
||||
Stopwatch timer = new Stopwatch();
|
||||
timer.start();
|
||||
|
||||
|
||||
throw new RuntimeException("This problem is not yet solved");
|
||||
|
||||
|
||||
//Read the file
|
||||
/*
|
||||
map = new ArrayList<>();
|
||||
try(Scanner scanner = new Scanner(this.getClass().getClassLoader().getResourceAsStream(inputFileName))){
|
||||
scanner.useDelimiter("\n");
|
||||
while(scanner.hasNext()){
|
||||
map.add(scanner.next());
|
||||
}
|
||||
}
|
||||
/* */
|
||||
//Answer: 6
|
||||
/*
|
||||
map = new ArrayList<>(List.of(
|
||||
"....#.....",
|
||||
".........#",
|
||||
"..........",
|
||||
"..#.......",
|
||||
".......#..",
|
||||
"..........",
|
||||
".#..^.....",
|
||||
"........#.",
|
||||
"#.........",
|
||||
"......#..."
|
||||
));
|
||||
/* */
|
||||
//Answer: 19
|
||||
/*
|
||||
map = new ArrayList<>(List.of(
|
||||
"...........#.....#......",
|
||||
"...................#....",
|
||||
"...#.....##.............",
|
||||
"......................#.",
|
||||
"..................#.....",
|
||||
"..#.....................",
|
||||
"....................#...",
|
||||
"........................",
|
||||
".#........^.............",
|
||||
"..........#..........#..",
|
||||
"..#.....#..........#....",
|
||||
"........#.....#..#......"
|
||||
));
|
||||
/* */
|
||||
|
||||
/*
|
||||
//Find the current location of the guard
|
||||
Triple<Integer, Integer, Character> currentLocation = findInitialLocation();
|
||||
patrolHistory = new ArrayList<>();
|
||||
loopLocations = new ArrayList<>();
|
||||
//printMap();
|
||||
//Loop while the guard is still on the map
|
||||
traverseMap(currentLocation, false);
|
||||
|
||||
//printMap();
|
||||
placePotentialLoops();
|
||||
//System.out.println("\n\n");
|
||||
printMap();
|
||||
|
||||
|
||||
|
||||
//Save the results
|
||||
timer.stop();
|
||||
result = "The number of positions that a new object could be placed to create a patrol loop is " + loopLocations.size() + ".\nIt took " + timer.toString() + " to run the algorithm.";
|
||||
return result;
|
||||
/* */
|
||||
}
|
||||
|
||||
private Triple<Integer, Integer, Character> findInitialLocation(){
|
||||
for(int row = 0;row < map.size();++row){
|
||||
String mapLine = map.get(row);
|
||||
int startIndex = mapLine.indexOf("^");
|
||||
if(startIndex != -1){
|
||||
return new Triple<>(row, startIndex, '^');
|
||||
}
|
||||
}
|
||||
|
||||
//If it gets this far it was not found
|
||||
return new Triple<>(-1, -1, '\0');
|
||||
}
|
||||
|
||||
private void traverseMap(Triple<Integer, Integer, Character> currentLocation, boolean loopCheck){
|
||||
boolean inBounds = true;
|
||||
while(inBounds){
|
||||
if(patrolHistory.contains(currentLocation)){
|
||||
patrolHistory.add(currentLocation);
|
||||
break;
|
||||
}
|
||||
else{
|
||||
patrolHistory.add(currentLocation);
|
||||
}
|
||||
|
||||
//Move in that direction as far as possible
|
||||
if(currentLocation.getC() == '^'){
|
||||
currentLocation = moveUp(currentLocation, loopCheck);
|
||||
}
|
||||
else if(currentLocation.getC() == '>'){
|
||||
currentLocation = moveRight(currentLocation, loopCheck);
|
||||
}
|
||||
else if(currentLocation.getC() == 'v'){
|
||||
currentLocation = moveDown(currentLocation, loopCheck);
|
||||
}
|
||||
else if(currentLocation.getC() == '<'){
|
||||
currentLocation = moveLeft(currentLocation, loopCheck);
|
||||
}
|
||||
else{
|
||||
throw new RuntimeException("There was an error in the location: " + currentLocation);
|
||||
}
|
||||
//Determine if still in bounds
|
||||
//if(loopCounter > LOOP_MAX || currentLocation.getC() == '\0'){
|
||||
if(currentLocation.getC() == '\0'){
|
||||
inBounds = false;
|
||||
}
|
||||
//++loopCounter;
|
||||
}
|
||||
}
|
||||
|
||||
private Triple<Integer, Integer, Character> moveUp(Triple<Integer, Integer, Character> currentLocation, boolean loopCheck){
|
||||
while(true){
|
||||
String currentMapString = map.get(currentLocation.getA());
|
||||
//If the current Y value is == 0 then the guard left the area
|
||||
if(currentLocation.getA() == 0){
|
||||
currentMapString = currentMapString.replace("^", "X");
|
||||
map.set(currentLocation.getA(), currentMapString);
|
||||
return new Triple<>(-1, -1, '\0');
|
||||
}
|
||||
String nextMapString = map.get(currentLocation.getA() - 1);
|
||||
//If the next Y value contains a # then the guard needs to move to the next stage
|
||||
if(nextMapString.charAt(currentLocation.getB()) == '#'){
|
||||
currentMapString = currentMapString.replace("^", ">");
|
||||
map.set(currentLocation.getA(), currentMapString);
|
||||
return new Triple<>(currentLocation.getA(), currentLocation.getB(), '>');
|
||||
}
|
||||
//If the next Y value is a . or X then move to the new location and mark the current location with an X
|
||||
else{
|
||||
currentMapString = currentMapString.replace("^", "X");
|
||||
map.set(currentLocation.getA(), currentMapString);
|
||||
StringBuilder newMapString = new StringBuilder(nextMapString);
|
||||
newMapString.setCharAt(currentLocation.getB(), '^');
|
||||
map.set(currentLocation.getA() - 1, newMapString.toString());
|
||||
currentLocation = new Triple<>(currentLocation.getA() - 1, currentLocation.getB(), '^');
|
||||
|
||||
//Check for the potential to create a loop
|
||||
if(!loopCheck){
|
||||
Triple<Integer, Integer, Character> potentialLoop = new Triple<>(currentLocation.getA() - 1, currentLocation.getB(), '>');
|
||||
if(createsLoop(potentialLoop) && !loopContains(potentialLoop)){
|
||||
loopLocations.add(potentialLoop);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Triple<Integer, Integer, Character> moveRight(Triple<Integer, Integer, Character> currentLocation, boolean loopCheck){
|
||||
while(true){
|
||||
String currentMapString = map.get(currentLocation.getA());
|
||||
//If the current X value is == the length of the string then the guard left the area
|
||||
if(currentLocation.getB() == (currentMapString.length() - 1)){
|
||||
currentMapString = currentMapString.replace(">", "X");
|
||||
map.set(currentLocation.getA(), currentMapString);
|
||||
return new Triple<>(-1, -1, '\0');
|
||||
}
|
||||
String nextMapString = map.get(currentLocation.getA());
|
||||
//If the next X value contains a # then the guard needs to move to the next stage
|
||||
if(nextMapString.charAt(currentLocation.getB() + 1) == '#'){
|
||||
currentMapString = currentMapString.replace(">", "v");
|
||||
map.set(currentLocation.getA(), currentMapString);
|
||||
return new Triple<>(currentLocation.getA(), currentLocation.getB(), 'v');
|
||||
}
|
||||
//If the next X value is a . or X then move to the new location and mark the current location with an X
|
||||
else{
|
||||
currentMapString = currentMapString.replace(">", "X");
|
||||
map.set(currentLocation.getA(), currentMapString);
|
||||
StringBuilder newMapString = new StringBuilder(nextMapString);
|
||||
newMapString.setCharAt(currentLocation.getB() + 1, '>');
|
||||
map.set(currentLocation.getA(), newMapString.toString());
|
||||
currentLocation = new Triple<>(currentLocation.getA(), currentLocation.getB() + 1, '>');
|
||||
|
||||
//Check for the potential to create a loop
|
||||
if(!loopCheck){
|
||||
Triple<Integer, Integer, Character> potentialLoop = new Triple<>(currentLocation.getA(), currentLocation.getB() + 1, 'v');
|
||||
if(createsLoop(potentialLoop) && !loopContains(potentialLoop)){
|
||||
loopLocations.add(potentialLoop);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Triple<Integer, Integer, Character> moveDown(Triple<Integer, Integer, Character> currentLocation, boolean loopCheck){
|
||||
while(true){
|
||||
String currentMapString = map.get(currentLocation.getA());
|
||||
//If the current Y value is == the length of the string then the guard left the area
|
||||
if(currentLocation.getA() == (map.size() - 1)){
|
||||
currentMapString = currentMapString.replace("v", "X");
|
||||
map.set(currentLocation.getA(), currentMapString);
|
||||
return new Triple<>(-1, -1, '\0');
|
||||
}
|
||||
String nextMapString = map.get(currentLocation.getA() + 1);
|
||||
//If the next Y value contains a # then the guard needs to move to the next stage
|
||||
if(nextMapString.charAt(currentLocation.getB()) == '#'){
|
||||
currentMapString = currentMapString.replace("v", "<");
|
||||
map.set(currentLocation.getA(), currentMapString);
|
||||
return new Triple<>(currentLocation.getA(), currentLocation.getB(), '<');
|
||||
}
|
||||
//If the next Y value is a . or X then move to the new location and mark the current location with an X
|
||||
else{
|
||||
currentMapString = currentMapString.replace("v", "X");
|
||||
map.set(currentLocation.getA(), currentMapString);
|
||||
StringBuilder newMapString = new StringBuilder(nextMapString);
|
||||
newMapString.setCharAt(currentLocation.getB(), 'v');
|
||||
map.set(currentLocation.getA() + 1, newMapString.toString());
|
||||
currentLocation = new Triple<>(currentLocation.getA() + 1, currentLocation.getB(), 'v');
|
||||
|
||||
//Check for the potential to create a loop
|
||||
if(!loopCheck){
|
||||
Triple<Integer, Integer, Character> potentialLoop = new Triple<>(currentLocation.getA() + 1, currentLocation.getB(), '<');
|
||||
if(createsLoop(potentialLoop) && !loopContains(potentialLoop)){
|
||||
loopLocations.add(potentialLoop);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Triple<Integer, Integer, Character> moveLeft(Triple<Integer, Integer, Character> currentLocation, boolean loopCheck){
|
||||
while(true){
|
||||
String currentMapString = map.get(currentLocation.getA());
|
||||
//If the current X value is == 0 then the guard left the area
|
||||
if(currentLocation.getB() == 0){
|
||||
currentMapString = currentMapString.replace("<", "X");
|
||||
map.set(currentLocation.getA(), currentMapString);
|
||||
return new Triple<>(-1, -1, '\0');
|
||||
}
|
||||
String nextMapString = map.get(currentLocation.getA());
|
||||
//If the next X value contains a # then the guard needs to move to the next stage
|
||||
if(nextMapString.charAt(currentLocation.getB() - 1) == '#'){
|
||||
currentMapString = currentMapString.replace("<", "^");
|
||||
map.set(currentLocation.getA(), currentMapString);
|
||||
return new Triple<>(currentLocation.getA(), currentLocation.getB(), '^');
|
||||
}
|
||||
//If the next X value is a . or X then move to the new location and mark the current location with an X
|
||||
else{
|
||||
currentMapString = currentMapString.replace("<", "X");
|
||||
map.set(currentLocation.getA(), currentMapString);
|
||||
StringBuilder newMapString = new StringBuilder(nextMapString);
|
||||
newMapString.setCharAt(currentLocation.getB() - 1, '<');
|
||||
map.set(currentLocation.getA(), newMapString.toString());
|
||||
currentLocation = new Triple<>(currentLocation.getA(), currentLocation.getB() - 1, '<');
|
||||
|
||||
//Check for the potential to create a loop
|
||||
if(!loopCheck){
|
||||
Triple<Integer, Integer, Character> potentialLoop = new Triple<>(currentLocation.getA(), currentLocation.getB() - 1, '^');
|
||||
if(createsLoop(potentialLoop)){
|
||||
loopLocations.add(potentialLoop);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean createsLoop(Triple<Integer, Integer, Character> newObstacleLocation){
|
||||
if(loopContains(newObstacleLocation)){
|
||||
return false;
|
||||
}
|
||||
if(newObstacleLocation.getA() >= map.size()){
|
||||
return false;
|
||||
}
|
||||
if(newObstacleLocation.getA() < 0){
|
||||
return false;
|
||||
}
|
||||
if(newObstacleLocation.getB() >= map.get(newObstacleLocation.getA()).length()){
|
||||
return false;
|
||||
}
|
||||
if(newObstacleLocation.getB() < 0){
|
||||
return false;
|
||||
}
|
||||
if(map.get(newObstacleLocation.getA()).charAt(newObstacleLocation.getB()) != '.'){
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean loop = false;
|
||||
List<String> originalMap = new ArrayList<>(map);
|
||||
List<Triple<Integer, Integer, Character>> originalHistory = new ArrayList<>(patrolHistory);
|
||||
patrolHistory = new ArrayList<>();
|
||||
//int orgLoopCnt = loopCounter;
|
||||
//loopCounter = 0;
|
||||
//int orgLoopMax = LOOP_MAX;
|
||||
//LOOP_MAX = 1000;
|
||||
|
||||
|
||||
StringBuilder mapLine = new StringBuilder(map.get(newObstacleLocation.getA()));
|
||||
mapLine.setCharAt(newObstacleLocation.getB(), '#');
|
||||
map.set(newObstacleLocation.getA(), mapLine.toString());
|
||||
|
||||
traverseMap(originalHistory.get(0), true);
|
||||
|
||||
/* */
|
||||
if(newObstacleLocation.getC() == '^'){
|
||||
//traverseMap(new Triple<>(newObstacleLocation.getA(), newObstacleLocation.getB() + 1, newObstacleLocation.getC()), true);
|
||||
}
|
||||
else if(newObstacleLocation.getC() == '>'){
|
||||
//traverseMap(new Triple<>(newObstacleLocation.getA() + 1, newObstacleLocation.getB(), newObstacleLocation.getC()), true);
|
||||
}
|
||||
else if(newObstacleLocation.getC() == 'v'){
|
||||
//traverseMap(new Triple<>(newObstacleLocation.getA(), newObstacleLocation.getB() - 1, newObstacleLocation.getC()), true);
|
||||
}
|
||||
else if(newObstacleLocation.getC() == '<'){
|
||||
//traverseMap(new Triple<>(newObstacleLocation.getA() - 1, newObstacleLocation.getB(), newObstacleLocation.getC()), true);
|
||||
}
|
||||
/* */
|
||||
|
||||
int lastLocation = patrolHistory.indexOf(patrolHistory.get(patrolHistory.size() - 1));
|
||||
if((lastLocation != -1) && (lastLocation != patrolHistory.size() - 1)){
|
||||
loop = true;
|
||||
}
|
||||
|
||||
|
||||
map = originalMap;
|
||||
patrolHistory = originalHistory;
|
||||
//loopCounter = orgLoopCnt;
|
||||
//LOOP_MAX = orgLoopMax;
|
||||
|
||||
return loop;
|
||||
}
|
||||
|
||||
private boolean loopContains(Triple<Integer, Integer, Character> loopLocation){
|
||||
for(Triple<Integer, Integer, Character> location : loopLocations){
|
||||
if(location.getA() == loopLocation.getA() && location.getB() == loopLocation.getB()){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void printMap(){
|
||||
for(String mapLine : map){
|
||||
System.out.println(mapLine);
|
||||
}
|
||||
}
|
||||
|
||||
private void placePotentialLoops(){
|
||||
for(Triple<Integer, Integer, Character> loopLocation : loopLocations){
|
||||
StringBuilder mapLine = new StringBuilder(map.get(loopLocation.getA()));
|
||||
mapLine.setCharAt(loopLocation.getB(), 'O');
|
||||
map.set(loopLocation.getA(), mapLine.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//! Too small
|
||||
/*
|
||||
360
|
||||
*/
|
||||
//! Too large
|
||||
/*
|
||||
1938
|
||||
*/
|
||||
|
||||
//! ?
|
||||
/*
|
||||
1065
|
||||
*/
|
||||
|
||||
//! ?
|
||||
/*
|
||||
Find the number of places that a new obstacle could be placed that creates a patrol loop.
|
||||
The number of positions that a new object could be placed to create a patrol loop is 1682.
|
||||
It took 1.641 seconds to run the algorithm.
|
||||
*/
|
||||
|
||||
//! How?
|
||||
/*
|
||||
1723
|
||||
*/
|
||||
Reference in New Issue
Block a user