[2022][ruby][9.1]
change swqvkquyznstywtqpmtrpxplptkurzpv
commit ce740bf01852a2f2b2334e19bcd9120b91ff65b9
author Alpha Chen <alpha@kejadlen.dev>
date
parent lyorolkk
diff --git a/2022/ruby/day_09.rb b/2022/ruby/day_09.rb
new file mode 100644
index 0000000..15239d0
--- /dev/null
+++ b/2022/ruby/day_09.rb
@@ -0,0 +1,43 @@
+require "set"
+
+motions = ARGF.read.scan(/([RLUD])\s+(\d+)/).map { [_1, _2.to_i] }
+
+class Snake
+  attr_reader :tail
+
+  def initialize
+    @head, @tail = [0, 0], [0, 0]
+  end
+
+  def move!(dir)
+    delta = case dir
+            when ?L then [ 0, -1]
+            when ?U then [ 1,  0]
+            when ?R then [ 0,  1]
+            when ?D then [-1,  0]
+            else fail dir.inspect
+            end
+    @head = @head.zip(delta).map { _1 + _2 }
+
+    delta = @head.zip(@tail).map { _1 - _2 }
+    if delta.any? { _1.abs > 1 }
+      if delta.any?(&:zero?)
+        @tail = @tail.zip(delta.map { _1.clamp(-1, 1) }).map { _1 + _2 }
+      else
+        @tail = @tail.zip(delta.map { _1.clamp(-1, 1) }).map { _1 + _2 }
+      end
+    end
+  end
+end
+
+snake = Snake.new
+seen = Set.new
+
+motions.each do |dir, distance|
+  distance.times do
+    snake.move!(dir)
+    seen << snake.tail
+  end
+end
+
+p seen.size