diff --git a/2022/ruby/day_12.rb b/2022/ruby/day_12.rb
new file mode 100644
index 0000000..201c798
--- /dev/null
+++ b/2022/ruby/day_12.rb
@@ -0,0 +1,69 @@
+height_map = ARGF.read.lines(chomp: true).map(&:chars)
+ .each.with_index.with_object({}) do |(row,y),map|
+ row.each.with_index do |height,x|
+ map[[y,x]] = height
+ end
+ end
+
+s, e = height_map.invert.values_at(?S, ?E)
+height_map[s] = ?a
+height_map[e] = ?z
+
+# part one
+# queue = [s]
+# visited = { s => 0 }
+
+# until visited.has_key?(e)
+# current = queue.shift
+# moves = visited.fetch(current)
+
+# neighbors = [
+# [-1, 0],
+# [ 1, 0],
+# [ 0, -1],
+# [ 0, 1],
+# ].map { current.zip(_1).map {|a,b| a + b } }
+# .select { height_map.has_key?(_1) }
+# .reject { visited.has_key?(_1) }
+# .select { height_map.fetch(_1).ord - 1 <= height_map.fetch(current).ord }
+
+# neighbors.each do |y,x|
+# visited[[y,x]] = moves + 1
+# queue << [y,x]
+# end
+
+# queue.sort_by { visited.fetch(_1) }
+# end
+
+# p visited.fetch(e)
+
+# part two
+queue = [e]
+visited = { e => 0 }
+
+loop do
+ current = queue.shift
+ moves = visited.fetch(current)
+
+ neighbors = [
+ [-1, 0],
+ [ 1, 0],
+ [ 0, -1],
+ [ 0, 1],
+ ].map { current.zip(_1).map {|a,b| a + b } }
+ .select { height_map.has_key?(_1) }
+ .reject { visited.has_key?(_1) }
+ .select { height_map.fetch(current).ord <= height_map.fetch(_1).ord + 1 }
+
+ if a = neighbors.find { height_map.fetch(_1) == ?a }
+ p moves + 1
+ break
+ end
+
+ neighbors.each do |y,x|
+ visited[[y,x]] = moves + 1
+ queue << [y,x]
+ end
+
+ queue.sort_by { visited.fetch(_1) }
+end