@@ -34,8 +34,10 @@ const STACK_FRAME_COLOR = {
34
34
const VIS_VARIABLE_STRINGS = {
35
35
i_left_index : 'i' ,
36
36
j_right_index : 'j' ,
37
+ i_eq_0 : 'i==0' ,
37
38
i_gt_n : 'i==n+1' ,
38
39
j_eq_0 : 'j==0' ,
40
+ j_gt_n : 'j==n+1' ,
39
41
left : 'left' ,
40
42
right : 'right' ,
41
43
right_eq_0 : 'right==0'
@@ -159,7 +161,6 @@ export default {
159
161
// where mid is undefined until after partition
160
162
const finished_stack_frames = [ ] ;
161
163
const real_stack = [ ] ;
162
- let leftCheck = false
163
164
164
165
// ----------------------------------------------------------------------------------------------------------------------------
165
166
// Define helper functions
@@ -169,83 +170,81 @@ export default {
169
170
// This function is the only way information is cached and incremented properly in the while loop
170
171
const partitionChunker = ( bookmark , i , j , prev_i , prev_j , left , right , depth , arr , mask ) => {
171
172
assert ( bookmark !== undefined ) ; // helps catch bugs early, and trace them in stack
172
- const args_array = [ real_stack , finished_stack_frames , i , j , prev_i , prev_j , left , right , depth , leftCheck , maxIndex , arr , mask ]
173
+ const args_array = [ real_stack , finished_stack_frames , i , j , prev_i , prev_j , left , right , depth , bookmark , maxIndex , arr , mask ]
173
174
chunker . add ( bookmark , refreshStack , args_array , depth )
174
175
}
175
176
176
- // we use a global flag in case we scan through the whole partition
177
- // and stop at the end without finding the mask bit we are looking
178
- // for
179
- const refreshStack = ( vis , cur_real_stack , cur_finished_stack_frames , cur_i , cur_j , prev_i , prev_j , left , right , cur_depth , checkingLeft , maxIndex , arr , mask ) => {
177
+ const refreshStack = ( vis , cur_real_stack , cur_finished_stack_frames , cur_i , cur_j , prev_i , prev_j , left , right , cur_depth , whereAreWe , maxIndex , arr , mask ) => {
180
178
// If we fall off the start/end of the array we just use the
181
179
// first/last element and give the actual value of j/i
180
+ let cur_i_too_low ;
182
181
let cur_i_too_high ;
183
182
let cur_j_too_low ;
183
+ let cur_j_too_high ;
184
184
let tmp_j = cur_j ; // used to determine context later
185
185
if ( cur_i === A . length ) {
186
186
cur_i = undefined ;
187
187
cur_i_too_high = A . length - 1 ;
188
- } else {
189
- cur_i_too_high = undefined ;
188
+ } else if ( cur_i === - 1 ) {
189
+ cur_i = undefined ;
190
+ cur_i_too_low = 0 ;
190
191
}
191
- if ( cur_j === - 1 ) {
192
+ if ( cur_j === A . length ) {
193
+ cur_j = undefined ;
194
+ cur_j_too_high = A . length - 1 ;
195
+ } else if ( cur_j === - 1 ) {
192
196
cur_j = undefined ;
193
197
cur_j_too_low = 0 ;
194
- } else {
195
- cur_j_too_low = undefined ;
196
198
}
197
199
198
200
assert ( vis . array ) ;
199
201
assert ( cur_real_stack && cur_finished_stack_frames ) ;
200
202
201
- vis . array . setStackDepth ( cur_real_stack . length ) ;
202
- vis . array . setStack (
203
- deriveStack ( cur_real_stack , cur_finished_stack_frames , cur_i , cur_j , cur_depth )
204
- ) ;
203
+ // This was getting very messy - colors depends a
204
+ // lot on where we are and we had a bunch of tricky testing of
205
+ // various vars to determine that. Now we use whereAreWe
206
+ // (current bookmark) simplify some things at least.
207
+ // XXX prev_i and prev_j are no longer used so could be deleted
208
+ // as parameters and elsewhere
205
209
206
- // XXX This is getting very messy - (un)highlighting depends a
207
- // lot on where we are and we have a bunch of tricky testing of
208
- // various vars to determine that. Could pass in bookmark to
209
- // simplify some things at least??
210
210
// Show the binary representation for the current index
211
- // plus (un)highlight appropriate element(s)
212
- updateMask ( vis , mask ) // only needed for start of recursive function
213
- if ( maxIndex !== undefined ) { // top level call to recursive fn
211
+ // plus color appropriate element(s)
212
+ updateMask ( vis , mask ) // needed at call/return of recursive function
213
+ if ( whereAreWe === MSD_BOOKMARKS . rec_function ) {
214
+ // top level call to recursive fn
214
215
unhighlight ( vis , maxIndex )
215
216
updateBinary ( vis , 0 )
216
217
}
217
- if ( cur_i !== undefined && tmp_j === undefined && prev_i !== undefined ) {
218
+ if ( whereAreWe === MSD_BOOKMARKS . pre_sort_left ) {
218
219
// just before first recursive call
219
- if ( i <= right )
220
- vis . array . selectColor ( prev_i , partRColor )
221
- if ( prev_j >= left ) // might have fallen off array
222
- vis . array . selectColor ( prev_j , partLColor )
223
220
for ( let k = cur_i ; k <= right ; k ++ )
224
221
vis . array . deselect ( k ) ;
225
- } else if ( checkingLeft ) {
222
+ } else if ( whereAreWe === MSD_BOOKMARKS . partition_left ) {
226
223
// note i can fall off RHS of array...
227
- if ( prev_i !== undefined && prev_i !== cur_j ) {
228
- let real_i = cur_i ;
229
- if ( cur_i === undefined )
230
- real_i = right + 1 ;
231
- for ( let k = prev_i ; k < real_i && k <= right ; k ++ )
232
- vis . array . selectColor ( k , partLColor )
233
- if ( cur_i !== undefined && cur_i <= right && ( arr [ cur_i ] >> mask & 1 ) === 1 )
224
+ if ( cur_i !== undefined && cur_i <= right ) {
225
+ updateBinary ( vis , arr [ cur_i ] ) ;
226
+ if ( ( arr [ cur_i ] >> mask & 1 ) === 1 )
234
227
vis . array . selectColor ( cur_i , partRColor )
228
+ else {
229
+ vis . array . selectColor ( cur_i , partLColor ) ;
230
+ }
235
231
}
236
- if ( arr && cur_i !== undefined )
237
- updateBinary ( vis , arr [ cur_i ] )
238
- } else {
232
+ } else if ( whereAreWe === MSD_BOOKMARKS . partition_right ) {
239
233
// note j can fall off LHS of array...
240
- if ( prev_j !== undefined && prev_j !== cur_i )
241
- for ( let k = prev_j ; k >= cur_j && k >= cur_i ; k -- )
242
- vis . array . selectColor ( k , partRColor )
243
- if ( prev_j !== undefined && cur_j !== undefined && cur_j > cur_i ) {
244
- vis . array . selectColor ( cur_j , partLColor ) ;
245
- // XXX probably best avoid updateBinary at swap
246
- updateBinary ( vis , arr [ cur_j ] )
234
+ if ( cur_j !== undefined && cur_j >= left ) {
235
+ updateBinary ( vis , arr [ cur_j ] ) ;
236
+ if ( ( arr [ cur_j ] >> mask & 1 ) === 0 )
237
+ vis . array . selectColor ( cur_j , partLColor )
238
+ else {
239
+ vis . array . selectColor ( cur_j , partRColor ) ;
240
+ }
247
241
}
248
242
}
243
+
244
+ vis . array . setStackDepth ( cur_real_stack . length ) ;
245
+ vis . array . setStack (
246
+ deriveStack ( cur_real_stack , cur_finished_stack_frames , cur_i , cur_j , cur_depth )
247
+ ) ;
249
248
if ( left < A . length ) // shouldn't happen with initial mask choice
250
249
assignVariable ( vis , VIS_VARIABLE_STRINGS . left , left ) ;
251
250
if ( right >= 0 ) {
@@ -257,11 +256,13 @@ export default {
257
256
}
258
257
if ( isPartitionExpanded ( ) || isRecursionExpanded ( ) ) {
259
258
assignVariable ( vis , VIS_VARIABLE_STRINGS . i_left_index , cur_i ) ;
259
+ assignVariable ( vis , VIS_VARIABLE_STRINGS . i_eq_0 , cur_i_too_low ) ;
260
260
assignVariable ( vis , VIS_VARIABLE_STRINGS . i_gt_n , cur_i_too_high ) ;
261
261
}
262
262
if ( isPartitionExpanded ( ) ) {
263
263
assignVariable ( vis , VIS_VARIABLE_STRINGS . j_right_index , cur_j ) ;
264
264
assignVariable ( vis , VIS_VARIABLE_STRINGS . j_eq_0 , cur_j_too_low ) ;
265
+ assignVariable ( vis , VIS_VARIABLE_STRINGS . j_gt_n , cur_j_too_high ) ;
265
266
}
266
267
} ;
267
268
@@ -334,8 +335,8 @@ export default {
334
335
let DELAY_POPPER_SWAP = 700 ;
335
336
336
337
const partition = ( arr , left , right , mask , depth ) => {
337
- i = left
338
- j = right
338
+ i = left - 1
339
+ j = right + 1
339
340
340
341
const partitionChunkerWrapper = ( bookmark ) => {
341
342
partitionChunker ( bookmark , i , j , prev_i , prev_j , left , right , depth , arr , mask )
@@ -354,8 +355,6 @@ cur_i, cur_j, cur_depth, A) => {
354
355
355
356
vis . array . swapElements ( _n1 , _n2 ) ;
356
357
refreshStack ( vis , cur_real_stack , cur_finished_stack_frames , cur_i , cur_j , prev_i , prev_j , left , right , cur_depth , false , undefined , A , mask )
357
- vis . array . selectColor ( _n1 , partLColor ) ;
358
- vis . array . selectColor ( _n2 , partRColor ) ;
359
358
// redo poppers: swapping the elements keeps the
360
359
// contents of the poppers correct but the position needs
361
360
// to change. The documentation suggests update()
@@ -376,25 +375,25 @@ arr],
376
375
depth ) ;
377
376
}
378
377
379
- partitionChunkerWrapper ( MSD_BOOKMARKS . set_i )
378
+ partitionChunkerWrapper ( MSD_BOOKMARKS . set_i ) ;
380
379
// partitionChunkerWrapper(MSD_BOOKMARKS.set_j)
381
380
while ( i < j ) {
382
381
prev_i = i ; // save prev value for unhighlighting
383
382
prev_j = j ;
384
383
// Build the left group until it reaches the mask (find the big element)
385
- leftCheck = true
386
- while ( i <= j && ( arr [ i ] >> mask & 1 ) === 0 ) {
387
- // partitionChunkerWrapper(MSD_BOOKMARKS.partition_left)
384
+ i ++ ;
385
+ partitionChunkerWrapper ( MSD_BOOKMARKS . partition_left )
386
+ while ( i < j && ( arr [ i ] >> mask & 1 ) === 0 ) {
388
387
i ++
388
+ partitionChunkerWrapper ( MSD_BOOKMARKS . partition_left )
389
389
}
390
- partitionChunkerWrapper ( MSD_BOOKMARKS . partition_left )
391
390
// Build the right group until it fails the mask (find the small element)
392
- leftCheck = false
391
+ j -- ;
392
+ partitionChunkerWrapper ( MSD_BOOKMARKS . partition_right )
393
393
while ( j > i && ( arr [ j ] >> mask & 1 ) === 1 ) {
394
- // partitionChunkerWrapper(MSD_BOOKMARKS.partition_right)
395
394
j --
395
+ partitionChunkerWrapper ( MSD_BOOKMARKS . partition_right )
396
396
}
397
- partitionChunkerWrapper ( MSD_BOOKMARKS . partition_right )
398
397
399
398
// Swap if the bigger element is not in the right place
400
399
if ( i < j ) {
0 commit comments