-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay12Part2.java
87 lines (72 loc) · 2.77 KB
/
Day12Part2.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package uk.oczadly.karl.aoc20.solution.day12;
import uk.oczadly.karl.aoc20.PuzzleSolution;
import uk.oczadly.karl.aoc20.input.IllegalInputException;
import uk.oczadly.karl.aoc20.input.PuzzleInput;
import uk.oczadly.karl.aoc20.util.InputUtil;
import java.util.regex.Matcher;
/**
* @author Karl Oczadly
*/
public class Day12Part2 extends PuzzleSolution {
public Day12Part2() { super(12, 2); } // Initializes the day and part number
@Override
public Object solve(PuzzleInput input) {
Ship ship = new Ship(new Waypoint(10, 1)); // Starts with waypoint ahead 10 east, 1 north
// Process each instruction
input.asStream()
.map(InputUtil.regexMapper("^(\\w)(\\d+)$"))
.forEachOrdered(ship::readInstruction);
// Return manhattan distance from origin (0, 0)
return Math.abs(ship.x) + Math.abs(ship.y);
}
static class Waypoint {
int x, y; // X and Y values are offsets from the ship, starting at (0, 0)
public Waypoint(int x, int y) {
this.x = x;
this.y = y;
}
/** Rotates the waypoint clockwise around (0, 0) */
public void rotate(int degrees) {
if (degrees == 90 || degrees == 270) {
int tmpX = x;
x = y;
y = -tmpX;
}
if (degrees == 180 || degrees == 270) {
x = -x;
y = -y;
}
}
}
static class Ship {
int x, y;
Waypoint waypoint;
public Ship(Waypoint waypoint) {
this.waypoint = waypoint;
}
/** Parses an instruction from the input, and processes it. */
public void readInstruction(Matcher input) {
int val = Integer.parseInt(input.group(2));
switch (input.group(1).charAt(0)) {
case 'N': // Move waypoint north
waypoint.y += val; break;
case 'S': // Move waypoint south
waypoint.y -= val; break;
case 'E': // Move waypoint east
waypoint.x += val; break;
case 'W': // Move waypoint west
waypoint.x -= val; break;
case 'L': // Rotate waypoint anticlockwise
waypoint.rotate(360 - val); break;
case 'R': // Rotate waypoint clockwise
waypoint.rotate(val); break;
case 'F': // Move ship towards waypoint
x += waypoint.x * val;
y += waypoint.y * val;
break;
default:
throw new IllegalInputException("Unknown instruction code.");
}
}
}
}