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], } start = input.find { _2 == ?^ }.first dir = [-1,0] path = [start] loop do peek = path.last.zip(dir).map {|i,di| i + di } case input.fetch(peek, nil) when ?. path << peek when ?^ path << peek when ?# dir = turns.fetch(dir) when nil break else fail end end pp path.to_set.length __END__ ....#..... .........# .......... ..#....... .......#.. .......... .#..^..... ........#. #......... ......#...