Full kode finner du her.
Main metode
For alle oppgavene i 2024 bruker jeg Java, og dette vil være metoden jeg bruker for å hente input for de ulike oppgavene. Input blir lagret i en txt fil og hentes via denne metoden.
Oppgave 1
Oppgave 1 for luke 6 går ut på å forutse vakten sin rute inntil vakten går ut av det planlagte feltet. Kodemessig vil dette da si når vakten sin neste x eller y posisjon vil være mindre enn 0 eller større enn lengden av feltet. Vakten vil alltid gå i en rett linje inntil den treffer en vegg, indikert av #. Ved krasj snur vakten 90 grader og fortsetter rett frem igjen. For å finne når vakten går ut av feltet kan vi simulerere vaktens gange. For å gjøre dette setter vi først opp feltet vakten går innenfor. Ved denne metoden:
int x = 0;
int y = 0;
for (int i = 0; i < lines.size(); i++) {
String line = lines.get(i);
if (line.contains("^")) {
y = i;
for (int j = 0; j < line.length(); j++) {
if (line.charAt(j) == '^') {
x = j;
break;
}
}
break;
}
}
HashSet<String> visited = walk(lines, x, y);
Metode for å simulere vaktens gange:
private static HashSet<String> walk(List<String> lines, int x, int y) {
HashSet<String> visited = new HashSet<>();
visited.add(y + "," + x);
int[][] directions = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
int i = 0;
while (x > 0 && y > 0 && y < lines.size() - 1 && x < lines.getFirst().length() - 1) {
if (lines.get(y + directions[i][0]).charAt(x + directions[i][1]) == '#') i++;
else {
y += directions[i][0];
x += directions[i][1];
}
visited.add(y + "," + x);
if(i == 4) i = 0;
}
return visited;
}
I main metoden printer vi størrelsen på HashSettet. Vi bruker HashSet siden vi kun ønsker de unike feltene.
Oppgave 2
For oppgave 2 skal vi finne når vakten vil ende opp med å gå i loop dersom vi plasserer flere vegger/bygninger. Vi ønsker å finne ut hvor mange potensielle loops det finnes i feltet for vakten. For dette oppretter vi en ekstra for loop i main for å kun plassere vegger/bygninger der vakten ville gått, ettersom alle andre steder vil være unødvendig.
int possibleLoops = 0;
for (int i = 0; i < lines.size(); i++) {
for (int j = 0; j < lines.getFirst().length(); j++) {
if (lines.get(i).charAt(j) != '^'
&& visited.contains(i + "," + j)) {
if (walkObstacle(lines, x, y, j, i) == 0) possibleLoops++;
}
}
}
Vi kjører så en oppdatert walk for å sjekke om det resulterer i en loop eller om vakten går ut av feltet.
private static int walkObstacle(List<String> lines, int x, int y, int obstacleX, int obstacleY) {
String obstacleLine = lines.get(obstacleY);
lines.set(obstacleY, obstacleLine.substring(0, obstacleX) + "#" + obstacleLine.substring(obstacleX + 1));
HashSet<String> obstacles = new HashSet<>();
int[][] directions = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
int i = 0;
while (x > 0 && y > 0 && y < lines.size() - 1 && x < lines.getFirst().length() - 1) {
if (lines.get(y + directions[i][0]).charAt(x + directions[i][1]) == '#'){
if(!obstacles.add(x + "," + y + " - " + directions[i][0] + directions[i][1])){
lines.set(obstacleY, obstacleLine);
return 0;
}
i++;
}
else {
y += directions[i][0];
x += directions[i][1];
}
if(i == 4) i = 0;
}
lines.set(obstacleY, obstacleLine);
return (obstacles.size());
}
I main metoden printer vi så antallet potensielle loops.