diff --git a/2024/ruby/day_06.rb b/2024/ruby/day_06.rb index 3284573..91a5199 100644 --- a/2024/ruby/day_06.rb +++ b/2024/ruby/day_06.rb @@ -15,25 +15,29 @@ TURNS = { Loop = Class.new(Exception) def patrol(lab) + return enum_for(__method__, lab) unless block_given? + start = lab.find { _2 == ?^ }.first - path = [[start, [-1,0]]] - seen = path.to_set + guard = [start, [-1,0]] + seen = Set.new + loop do - pos, dir = path.last - peek = pos.zip(dir).map {|i,di| i + di } + pos, dir = guard + yield pos - return path unless lab.has_key?(peek) + peek = pos.zip(dir).map {|i,di| i + di } + return unless lab.has_key?(peek) raise Loop if seen.include?([peek, dir]) seen << [peek, dir] case lab.fetch(peek) when ?., ?^ - path << [peek, dir] + guard[0] = peek when ?# - path.last[1] = TURNS.fetch(dir) + guard[1] = TURNS.fetch(dir) when nil - return path + return else fail end @@ -41,13 +45,13 @@ def patrol(lab) end def loop?(lab) - patrol(lab) + patrol(lab).each {} false rescue Loop true end -path = patrol(input).map(&:first).to_set +path = patrol(input).to_set pp path.length pp input