-
Notifications
You must be signed in to change notification settings - Fork 0
/
Solution.kt
144 lines (127 loc) · 4.62 KB
/
Solution.kt
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package solutions.day12
import solutions.GenericSolution
import util.readLines
import java.io.File
import java.security.InvalidParameterException
import kotlin.math.abs
private const val NORTH = 'N'
private const val EAST = 'E'
private const val SOUTH = 'S'
private const val WEST = 'W'
private const val LEFT = 'L'
private const val RIGHT = 'R'
private const val FORWARD = 'F'
private data class ShipPosition(
var x: Int,
var y: Int,
var bearing: Char
)
private data class WaypointPosition(
var x: Int,
var y: Int
)
class Solution : GenericSolution {
private fun turn(shipPosition: ShipPosition, action: Char, value: Int) {
for (turn in 0 until value / 90) {
when (action) {
LEFT -> {
shipPosition.bearing = when (shipPosition.bearing) {
NORTH -> WEST
WEST -> SOUTH
SOUTH -> EAST
EAST -> NORTH
else -> throw InvalidParameterException()
}
}
RIGHT -> {
shipPosition.bearing = when (shipPosition.bearing) {
NORTH -> EAST
EAST -> SOUTH
SOUTH -> WEST
WEST -> NORTH
else -> throw InvalidParameterException()
}
}
}
}
}
// North & East positive, South & West negative
private fun navigate(shipPosition: ShipPosition, action: Char, value: Int) {
when (action) {
NORTH -> shipPosition.y += value
EAST -> shipPosition.x += value
SOUTH -> shipPosition.y -= value
WEST -> shipPosition.x -= value
LEFT -> turn(shipPosition, action, value)
RIGHT -> turn(shipPosition, action, value)
FORWARD -> navigate(shipPosition, shipPosition.bearing, value)
}
}
private fun navigate(shipPosition: ShipPosition, instructions: List<String>) {
instructions.forEach {
val action = it[0]
val value = it.substring(1).toInt()
navigate(shipPosition, action, value)
}
}
override fun runPart1(inputFile: File): String {
val instructions = readLines(inputFile)
val shipPosition = ShipPosition(0, 0, EAST)
navigate(shipPosition, instructions)
return (abs(shipPosition.x) + abs(shipPosition.y)).toString()
}
private fun turnWaypoint(waypointPosition: WaypointPosition, action: Char, value: Int) {
for (turn in 0 until value / 90) {
when (action) {
LEFT -> {
val y = waypointPosition.x
waypointPosition.x = -waypointPosition.y
waypointPosition.y = y
}
RIGHT -> {
val y = -waypointPosition.x
waypointPosition.x = waypointPosition.y
waypointPosition.y = y
}
}
}
}
private fun navigateToWaypoint(shipPosition: ShipPosition, waypointPosition: WaypointPosition, value: Int) {
shipPosition.x = shipPosition.x + value * waypointPosition.x
shipPosition.y = shipPosition.y + value * waypointPosition.y
}
private fun navigateByWaypoint(
shipPosition: ShipPosition,
waypointPosition: WaypointPosition,
action: Char,
value: Int
) {
when (action) {
NORTH -> waypointPosition.y += value
EAST -> waypointPosition.x += value
SOUTH -> waypointPosition.y -= value
WEST -> waypointPosition.x -= value
LEFT -> turnWaypoint(waypointPosition, action, value)
RIGHT -> turnWaypoint(waypointPosition, action, value)
FORWARD -> navigateToWaypoint(shipPosition, waypointPosition, value)
}
}
private fun navigateByWaypoint(
shipPosition: ShipPosition,
waypointPosition: WaypointPosition,
instructions: List<String>
) {
instructions.forEach {
val action = it[0]
val value = it.substring(1).toInt()
navigateByWaypoint(shipPosition, waypointPosition, action, value)
}
}
override fun runPart2(inputFile: File): String {
val instructions = readLines(inputFile)
val shipPosition = ShipPosition(0, 0, EAST)
val waypointPosition = WaypointPosition(10, 1)
navigateByWaypoint(shipPosition, waypointPosition, instructions)
return (abs(shipPosition.x) + abs(shipPosition.y)).toString()
}
}