-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path12.js
75 lines (65 loc) · 1.66 KB
/
12.js
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
// testPuzzle = document.querySelector('pre > code').textContent.trimRight().split('\n')
puzzle = document.body.textContent.trimRight().split('\n')
function part1(puzzle) {
const actions = Navigation.decodeActions(puzzle)
const navigator = new Navigation('E')
for (const [action, amount] of actions) {
navigator.takeAction(action, amount)
}
console.log(navigator)
return navigator.calcManhattanDistance()
}
// helpers:
class Navigation {
constructor(dir) {
this.dir = dir
this.v = 0 // north-south
this.h = 0 // east-west
}
static decodeActions(puzzle) {
return puzzle.map(instruction => [instruction[0], Number(instruction.slice(1))])
}
takeAction(action, amount) {
switch (action) {
case 'N':
this.v += amount
break
case 'S':
this.v -= amount
break
case 'E':
this.h += amount
break
case 'W':
this.h -= amount
break
case 'L':
this.rotate(-amount)
break
case 'R':
this.rotate(amount)
break
case 'F':
this.takeAction(this.dir, amount)
break
default:
throw new Error(`'${action}' is not a valid action`)
}
}
// TODO: refactor
rotate(amount) {
const target = Math.abs(amount / 90)
if (amount > 0) {
const cw = ['E', 'S', 'W', 'N']
const current = cw.indexOf(this.dir)
this.dir = cw[(current + target) % 4]
} else {
const ccw = ['E', 'N', 'W', 'S']
const current = ccw.indexOf(this.dir)
this.dir = ccw[(current + target) % 4]
}
}
calcManhattanDistance() {
return Math.abs(this.v) + Math.abs(this.h)
}
}