[2022][ruby][18.x]
change ttyuksqxplwvyvovtvvlrkunnxyrxtro
commit b3d83e031a244cdd9cdf5a1a8d95507c71e71571
author Alpha Chen <alpha@kejadlen.dev>
date
parent yvpvxvzp
diff --git a/2022/ruby/day_18.rb b/2022/ruby/day_18.rb
new file mode 100644
index 0000000..05c7eb6
--- /dev/null
+++ b/2022/ruby/day_18.rb
@@ -0,0 +1,50 @@
+cubes = ARGF.read.lines(chomp: true).map { _1.split(?,).map(&:to_i) }
+
+# part one
+# p cubes.sum {|cube|
+#   6 - cubes.count {|other|
+#     cube.zip(other).map { _1 - _2 }.map(&:abs).sum == 1
+#   }
+# }
+
+deltas = [
+  [-1,  0,  0],
+  [ 1,  0,  0],
+  [ 0, -1,  0],
+  [ 0,  1,  0],
+  [ 0,  0, -1],
+  [ 0,  0,  1],
+]
+
+bounds = cubes.transpose.map(&:minmax).map {|(min, max)| (min-1..max+1) }
+cubes = cubes.to_h { [_1, true] }
+corners = [
+  [bounds[0].begin, bounds[1].begin, bounds[2].begin],
+  [bounds[0].begin, bounds[1].begin, bounds[2].end],
+  [bounds[0].begin, bounds[1].end, bounds[2].begin],
+  [bounds[0].begin, bounds[1].end, bounds[2].end],
+  [bounds[0].end, bounds[1].begin, bounds[2].begin],
+  [bounds[0].end, bounds[1].begin, bounds[2].end],
+  [bounds[0].end, bounds[1].end, bounds[2].begin],
+  [bounds[0].end, bounds[1].end, bounds[2].end],
+]
+
+frontier = [corners[0]]
+seen = Hash.new
+
+until frontier.empty?
+  current = frontier.shift
+
+  neighbors = deltas.map {|delta| current.zip(delta).map { _1 + _2 }}
+    .select {|neighbor| bounds.zip(neighbor).all? {|(bound, i)| bound.cover?(i) }}
+
+  seen[current] = neighbors.any? { cubes.has_key?(_1) }
+
+  frontier.concat(neighbors.reject {|neighbor| seen.has_key?(neighbor) || cubes.has_key?(neighbor) })
+  frontier.uniq!
+end
+
+p cubes.keys.sum {|cube|
+  neighbors = deltas.map {|delta| cube.zip(delta).map { _1 + _2 }}
+  neighbors.count { seen.has_key?(_1) }
+}