You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
advent-of-code/2024/ruby/day_06.rb

78 lines
1.2 KiB

input = DATA.readlines(chomp: true)
.flat_map.with_index {|line, j|
line.chars.map.with_index {|x, i|
[[j,i], x]
}
}.to_h
TURNS = {
[-1,0] => [0,1],
[0,1] => [1,0],
[1,0] => [0,-1],
[0,-1] => [-1,0],
}
Loop = Class.new(Exception)
def patrol(lab)
return enum_for(__method__, lab) unless block_given?
start = lab.find { _2 == ?^ }.first
guard = [start, [-1,0]]
seen = Set.new
loop do
pos, dir = guard
yield pos
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 ?., ?^
guard[0] = peek
when ?#
guard[1] = TURNS.fetch(dir)
when nil
return
else
fail
end
end
end
def loop?(lab)
patrol(lab).each {}
false
rescue Loop
true
end
path = patrol(input).to_set
pp path.length
pp input
.select { path.include?(_1) && _2 != ?^ }
.select {|xy, _|
# pp xy
input[xy] = ?#
res = loop?(input)
input[xy] = ?.
res
}.size
__END__
....#.....
.........#
..........
..#.......
.......#..
..........
.#..^.....
........#.
#.........
......#...