@@ -6,18 +6,28 @@ class Day11 < Day # >
6
6
# @example
7
7
# day.part1 #=> 374
8
8
def part1
9
- universe = CosmicExpansion . new ( input )
9
+ @ universe || = CosmicExpansion . new ( input )
10
10
11
- universe
12
- . galaxies
13
- . combination ( 2 )
14
- . map { |here , there | universe . distance_between ( here , there ) }
11
+ @universe
12
+ . shortest_distances ( expansion_rate : 2 )
15
13
. reduce ( &:+ )
16
14
end
17
15
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
20
25
def part2
26
+ @universe ||= CosmicExpansion . new ( input )
27
+
28
+ @universe
29
+ . shortest_distances ( expansion_rate : 1_000_000 )
30
+ . reduce ( &:+ )
21
31
end
22
32
23
33
EXAMPLE_INPUT = <<~INPUT
@@ -50,27 +60,75 @@ def part2
50
60
end
51
61
52
62
class CosmicExpansion
53
- attr_reader :galaxies
54
-
55
63
def initialize ( input )
56
64
@input = input
65
+ @empty_rows = nil
66
+ @empty_columns = nil
57
67
@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
67
83
end
68
84
69
- EMPTY_SPACE = '.'
70
- GALAXY = '#'
71
85
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
74
132
end
75
133
76
134
# @example
@@ -82,32 +140,4 @@ def scan(image)
82
140
. split ( "\n " )
83
141
. map ( &:chars )
84
142
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
113
143
end
0 commit comments