cem 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/examples/aoc2018/.gitignore +2 -0
  3. data/examples/aoc2018/day10.rb +61 -0
  4. data/examples/aoc2018/day11.rb +66 -0
  5. data/examples/aoc2018/day12.rb +61 -0
  6. data/examples/aoc2018/day13.rb +167 -0
  7. data/examples/aoc2018/day14.rb +31 -0
  8. data/examples/aoc2018/day14_2.rb +71 -0
  9. data/examples/aoc2018/day15.rb +271 -0
  10. data/examples/aoc2018/day16.rb +158 -0
  11. data/examples/aoc2018/day17.rb +203 -0
  12. data/examples/aoc2018/day18.rb +113 -0
  13. data/examples/aoc2018/day18_rspec.rb +131 -0
  14. data/examples/aoc2018/day19.rb +145 -0
  15. data/examples/aoc2018/day20.rb +103 -0
  16. data/examples/aoc2018/day21.rb +158 -0
  17. data/examples/aoc2018/day21_v2.rb +137 -0
  18. data/examples/aoc2018/day21_v3.rb +157 -0
  19. data/examples/aoc2018/day21_v4.rb +141 -0
  20. data/examples/aoc2018/day22.rb +212 -0
  21. data/examples/aoc2018/day23.rb +148 -0
  22. data/examples/aoc2018/day24.rb +156 -0
  23. data/examples/aoc2018/day25.rb +52 -0
  24. data/examples/aoc2018/day9.rb +51 -0
  25. data/examples/aoc2018/day9_circular.rb +125 -0
  26. data/examples/aoc2018/inputs/day10_input.txt +395 -0
  27. data/examples/aoc2018/inputs/day11_input.txt +1 -0
  28. data/examples/aoc2018/inputs/day12_input.txt +34 -0
  29. data/examples/aoc2018/inputs/day12_input2.txt +16 -0
  30. data/examples/aoc2018/inputs/day13_input.txt +150 -0
  31. data/examples/aoc2018/inputs/day13_test.txt +6 -0
  32. data/examples/aoc2018/inputs/day14_input.txt +1 -0
  33. data/examples/aoc2018/inputs/day15_input.txt +32 -0
  34. data/examples/aoc2018/inputs/day15_input10.txt +32 -0
  35. data/examples/aoc2018/inputs/day15_input11.txt +32 -0
  36. data/examples/aoc2018/inputs/day15_input12.txt +32 -0
  37. data/examples/aoc2018/inputs/day15_input13.txt +32 -0
  38. data/examples/aoc2018/inputs/day15_input14.txt +32 -0
  39. data/examples/aoc2018/inputs/day15_input2.txt +7 -0
  40. data/examples/aoc2018/inputs/day15_input3.txt +9 -0
  41. data/examples/aoc2018/inputs/day15_input4.txt +7 -0
  42. data/examples/aoc2018/inputs/day15_input5.txt +7 -0
  43. data/examples/aoc2018/inputs/day15_input6.txt +7 -0
  44. data/examples/aoc2018/inputs/day15_input7.txt +7 -0
  45. data/examples/aoc2018/inputs/day15_input8.txt +5 -0
  46. data/examples/aoc2018/inputs/day15_input9.txt +7 -0
  47. data/examples/aoc2018/inputs/day15_test.txt +9 -0
  48. data/examples/aoc2018/inputs/day16_input.txt +3865 -0
  49. data/examples/aoc2018/inputs/day17_input.txt +2229 -0
  50. data/examples/aoc2018/inputs/day17_input_test.txt +8 -0
  51. data/examples/aoc2018/inputs/day18_input.txt +50 -0
  52. data/examples/aoc2018/inputs/day18_test.txt +10 -0
  53. data/examples/aoc2018/inputs/day19_input.txt +48 -0
  54. data/examples/aoc2018/inputs/day20_input.txt +1 -0
  55. data/examples/aoc2018/inputs/day21_input.txt +32 -0
  56. data/examples/aoc2018/inputs/day22_input.txt +2 -0
  57. data/examples/aoc2018/inputs/day23_input.txt +1000 -0
  58. data/examples/aoc2018/inputs/day23_input2.txt +9 -0
  59. data/examples/aoc2018/inputs/day24_input.txt +24 -0
  60. data/examples/aoc2018/inputs/day25_input.txt +1483 -0
  61. data/examples/aoc2018/inputs/day9_input.txt +1 -0
  62. data/lib/cem.rb +0 -6
  63. data/lib/cem/ccommon.rb +45 -0
  64. data/lib/cem/cruzzles.rb +93 -38
  65. data/lib/cem/version.rb +1 -1
  66. metadata +62 -2
