Skip to content

Commit ff7441d

Browse files
author
Robb Kidd
committed
day 11, part 2
ABANDON GRID! Do a minimal implementation of the parsing for only galaxies. Expand with math.
1 parent ce010db commit ff7441d

File tree

1 file changed

+80
-50
lines changed

1 file changed

+80
-50
lines changed

2023/ruby/day11.rb

Lines changed: 80 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,28 @@ class Day11 < Day # >
66
# @example
77
# day.part1 #=> 374
88
def part1
9-
universe = CosmicExpansion.new(input)
9+
@universe ||= CosmicExpansion.new(input)
1010

11-
universe
12-
.galaxies
13-
.combination(2)
14-
.map { |here, there| universe.distance_between(here, there) }
11+
@universe
12+
.shortest_distances(expansion_rate: 2)
1513
.reduce(&:+)
1614
end
1715

18-
# @example
19-
# day.part2 #=> 'how are you'
16+
# @example 2x
17+
# universe = CosmicExpansion.new(Day11::EXAMPLE_INPUT)
18+
# universe.shortest_distances(expansion_rate: 2).reduce(&:+) #=> 374
19+
# @example 10x
20+
# universe = CosmicExpansion.new(Day11::EXAMPLE_INPUT)
21+
# universe.shortest_distances(expansion_rate: 10).reduce(&:+) #=> 1030
22+
# @example 100x
23+
# universe = CosmicExpansion.new(Day11::EXAMPLE_INPUT)
24+
# universe.shortest_distances(expansion_rate: 100).reduce(&:+) #=> 8410
2025
def part2
26+
@universe ||= CosmicExpansion.new(input)
27+
28+
@universe
29+
.shortest_distances(expansion_rate: 1_000_000)
30+
.reduce(&:+)
2131
end
2232

2333
EXAMPLE_INPUT = <<~INPUT
@@ -50,27 +60,75 @@ def part2
5060
end
5161

5262
class CosmicExpansion
53-
attr_reader :galaxies
54-
5563
def initialize(input)
5664
@input = input
65+
@empty_rows = nil
66+
@empty_columns = nil
5767
@galaxies = []
58-
@grid =
59-
Grid.new(
60-
expand_cosmically(
61-
scan(input)
62-
)
63-
)
64-
@grid.parse do |coords, value|
65-
galaxies << coords if value == GALAXY
66-
end
68+
@occupied_rows = []
69+
@occupied_columns = []
70+
71+
input
72+
.split("\n")
73+
.map(&:chars)
74+
.each_with_index do |row, r|
75+
row.each_with_index do |char, c|
76+
if char == '#'
77+
@occupied_rows << r
78+
@occupied_columns << c
79+
@galaxies << [r, c]
80+
end
81+
end
82+
end
6783
end
6884

69-
EMPTY_SPACE = '.'
70-
GALAXY = '#'
7185

72-
def distance_between(here, there)
73-
@grid.manhattan_distance(here, there)
86+
def shortest_distances(expansion_rate: 1)
87+
expand_by(expansion_rate)
88+
.combination(2)
89+
.map { |here, there|
90+
# like in manhattan
91+
(here[0] - there[0]).abs + (here[1] - there[1]).abs
92+
}
93+
end
94+
95+
def expand_by(expansion_rate)
96+
galaxies
97+
.map { |coords|
98+
row, column = coords
99+
[
100+
row + ((empty_rows.select{|r| r < row}).length * (expansion_rate-1)), # -1 because the original row/column is
101+
column + ((empty_columns.select{|c| c < column}).length * (expansion_rate-1)) # already included in original coord
102+
]
103+
}
104+
end
105+
106+
def empty_rows
107+
@empty_rows ||= Range.new(*@occupied_rows.minmax).entries - @occupied_rows
108+
end
109+
110+
def empty_columns
111+
@empty_columns ||= Range.new(*@occupied_columns.minmax).entries - @occupied_columns
112+
end
113+
114+
def galaxies
115+
return @galaxies if @galaxies
116+
117+
@galaxies = []
118+
@occupied_rows = []
119+
@occupied_columns = []
120+
121+
@scanned_image
122+
.each_with_index do |row, r|
123+
row.each_with_index do |char, c|
124+
if char == GALAXY
125+
@occupied_rows << r
126+
@occupied_columns << c
127+
@galaxies << [r, c]
128+
end
129+
end
130+
end
131+
@galaxies
74132
end
75133

76134
# @example
@@ -82,32 +140,4 @@ def scan(image)
82140
.split("\n")
83141
.map(&:chars)
84142
end
85-
86-
# @example
87-
# scanned_image = day.scan(Day11::EXAMPLE_INPUT)
88-
# input_expanded = day.expand_cosmically(scanned_image)
89-
# input_expanded #=> day.scan(Day11::EXPANDED_INPUT)
90-
def expand_cosmically(scanned_image)
91-
# dupe empty-space rows
92-
expanded_rows = []
93-
scanned_image
94-
.each do |row|
95-
n = row.all?(EMPTY_SPACE) ? 2 : 1
96-
n.times { expanded_rows << row }
97-
end
98-
99-
# pivot the table, dupe empty-space columns
100-
expanded_columns = []
101-
expanded_rows
102-
.transpose
103-
.each do |column|
104-
n = column.all?(EMPTY_SPACE) ? 2 : 1
105-
n.times { expanded_columns << column }
106-
end
107-
108-
# pivot things back around to original orientation
109-
# gotta get rid of this entirely for part 2, though
110-
3.times { expanded_columns = expanded_columns.transpose }
111-
expanded_columns
112-
end
113143
end

0 commit comments

Comments
 (0)