[2024][ruby][18.2]
change nvtxnozslzrwkxwvoqvxpqpoyppsopun
commit 2713298f63c52635f7995f04a114700348841bee
author Alpha Chen <alpha@kejadlen.dev>
date
parent mzquxzso
diff --git a/2024/ruby/day_18.rb b/2024/ruby/day_18.rb
index e45ef14..20c69f7 100644
--- a/2024/ruby/day_18.rb
+++ b/2024/ruby/day_18.rb
@@ -1,39 +1,47 @@
 falling_bytes = DATA.read.scan(/\d+/).map(&:to_i).each_slice(2).to_a
 
-corrupted = falling_bytes[0,1024]
-
-max = 70
-
-deltas = [[-1,0], [1,0], [0,-1], [0,1]]
-
-start = [0,0]
-stop = [max,max]
-
-scores = Hash.new(Float::INFINITY)
-scores[start] = 0
-frontier = [start]
-visited = Set.new
-until scores.has_key?(stop)
-  current = frontier.shift
-  visited << current
-
-  neighbors = deltas.map {|delta|
-    current.zip(delta).map { _1 + _2 }
-  }.select {|xy|
-    xy.all? { (0..max).cover?(_1) }
-  }.reject {|xy|
-    corrupted.include?(xy) || visited.include?(xy)
-  }
-  neighbors.each do |xy|
-    scores[xy] = [scores[xy], scores.fetch(current) + 1].min
+MAX = 70
+DELTAS = [[-1,0], [1,0], [0,-1], [0,1]]
+
+def path(corrupted)
+  start = [0,0]
+  stop = [MAX,MAX]
+
+  scores = Hash.new(Float::INFINITY)
+  scores[start] = 0
+  frontier = [start]
+  visited = Set.new
+  until scores.has_key?(stop)
+    current = frontier.shift
+    visited << current
+
+    neighbors = DELTAS.map {|delta|
+      current.zip(delta).map { _1 + _2 }
+    }.select {|xy|
+      xy.all? { (0..MAX).cover?(_1) }
+    }.reject {|xy|
+      corrupted.include?(xy) || visited.include?(xy)
+    }
+    neighbors.each do |xy|
+      scores[xy] = [scores[xy], scores.fetch(current) + 1].min
+    end
+
+    frontier.concat(neighbors)
+
+    frontier.uniq!
+    frontier.sort_by! { scores.fetch(_1) }
   end
 
-  frontier.concat(neighbors)
-
-  frontier.uniq!
-  frontier.sort_by! { scores.fetch(_1) }
+  scores.fetch(stop)
 end
 
-pp scores.fetch(stop)
+i = (0...falling_bytes.length).bsearch {|i|
+  begin
+    path(falling_bytes[0,i]) && false
+  rescue
+    true
+  end
+}
+puts falling_bytes.fetch(i-1).join(?,)
 
 __END__