@@ -0,0 +1,271 @@
1
+
2
+ #
3
+ # https://adventofcode.com/2018/day/15 part 1 and part 2
4
+ #
5
+ # Demonstrate use of Point2D and Grid
6
+ #
7
+ # This task took me a long time, because I did a array.sort instead of array.sort!
8
+ #
9
+
10
+ require 'cem'
11
+
12
+ Agent = Struct.new("Agent", :pos, :faction, :hp)
13
+
14
+ class Puzzle
15
+
16
+ attr_accessor :persons, :lines, :dirs
17
+
18
+ def initialize
19
+ @persons = []
20
+ @grid = []
21
+ @dirs = []
22
+ end
23
+
24
+ def others(o)
25
+ @persons.select { |p| p.faction != o.faction }
26
+ end
27
+
28
+ def adjacents(o)
29
+ @dirs.map {|dir| o.pos + dir if @grid[o.pos + dir] == '.'}.compact
30
+ end
31
+
32
+ def free(pos)
33
+ @grid[pos] == '.' && @persons.find { |p| p.pos == pos } == nil
34
+ end
35
+
36
+ def printBoard(overlay = nil)
37
+
38
+ @grid.data.each_with_index { |l, y|
39
+ l.each_with_index { |c, x|
40
+
41
+ pos = Point2D.new(x,y)
42
+
43
+ if overlay && overlay.has_key?(pos)
44
+ print overlay[pos]
45
+ else
46
+ p = @persons.find { |p| p.pos == pos }
47
+ if p
48
+ print p.faction
49
+ else
50
+ print c
51
+ end
52
+ end
53
+ }
54
+
55
+ puts " " + @persons.select{ |p| p.pos.y == y }.sort_by { |p| p.pos.x }.map {|p| "#{p.faction}(#{p.hp})"}.join(", ")
56
+ }
57
+ end
58
+
59
+ def run(inputFilename, debug, elvenPower=3)
60
+
61
+ # Crucial to sort the directions as given in the problem description
62
+ @dirs = Dirs2D.sort_by { |pos| pos.y * 10000 + pos.x }
63
+
64
+ lines = []
65
+ File.readlines(inputFilename, chomp: true).each { |line|
66
+ lines << line.rstrip.chars
67
+ }
68
+
69
+ @grid = Grid.new(lines.size, lines[0].size, ' ')
70
+ @grid.data = lines
71
+
72
+ # Read board
73
+ @grid.map_a! { |p, c|
74
+ case c
75
+ when 'E', 'G'
76
+ @persons << Agent.new(p, c, 200)
77
+ next '.'
78
+ end
79
+ }
80
+
81
+ generation = -1
82
+
83
+ loop do
84
+
85
+ system "cls" if debug
86
+
87
+ generation += 1
88
+
89
+ if generation == 0
90
+ puts "Initial Generation with power #{elvenPower}" if debug
91
+ else
92
+ puts "After Generation: #{generation} with power #{elvenPower}" if debug
93
+ end
94
+
95
+ printBoard if debug
96
+ #gets if debug && generation >= 70
97
+
98
+ @persons.sort_by { |cart| cart.pos.y * 10000 + cart.pos.x }.each { |p|
99
+
100
+ next if !@persons.include?(p)
101
+
102
+ if @persons.select {|p| p.faction == 'E' }.size == 0 || @persons.select {|p| p.faction == 'G' }.size == 0
103
+ system "cls" if debug
104
+ puts "Before Generation: #{generation} finishes" if debug
105
+ printBoard if debug
106
+
107
+ puts "#{generation} * #{@persons.sum {|p| p.hp }} = #{generation * @persons.sum {|p| p.hp }}"
108
+ return (@persons[0].faction == 'E' ? 1 : -1) * generation * @persons.sum {|p| p.hp }
109
+ end
110
+
111
+ # puts p.inspect
112
+
113
+ # Moving
114
+ nearby = @persons.select { |o| o.faction != p.faction && dirs.any? { |dir| p.pos + dir == o.pos } }.group_by { |o| o.hp }.min_by { |k,v| k }
115
+
116
+ if nearby == nil || nearby.size == 0
117
+ distancemap = Array.new(@grid.data.size) { Array.new(@grid[0].size)}
118
+
119
+ targets = Set.new(others(p).map {|o| adjacents(o)}.flatten)
120
+
121
+ s = p.pos
122
+ distancemap[s.y][s.x] = 0
123
+ bfs = []
124
+ bfsNG = [s]
125
+ found = []
126
+
127
+ target = []
128
+ while bfsNG.size > 0 && found.size == 0
129
+ bfs = bfsNG
130
+ bfsNG = []
131
+ while bfs.size > 0
132
+
133
+ s = bfs.shift
134
+
135
+ dirs.each { |dir|
136
+
137
+ s2 = s + dir
138
+
139
+ if free(s2)
140
+
141
+ if distancemap[s2.y][s2.x] == nil
142
+ bfsNG << s2
143
+ #puts " free " + s2.inspect + " - " + dir.to_s
144
+ distancemap[s2.y][s2.x] = dir.flip
145
+ end
146
+
147
+ if targets.include?(s2)
148
+ found << s2
149
+ end
150
+ end
151
+ }
152
+ end
153
+ end
154
+
155
+ if found.size > 0
156
+ found.sort_by! { |p| p.y * 10000 + p.x }
157
+
158
+ overlay = {}
159
+
160
+ if found.size > 1
161
+ found.each { |p| overlay[p] = '+' }
162
+ overlay[found[0]] = 'X'
163
+ end
164
+
165
+ target = found[0]
166
+ #puts " Target: #{target}"
167
+
168
+ lastMove = nil
169
+
170
+ while target && target != p.pos
171
+ lastMove = distancemap[target.y][target.x]
172
+ #puts target.inspect
173
+ overlay[target] = 'x'
174
+ target = target + lastMove
175
+ end
176
+
177
+ #if generation >= 77
178
+ # system('cls')
179
+ # printBoard(overlay)
180
+ # puts found.inspect
181
+ # gets
182
+ #end
183
+
184
+ p.pos = p.pos + lastMove.flip if lastMove
185
+ #puts " Moved to #{p.pos}"
186
+ end
187
+ end
188
+
189
+ # Fighting
190
+ nearby = @persons.select { |o| o.faction != p.faction && dirs.any? { |dir| p.pos + dir == o.pos } }.group_by { |o| o.hp }.min_by { |k,v| k }
191
+ if nearby && nearby.size > 0
192
+ nearby = nearby[1]
193
+
194
+ #puts "Fighting"
195
+ nearby.sort_by! { |cart| cart.pos.y * 10000 + cart.pos.x }
196
+
197
+ if p.faction == 'E'
198
+ nearby[0].hp -= elvenPower
199
+ else
200
+ nearby[0].hp -= 3
201
+ end
202
+
203
+ if (nearby[0].hp <= 0)
204
+ @persons -= [nearby[0]]
205
+
206
+ if nearby[0].faction == 'E' && elvenPower > 3
207
+ return -1
208
+ end
209
+ end
210
+ end
211
+
212
+ }
213
+
214
+
215
+ end
216
+ end
217
+
218
+ end
219
+
220
+ part1 = {
221
+ # "inputs/day15_input14.txt" => -248848,
222
+ # "inputs/day15_input13.txt" => -261855,
223
+ # "inputs/day15_input12.txt" => -189000,
224
+ # "inputs/day15_input11.txt" => '?',
225
+ # "inputs/day15_input10.txt" => -261855,
226
+ # "inputs/day15_input2.txt" => -27730,
227
+ # "inputs/day15_input3.txt" => -18740,
228
+ # "inputs/day15_input4.txt" => 36334,
229
+ # "inputs/day15_input5.txt" => 39514,
230
+ # "inputs/day15_input6.txt" => -27755,
231
+ # "inputs/day15_input7.txt" => -28944,
232
+ "inputs/day15_input.txt" => '?'
233
+ }
234
+
235
+ debug = false
236
+
237
+ part1.each_pair { |k,v|
238
+
239
+ power = 3
240
+ is = Puzzle.new.run(k, debug, power)
241
+
242
+ puts "Part 1: #{k} == #{is}"
243
+ if is != v && v != '?'
244
+ puts "#{k} should be #{v}, but is #{is}"
245
+ exit
246
+ end
247
+ }
248
+
249
+
250
+ part2 = {
251
+ "inputs/day15_input.txt" => '?'
252
+ }
253
+
254
+ part2.each_pair { |k,v|
255
+
256
+ power = 4
257
+ while true
258
+ # puts "Elven Power: #{power} "
259
+ is = Puzzle.new.run(k, debug, power)
260
+ power += 1
261
+ if is > 0
262
+ break;
263
+ end
264
+ end
265
+
266
+ puts "Part 2: #{k} == #{is}"
267
+ if is != v && v != '?'
268
+ puts "#{k} should be #{v}, but is #{is}"
269
+ exit
270
+ end
271
+ }
@@ -0,0 +1,158 @@
1
+ #
2
+ # https://adventofcode.com/2018/day/16 part 1 and part 2
3
+ #
4
+ # Does not use any 'cem' functions
5
+ #
6
+
7
+ input = File.readlines("inputs/day16_input.txt", chomp: true)
8
+
9
+ data = []
10
+ inputs = []
11
+
12
+ input.each { |line|
13
+
14
+ if line =~ /^Before\: \[([+-]?\d+), ([+-]?\d+), ([+-]?\d+), ([+-]?\d+)\]$/
15
+
16
+ v1 = $1.to_i
17
+ v2 = $2.to_i
18
+ v3 = $3.to_i
19
+ v4 = $4.to_i
20
+
21
+ data << [v1,v2,v3,v4]
22
+
23
+ end
24
+
25
+ if line =~ /^([+-]?\d+) ([+-]?\d+) ([+-]?\d+) ([+-]?\d+)$/
26
+
27
+
28
+ v1 = $1.to_i
29
+ v2 = $2.to_i
30
+ v3 = $3.to_i
31
+ v4 = $4.to_i
32
+
33
+ data << [v1,v2,v3,v4]
34
+ end
35
+
36
+ if line =~ /^After\: \[([+-]?\d+), ([+-]?\d+), ([+-]?\d+), ([+-]?\d+)\]$/
37
+ v1 = $1.to_i
38
+ v2 = $2.to_i
39
+ v3 = $3.to_i
40
+ v4 = $4.to_i
41
+
42
+ data << [v1,v2,v3,v4]
43
+
44
+ # puts data.inspect
45
+ inputs << data
46
+ data = []
47
+ end
48
+
49
+ if line =~ /^$/
50
+ # data << $1.to_i
51
+ end
52
+ }
53
+
54
+ mapping = {}
55
+
56
+ def op(op, reg, command)
57
+
58
+ case op
59
+
60
+ when 0 # addr
61
+ reg[command[1]] + reg[command[2]]
62
+
63
+ when 1 # addi
64
+ reg[command[1]] + command[2]
65
+
66
+ when 2 # mulr
67
+ reg[command[1]] * reg[command[2]]
68
+
69
+ when 3 #muli
70
+ reg[command[1]] * command[2]
71
+
72
+ when 4 # banr
73
+ reg[command[1]] & reg[command[2]]
74
+
75
+ when 5 # bani
76
+ reg[command[1]] & command[2]
77
+
78
+ when 6 # borr
79
+ reg[command[1]] | reg[command[2]]
80
+
81
+ when 7 # bori
82
+ reg[command[1]] | command[2]
83
+
84
+ when 8 # setr
85
+ reg[command[1]]
86
+
87
+ when 9 # seti
88
+ command[1]
89
+
90
+ when 10 # gtir
91
+ command[1] > reg[command[2]] ? 1 : 0
92
+
93
+ when 11 # gtri
94
+ reg[command[1]] > command[2] ? 1 : 0
95
+
96
+ when 12 # gtrr
97
+ reg[command[1]] > reg[command[2]] ? 1 : 0
98
+
99
+ when 13 # eqir
100
+ command[1] == reg[command[2]] ? 1 : 0
101
+
102
+ when 14 # eqri
103
+ reg[command[1]] == command[2] ? 1 : 0
104
+
105
+ when 15 # eqrr
106
+ reg[command[1]] == reg[command[2]] ? 1 : 0
107
+
108
+ else
109
+ raise
110
+ end
111
+ end
112
+
113
+ result = 0
114
+ inputs.each { |data|
115
+
116
+ # puts data.inspect
117
+
118
+ # puts "Before: " + data[0].inspect
119
+ # puts "OP : " + data[1].inspect
120
+ # puts "After : " + data[2].inspect
121
+
122
+ # puts data[1].inspect + ": Cmd #{data[1][0]} on reg#{data[1][1]} val=#{data[0][data[1][1]]} op? reg#{data[1][2]} val=#{data[0][data[1][2]]} (imm #{data[1][2]}) == #{data[2][data[1][3]]} (was #{data[0][data[1][3]]})"
123
+
124
+ command = data[1]
125
+ matches = []
126
+ (0..15).each { |i|
127
+
128
+ reg = data[0].dup
129
+
130
+ reg[command[3]] = op(i, reg, command)
131
+
132
+ if reg == data[2]
133
+ matches << i
134
+ end
135
+ }
136
+
137
+ result += 1 if matches.size >= 3
138
+
139
+ matches = matches.select { |m| !mapping.values.include?(m) }
140
+
141
+ if matches.size == 1
142
+ mapping[data[1][0]] = matches[0]
143
+ end
144
+
145
+ # puts matches.inspect
146
+ }
147
+
148
+ # puts mapping.inspect
149
+
150
+ puts "Part 1: #{result}"
151
+
152
+ reg = [0,0,0,0]
153
+
154
+ data.each { |command|
155
+ reg[command[3]] = op(mapping[command[0]], reg, command)
156
+ }
157
+
158
+ puts "Part 2: #{reg[0]}"
@@ -0,0 +1,203 @@
1
+
2
+ #
3
+ # https://adventofcode.com/2018/day/17 part 1 and 2
4
+ #
5
+ # Demonstrates Point2D and Dir2D in particular #left, #right, #down methods. Could use Grid!
6
+ #
7
+
8
+ require 'cem'
9
+ require 'set'
10
+
11
+ input = File.readlines("inputs/day17_input.txt", chomp: true)
12
+
13
+ @vert = []
14
+ @hori = []
15
+ @waterTiles = Set.new
16
+ @deepWater = Set.new
17
+
18
+ input.each { |line|
19
+
20
+ if line =~ /^y=([+-]?\d+), x=([+-]?\d+)..([+-]?\d+)$/
21
+ v1 = $1.to_i
22
+ v2 = $2.to_i
23
+ v3 = $3.to_i
24
+
25
+ @vert << [v1,v2,v3]
26
+ end
27
+
28
+ if line =~ /^x=([+-]?\d+), y=([+-]?\d+)..([+-]?\d+)$/
29
+ v1 = $1.to_i
30
+ v2 = $2.to_i
31
+ v3 = $3.to_i
32
+
33
+ @hori << [v1,v2,v3]
34
+ end
35
+ }
36
+
37
+ @minY = [@vert.map { |v| v[0] }.min, @hori.map { |h| h[1] }.min].min
38
+ @maxY = [@vert.map { |v| v[0] }.max, @hori.map { |h| h[2] }.max].max
39
+
40
+ @minX = [@hori.map { |v| v[0] }.min, @vert.map { |h| h[1] }.min].min
41
+ @maxX = [@hori.map { |v| v[0] }.max, @vert.map { |h| h[2] }.max].max
42
+
43
+ cursor = Point2D.new(500, @minY)
44
+
45
+ @map = []
46
+ (0..@maxY + 1).each { |y|
47
+ @map << []
48
+ (0..@maxX + 1).each { |x|
49
+ @map[y] << ' '
50
+ }
51
+ }
52
+
53
+ @vert.each { |v|
54
+ (v[1]..v[2]).each {|x| @map[v[0]][x] = 'x' }
55
+ }
56
+ @hori.each {|h|
57
+ (h[1]..h[2]).each {|y| @map[y][h[0]] = 'x' }
58
+ }
59
+
60
+ def free(cursor)
61
+ @map[cursor.y][cursor.x] == ' '
62
+ end
63
+
64
+ def printMap(filename, map, overlay, deepWater, cursor=nil, windowSizeY = 15, windowSizeX = 35)
65
+
66
+ file = File.open(filename, 'w') if filename
67
+
68
+ if !filename
69
+ system('cls')
70
+ puts cursor
71
+ end
72
+
73
+ rangeY = cursor ? ((cursor.y - windowSizeY)..(cursor.y + windowSizeY)) : 0...map.size
74
+ rangeX = cursor ? ((cursor.x - windowSizeX)..(cursor.x + windowSizeX)) : 0...map[0].size
75
+
76
+ rangeY.each { |y|
77
+ l = map[y]
78
+ line = ''
79
+ rangeX.each { |x|
80
+ if l != nil
81
+ c = l[x]
82
+ else
83
+ c = nil
84
+ end
85
+
86
+ if c == nil
87
+ c = '?'
88
+ end
89
+
90
+ pos = Point2D.new(x,y)
91
+ if deepWater && deepWater.include?(pos)
92
+ line += '~'
93
+ elsif overlay && overlay.include?(pos)
94
+ line += '|'
95
+ else
96
+ line += c
97
+ end
98
+ }
99
+ if filename
100
+ file.write(line + "\n")
101
+ else
102
+ puts line
103
+ end
104
+ }
105
+
106
+ if !filename
107
+ gets
108
+ else
109
+ file.close
110
+ end
111
+
112
+ end
113
+
114
+ #
115
+ # returns true if all available space has been filled
116
+ #
117
+ def cursorMove(cursor)
118
+
119
+ cursorStart = cursor
120
+
121
+ @waterTiles << cursor
122
+
123
+ # Traverse down from cursor position
124
+ while free(cursor.down) && cursor.y < @maxY && !@waterTiles.include?(cursor.down)
125
+ printMap(nil, @map, @waterTiles, @deepWater, cursor) if false
126
+
127
+ cursor = cursor.down
128
+ @waterTiles << cursor
129
+ end
130
+
131
+ if cursor.y == @maxY
132
+ return false # we moved out of the field - stop recursion
133
+ end
134
+
135
+ if @waterTiles.include?(cursor.down) && !@deepWater.include?(cursor.down)
136
+ return false # already been here
137
+ end
138
+
139
+ # Below us is rock
140
+ left = right = rowStart = cursor
141
+
142
+ row = Set.new
143
+ row << rowStart
144
+
145
+ while true
146
+
147
+ while free(left.left) && !@waterTiles.include?(left.left) && (!free(left.down) || @deepWater.include?(left.down))
148
+ left = left.left
149
+ row << left
150
+ @waterTiles << left
151
+ end
152
+
153
+ while free(right.right) && !@waterTiles.include?(right.right) && (!free(right.down) || @deepWater.include?(right.down))
154
+ right = right.right
155
+ row << right
156
+ @waterTiles << right
157
+ end
158
+
159
+ printMap(nil, @map, @waterTiles, @deepWater, cursor) if false # && cursor.y > 1300 && cursor.y < 1330
160
+
161
+ if !free(right.right) && (!free(right.down) || @deepWater.include?(right.down)) && !free(left.left) && (!free(left.down) || @deepWater.include?(left.down))
162
+
163
+ # Move up
164
+ rowStart = rowStart.up
165
+
166
+ @deepWater.merge row
167
+ row = Set.new
168
+ row << rowStart
169
+
170
+ if rowStart.y < cursorStart.y
171
+ return true # Return true, if we filled all available space
172
+ end
173
+
174
+ left = right = rowStart
175
+
176
+ # Fill again...
177
+
178
+ else
179
+
180
+ a = !@waterTiles.include?(right.right) && !@waterTiles.include?(left.left)
181
+ if free(right.down) && !(!free(right.down) || @deepWater.include?(right.down))
182
+ a &= cursorMove(right.down)
183
+ end
184
+
185
+ if free(left.left) && !(!free(left.down) || @deepWater.include?(left.down))
186
+ a &= cursorMove(left.down)
187
+ end
188
+
189
+ if !a
190
+ break
191
+ end
192
+ end
193
+ end
194
+
195
+ return false
196
+ end
197
+
198
+ cursorMove(cursor)
199
+
200
+ printMap("day17.out", @map, @waterTiles, @deepWater) if false
201
+
202
+ puts "Part 1: #{@waterTiles.size}"
203
+ puts "Part 2: #{@deepWater.size}"