-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path06.js
78 lines (73 loc) · 2.02 KB
/
06.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
76
77
78
const fs = require('fs')
const args = process.argv.slice(2)
const data = fs.readFileSync(args[0], 'utf8')
const lines = data.split('\n')
const puzzle = []
let guard = []
lines.forEach((line, y) => {
const x = line.indexOf('^')
if (x !== -1) {
guard = [x, y]
}
puzzle.push(line.split(''))
})
let firstpass = JSON.parse(JSON.stringify(puzzle))
let [positions, _] = moveGuard(guard, firstpass)
console.log('Del 1:', positions)
// Del 2
let loops = 0
for (let y = 0; y < puzzle.length; y++) {
let now = Date.now()
for (let x = 0; x < puzzle[y].length; x++) {
if (firstpass[y][x] != 'X') continue
let puzzlecopy = JSON.parse(JSON.stringify(puzzle))
puzzlecopy[y][x] = 'O'
const [_, loop] = moveGuard(guard, puzzlecopy)
if (loop) {
loops++
}
}
console.log({ y, time: Date.now() - now })
}
console.log('Del 2:', loops)
function moveGuard(start, p) {
let cache = new Set()
let positions = 0
let guarddir = 0
let guard = [start[0], start[1]]
const dir = [[0, -1], [1, 0], [0, 1], [-1, 0]]
let next = p[guard[1]][guard[0]]
do {
let [dx, dy] = dir[guarddir]
let nx = guard[0] + dx
let ny = guard[1] + dy
if (p[ny] === undefined) break
next = p[ny][nx]
if (next != '#' && next != 'O') {
guard[0] += dx
guard[1] += dy
p[ny][nx] = 'X'
if (next != 'X') {
cache.add(nx+','+ny+','+dx+','+dy)
positions++
}
} else {
guarddir = (guarddir + 1) % dir.length
dx = dir[guarddir][0]
dy = dir[guarddir][1]
}
// Loop detection
if (next == 'O' || next == 'X') {
if (cache.has(nx+','+ny+','+dx+','+dy)) {
return [positions, true]
}
}
} while (next != undefined);
return [positions, false]
}
function printPuzzle(p) {
p.forEach(line => {
console.log(line.join(''))
})
console.log()
}