|
|
|
@ -11,38 +11,28 @@ count_energized = ->(start, dir) {
|
|
|
|
|
coord, delta = current.shift
|
|
|
|
|
seen << [coord, delta]
|
|
|
|
|
|
|
|
|
|
case [elem = input[coord], delta]
|
|
|
|
|
in [nil, _]
|
|
|
|
|
# the beam has escaped the contraption
|
|
|
|
|
in [?., _] | [?|, [_,0]] | [?-, [0,_]] # keep going
|
|
|
|
|
current << [coord.zip(delta).map { _1 + _2 }, delta]
|
|
|
|
|
in [?|, [0,_]] # split up and down
|
|
|
|
|
current << [coord.zip([-1,0]).map { _1 + _2 }, [-1,0]]
|
|
|
|
|
current << [coord.zip([1,0]).map { _1 + _2 }, [1,0]]
|
|
|
|
|
in [?-, [_,0]] # split left and right
|
|
|
|
|
current << [coord.zip([0,-1]).map { _1 + _2 }, [0,-1]]
|
|
|
|
|
current << [coord.zip([0,1]).map { _1 + _2 }, [0,1]]
|
|
|
|
|
in [?/, [0,1]] # going right, goes up
|
|
|
|
|
current << [coord.zip([-1,0]).map { _1 + _2 }, [-1,0]]
|
|
|
|
|
in [?/, [0,-1]] # going left, goes down
|
|
|
|
|
current << [coord.zip([1,0]).map { _1 + _2 }, [1,0]]
|
|
|
|
|
in [?/, [1,0]] # going down, goes left
|
|
|
|
|
current << [coord.zip([0,-1]).map { _1 + _2 }, [0,-1]]
|
|
|
|
|
in [?/, [-1,0]] # going up, goes right
|
|
|
|
|
current << [coord.zip([0,1]).map { _1 + _2 }, [0,1]]
|
|
|
|
|
in [?\\, [0,1]] # going right, goes down
|
|
|
|
|
current << [coord.zip([1,0]).map { _1 + _2 }, [1,0]]
|
|
|
|
|
in [?\\, [0,-1]] # going left, goes up
|
|
|
|
|
current << [coord.zip([-1,0]).map { _1 + _2 }, [-1,0]]
|
|
|
|
|
in [?\\, [1,0]] # going down, goes right
|
|
|
|
|
current << [coord.zip([0,1]).map { _1 + _2 }, [0,1]]
|
|
|
|
|
in [?\\, [-1,0]] # going up, goes left
|
|
|
|
|
current << [coord.zip([0,-1]).map { _1 + _2 }, [0,-1]]
|
|
|
|
|
else
|
|
|
|
|
fail "unexpected element: #{elem.inspect}"
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
current = current.reject { seen.include?(_1) }
|
|
|
|
|
next_delta = case [input[coord], delta]
|
|
|
|
|
in [nil, _]
|
|
|
|
|
[] # the beam has escaped the contraption
|
|
|
|
|
in [?., _] | [?|, [_,0]] | [?-, [0,_]] # keep going
|
|
|
|
|
[delta]
|
|
|
|
|
in [?|, [0,_]] # split up and down
|
|
|
|
|
[[-1,0], [1,0]]
|
|
|
|
|
in [?-, [_,0]] # split left and right
|
|
|
|
|
[[0,-1], [0,1]]
|
|
|
|
|
in [?/, _]
|
|
|
|
|
[delta.map { -_1 }.reverse]
|
|
|
|
|
in [?\\, _]
|
|
|
|
|
[delta.reverse]
|
|
|
|
|
else
|
|
|
|
|
fail
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
current.concat(
|
|
|
|
|
next_delta
|
|
|
|
|
.map {|d| [coord.zip(d).map { _1 + _2 }, d] }
|
|
|
|
|
.reject { seen.include?(_1) }
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
seen.map(&:first).select { input.has_key?(_1) }.uniq.size
|
|
|
|
|