1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
beam = nil
SPLITTERS = Hash.new {|h,k| h[k] = Set.new }

DATA.read.lines(chomp: true).each.with_index do |line, y|
  line.chars.each.with_index do |value, x|
    case value
    when ?S
      beam = x
    when ?^
      SPLITTERS[y] << x
    when ?.
      # no-op
    else
      fail value
    end
  end
end

# beams = Set[beam]
# pp (0..splitters.keys.max).inject(0) {|splits, y|
#   split_beams = beams & splitters[y]
#   beams -= split_beams
#   beams |= split_beams.flat_map { [it - 1, it + 1] }
#   splits + split_beams.size
# }

timelines = Hash.new {|timelines, (beam, level)|
  timelines[[beam, level]] = if level > SPLITTERS.keys.max
                               1
                             else
                               if SPLITTERS[level].include?(beam)
                                 [-1, 1].sum {|d|
                                   timelines[[beam + d, level + 1]]
                                 }
                               else
                                 timelines[[beam, level + 1]]
                               end
                             end
}

pp timelines[[beam, 0]]

__END__