-
Notifications
You must be signed in to change notification settings - Fork 0
/
day15_1.groovy
108 lines (94 loc) · 2.89 KB
/
day15_1.groovy
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
import java.lang.StringBuilder
def sampleInputSmall = '''########
#..O.O.#
##@.O..#
#...O..#
#.#.O..#
#...O..#
#......#
########
<^^>>>vv<v>>v<<'''
def sampleInput = '''##########
#..O..O.O#
#......O.#
#.OO..O.O#
#O#..O...#
#O..O..O.#
#.OO.O.OO#
#....O...#
##########
<vv>^<v^>v>^vv^v>v<>v^v<v<^vv<<<^><<><>>v<vvv<>^v^>^<<<><<v<<<v^vv^v>^
vvv<<^>^v^^><<>>><>^<<><^vv^^<>vvv<>><^^v>^>vv<>v<<<<v<^v>^<^^>>>^<v<v
><>vv>v^v^<>><>>>><^^>vv>v<^^^>>v^v^<^^>v^^>v^<^v>v<>>v^v^<v>v^^<^^vv<
<<v<^>>^^^^>>>v^<>vvv^><v<<<>^^^vv^<vvv>^>v<^^^^v<>^>vvvv><>>v^<<^^^^^
^><^><>>><>^^<<^^v>>><^<v>^<vv>>v>>>^v><>^v><<<<v>>v<v<v>vvv>^<><<>^><
^>><>^v<><^vvv<^^<><v<<<<<><^v<<<><<<^^<v<^^^><^>>^<v^><<<^>>^v<v^v<v^
>^>>^v>vv>^<<^v<>><<><<v<<v><>v<^vv<<<>^^v^>^^>>><<^v>>v^v><^^>>^<>vv^
<><^^>^^^<><vvvvv^v<v<<>^v<v>v<<^><<><<><<<^^<<<^<<>><<><^^^>^^<>^>v<>
^^>vv<^v^v<vv>^<><v<^v>^^^>>>^^vvv^>vvv<>>>^<^>>>>>^<<^v>^vvv<>^<><<v>
v^^>>><<^^<>>^v^<v^vv<>v^<<>^<^v^v><^<<<><<^<v><v<>vv>>v><v^<vv<>v^<<^'''
static def parse(List<String> input) {
int indexOfEmptyLine = input.findIndexOf { it.isEmpty() }
def map = input.take(indexOfEmptyLine).collect { new StringBuilder(it) }
int i = (0..<map.size()).find {
map[it].contains('@')
}
def j = map[i].indexOf('@')
def commands = input.drop(indexOfEmptyLine + 1).join('')
[[i, j], map, commands]
}
enum DIR {
UP('^', [-1, 0]), RIGHT('>', [0, 1]), DOWN('v', [1, 0]), LEFT('<', [0, -1])
def sign
def dir
DIR(sign, dir) {
this.sign = sign
this.dir = dir
}
}
static def getAt(def map, def pos) {
map[pos[0]][pos[1]]
}
static def next(def pos, def dir) {
[pos[0] + dir[0], pos[1] + dir[1]]
}
// note: modifies map
static def move(def start, def dir, def map) {
def end = next(start, dir)
while (getAt(map, end) == 'O') {
end = next(end, dir)
}
if (getAt(map, end) == '.') {
def closest = next(start, dir)
if(getAt(map, closest) == 'O') {
map[end[0]].replace(end[1], end[1]+1, 'O')
}
map[start[0]].replace(start[1], start[1]+1, '.')
map[closest[0]].replace(closest[1], closest[1]+1, '@')
return closest
}
start
}
static def transform(def start, def map, String commands) {
commands.each { c ->
def dir = DIR.values().find { it.sign == c }?.dir
start = move(start, dir, map)
}
}
static long solve(List<String> input) {
def (start, map, commands) = parse(input)
transform(start, map, commands)
def sumOfBoxesGPSCoordinates = 0
map.size().times { i ->
map[i].size().times { j ->
if (map[i][j] == 'O') {
sumOfBoxesGPSCoordinates += i * 100 + j
}
}
}
sumOfBoxesGPSCoordinates
}
assert 2028L == solve(sampleInputSmall.split('\n') as List)
assert 10092L == solve(sampleInput.split('\n') as List)
println solve(new File('input/day15.txt').readLines())