@@ -80,3 +80,138 @@ def to_s
8080end
8181
8282puts viable_pairs
83+
84+ # --- Part Two ---
85+ #
86+ # Now that you have a better understanding of the grid, it's time to get to work.
87+ #
88+ # Your goal is to gain access to the data which begins in the node with y=0 and the highest x
89+ # (that is, the node in the top-right corner).
90+ #
91+ # For example, suppose you have the following grid:
92+ #
93+ # Filesystem Size Used Avail Use%
94+ # /dev/grid/node-x0-y0 10T 8T 2T 80%
95+ # /dev/grid/node-x0-y1 11T 6T 5T 54%
96+ # /dev/grid/node-x0-y2 32T 28T 4T 87%
97+ # /dev/grid/node-x1-y0 9T 7T 2T 77%
98+ # /dev/grid/node-x1-y1 8T 0T 8T 0%
99+ # /dev/grid/node-x1-y2 11T 7T 4T 63%
100+ # /dev/grid/node-x2-y0 10T 6T 4T 60%
101+ # /dev/grid/node-x2-y1 9T 8T 1T 88%
102+ # /dev/grid/node-x2-y2 9T 6T 3T 66%
103+ #
104+ # In this example, you have a storage grid 3 nodes wide and 3 nodes tall. The node you can access
105+ # directly, node-x0-y0, is almost full. The node containing the data you want to access,
106+ # node-x2-y0 (because it has y=0 and the highest x value), contains 6 terabytes of data - enough
107+ # to fit on your node, if only you could make enough space to move it there.
108+ #
109+ # Fortunately, node-x1-y1 looks like it has enough free space to enable you to move some of this
110+ # data around. In fact, it seems like all of the nodes have enough space to hold any node's data
111+ # (except node-x0-y2, which is much larger, very full, and not moving any time soon). So,
112+ # initially, the grid's capacities and connections look like this:
113+ #
114+ # ( 8T/10T) -- 7T/ 9T -- [ 6T/10T]
115+ # | | |
116+ # 6T/11T -- 0T/ 8T -- 8T/ 9T
117+ # | | |
118+ # 28T/32T -- 7T/11T -- 6T/ 9T
119+ #
120+ # The node you can access directly is in parentheses; the data you want starts in the node marked
121+ # by square brackets.
122+ #
123+ # In this example, most of the nodes are interchangable: they're full enough that no other node's
124+ # data would fit, but small enough that their data could be moved around. Let's draw these nodes
125+ # as .. The exceptions are the empty node, which we'll draw as _, and the very large, very full
126+ # node, which we'll draw as #. Let's also draw the goal data as G. Then, it looks like this:
127+ #
128+ # (.) . G
129+ # . _ .
130+ # # . .
131+ #
132+ # The goal is to move the data in the top right, G, to the node in parentheses. To do this, we can
133+ # issue some commands to the grid and rearrange the data:
134+ #
135+ # - Move data from node-y0-x1 to node-y1-x1, leaving node node-y0-x1 empty:
136+ #
137+ # (.) _ G
138+ # . . .
139+ # # . .
140+ #
141+ # - Move the goal data from node-y0-x2 to node-y0-x1:
142+ #
143+ # (.) G _
144+ # . . .
145+ # # . .
146+ #
147+ # - At this point, we're quite close. However, we have no deletion command, so we have to move
148+ # some more data around. So, next, we move the data from node-y1-x2 to node-y0-x2:
149+ #
150+ # (.) G .
151+ # . . _
152+ # # . .
153+ #
154+ # - Move the data from node-y1-x1 to node-y1-x2:
155+ #
156+ # (.) G .
157+ # . _ .
158+ # # . .
159+ #
160+ # - Move the data from node-y1-x0 to node-y1-x1:
161+ #
162+ # (.) G .
163+ # _ . .
164+ # # . .
165+ #
166+ # - Next, we can free up space on our node by moving the data from node-y0-x0 to node-y1-x0:
167+ #
168+ # (_) G .
169+ # . . .
170+ # # . .
171+ #
172+ # - Finally, we can access the goal data by moving the it from node-y0-x1 to node-y0-x0:
173+ #
174+ # (G) _ .
175+ # . . .
176+ # # . .
177+ #
178+ # So, after 7 steps, we've accessed the data we want. Unfortunately, each of these moves takes
179+ # time, and we need to be efficient:
180+ #
181+ # What is the fewest number of steps required to move your goal data to node-x0-y0?
182+
183+ min_x , max_x = nodes . map ( &:x ) . minmax
184+ min_y , max_y = nodes . map ( &:y ) . minmax
185+
186+ grid = Array . new ( max_y - min_y + 1 ) { Array . new ( max_x - min_x + 1 ) }
187+
188+ nodes . each do |node |
189+ grid [ node . y ] [ node . x ] = node
190+ end
191+
192+ grid . each do |row |
193+ if row [ 0 ] . y . zero?
194+ print " "
195+ row . each do |node |
196+ print " %2d " %[node.x]
197+ end
198+ puts
199+ end
200+ print "%2d:" %[row[0].y]
201+ row . each do |node |
202+ l , r = ' ' , ' '
203+ if node . y == min_y
204+ if node . x == max_x
205+ l , r = '[' , ']'
206+ elsif node . x == min_x
207+ l , r = '(' , ')'
208+ end
209+ end
210+ if node . used . zero?
211+ print "%c _ /%-2d%c" %[l,node.avail,r]
212+ else
213+ print "%c%3d/%-2d%c" %[l,node.used, node.avail,r]
214+ end
215+ end
216+ puts
217+ end
0 commit comments