Skip to content

Commit 8f27677

Browse files
committed
remove extraneous sets
use splitter coordinates and density map to count beam splits
1 parent 9afe4c7 commit 8f27677

File tree

1 file changed

+27
-39
lines changed

1 file changed

+27
-39
lines changed

2025/ruby/day07.rb

Lines changed: 27 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -26,25 +26,20 @@ def part2
2626
class TachyonManifold < Grid
2727
include UglySweater
2828

29-
attr_reader :entrance, :splitter_coords, :splitters_by_row, :beams_by_row
30-
31-
def self.example
32-
new(Day07::EXAMPLE_INPUT).parse
33-
end
29+
attr_reader :entrance, :splitter_coords
3430

3531
def initialize(input=nil)
3632
super
3733
@entrance = nil
3834
@splitter_coords = Set.new
35+
@beam_density = Hash.new { 0 }
3936
end
4037

4138
# @example
4239
# tachmani = new(Day07::EXAMPLE_INPUT)
4340
# tachmani.parse
4441
# tachmani.entrance #=> [0,7]
4542
# tachmani.splitter_coords #=> Set[[2, 7], [4, 6], [4, 8], [6, 5], [6, 7], [6, 9], [8, 4], [8, 6], [8, 10], [10, 3], [10, 5], [10, 9], [10, 11], [12, 2], [12, 6], [12, 12], [14, 1], [14, 3], [14, 5], [14, 7], [14, 9], [14, 13]]
46-
# tachmani.splitters_by_row[4] #=> Set[6,8]
47-
# tachmani.beams_by_row[0] #=> Set[7]
4843
def parse
4944
super { |coord, char|
5045
case char
@@ -53,47 +48,41 @@ def parse
5348
else ; # keep calm and parse on
5449
end
5550
}
56-
57-
@beams_by_row = Array.new(@row_bounds.count) { Set.new }
58-
@beams_by_row[@entrance[0]] << @entrance[1]
59-
60-
@beam_density = Hash.new { 0 }
61-
@beam_density[@entrance] += 1
62-
63-
@splitters_by_row = Array.new(@row_bounds.count) { Set.new }
64-
@splitter_coords.each { |(r,c)|
65-
@splitters_by_row[r] << c
66-
}
67-
68-
@beam_splits = 0
69-
70-
self
7151
end
7252

7353
def track_beam
74-
@row_bounds.to_a[1..].each { |r|
75-
@beams_by_row[r-1].each { |c|
76-
if @splitters_by_row[r].include?(c)
77-
@beams_by_row[r] << c-1
78-
@beams_by_row[r] << c+1
79-
@beam_splits += 1
80-
@beam_density[[r,c-1]] += @beam_density[[r-1,c]]
81-
@beam_density[[r,c+1]] += @beam_density[[r-1,c]]
82-
else
83-
@beams_by_row[r] << c
84-
@beam_density[[r,c]] += @beam_density[[r-1,c]]
85-
end
86-
}
87-
}
54+
@beam_density[@entrance] += 1
55+
56+
@row_bounds
57+
.each do |row|
58+
next if row == @row_bounds.min # skip first row, that's where the beam enters
59+
60+
@beam_density
61+
.select {|(beam_row, _), _| beam_row == row-1 } # beams from above
62+
.each do |(_, beam_col), density|
63+
if @splitter_coords.include?([row, beam_col])
64+
@beam_density[[row,beam_col-1]] += density
65+
@beam_density[[row,beam_col+1]] += density
66+
else
67+
@beam_density[[row,beam_col]] += density
68+
end
69+
end
70+
end
8871
end
8972

9073
def beam_splits
91-
@beam_splits
74+
@splitter_coords
75+
.select { |(r,c)|
76+
@beam_density[[r-1,c]] > 0 # look above every splitter for beaminess
77+
}
78+
.count
9279
end
9380

9481
def timeline_splits
9582
@beam_density
96-
.filter_map {|(r,c), density| density if r == @row_bounds.max }
83+
.filter_map {|(r,c), density|
84+
density if r == @row_bounds.max # beam densities on manifold exit
85+
}
9786
.reduce(&:+)
9887
end
9988

@@ -107,5 +96,4 @@ def to_s
10796
end
10897
}
10998
end
110-
11199
end

0 commit comments

Comments
 (0)