@@ -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'
@@ -54,7 +56,6 @@ const MSD_BOOKMARKS = {
54
56
partition_right : 305 ,
55
57
swap_condition : 309 ,
56
58
swap : 310 ,
57
- inc_dec : 'inc_dec' ,
58
59
pre_sort_left : 400 ,
59
60
sort_left : 401 ,
60
61
pre_sort_right : 500 ,
@@ -160,13 +161,6 @@ export default {
160
161
// where mid is undefined until after partition
161
162
const finished_stack_frames = [ ] ;
162
163
const real_stack = [ ] ;
163
- // refreshStack does lots of work with highlighting etc but is
164
- // called from other functions which are called from other
165
- // function and somewhere along the line one of the functions is
166
- // chunker.add. Often the arguments are not given explicitly -
167
- // it's a mess. We assign the current bookmark to whereAreWe for
168
- // now, to be used in refreshStack. Maybe worth a re-write XXX.
169
- let whereAreWe ;
170
164
171
165
// ----------------------------------------------------------------------------------------------------------------------------
172
166
// Define helper functions
@@ -176,51 +170,53 @@ export default {
176
170
// This function is the only way information is cached and incremented properly in the while loop
177
171
const partitionChunker = ( bookmark , i , j , prev_i , prev_j , left , right , depth , arr , mask ) => {
178
172
assert ( bookmark !== undefined ) ; // helps catch bugs early, and trace them in stack
179
- const args_array = [ real_stack , finished_stack_frames , i , j , prev_i , prev_j , left , right , depth , whereAreWe , 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 ]
180
174
chunker . add ( bookmark , refreshStack , args_array , depth )
181
175
}
182
176
183
- // see comment above on whereAreWe
184
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 ) => {
185
178
// If we fall off the start/end of the array we just use the
186
179
// first/last element and give the actual value of j/i
180
+ let cur_i_too_low ;
187
181
let cur_i_too_high ;
188
182
let cur_j_too_low ;
183
+ let cur_j_too_high ;
189
184
let tmp_j = cur_j ; // used to determine context later
190
185
if ( cur_i === A . length ) {
191
186
cur_i = undefined ;
192
187
cur_i_too_high = A . length - 1 ;
193
- } else {
194
- cur_i_too_high = undefined ;
188
+ } else if ( cur_i === - 1 ) {
189
+ cur_i = undefined ;
190
+ cur_i_too_low = 0 ;
195
191
}
196
- 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 ) {
197
196
cur_j = undefined ;
198
197
cur_j_too_low = 0 ;
199
- } else {
200
- cur_j_too_low = undefined ;
201
198
}
202
199
203
200
assert ( vis . array ) ;
204
201
assert ( cur_real_stack && cur_finished_stack_frames ) ;
205
202
206
- // XXX This was getting very messy - colors depends a
203
+ // This was getting very messy - colors depends a
207
204
// lot on where we are and we had a bunch of tricky testing of
208
- // various vars to determine that. Now we use whereAreWe to
209
- // simplify some things at least.
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
210
209
211
210
// Show the binary representation for the current index
212
211
// plus color appropriate element(s)
213
- updateMask ( vis , mask ) // only needed for start of recursive function
214
- if ( maxIndex !== undefined ) { // top level call to recursive fn
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
215
215
unhighlight ( vis , maxIndex )
216
216
updateBinary ( vis , 0 )
217
217
}
218
- if ( cur_i !== undefined && tmp_j === undefined && prev_i !== undefined ) {
218
+ if ( whereAreWe === MSD_BOOKMARKS . pre_sort_left ) {
219
219
// just before first recursive call
220
- if ( i <= right )
221
- vis . array . selectColor ( prev_i , partRColor )
222
- if ( prev_j >= left ) // might have fallen off array
223
- vis . array . selectColor ( prev_j , partLColor )
224
220
for ( let k = cur_i ; k <= right ; k ++ )
225
221
vis . array . deselect ( k ) ;
226
222
} else if ( whereAreWe === MSD_BOOKMARKS . partition_left ) {
@@ -231,31 +227,17 @@ export default {
231
227
vis . array . selectColor ( cur_i , partRColor )
232
228
else {
233
229
vis . array . selectColor ( cur_i , partLColor ) ;
234
- cur_i ++ ; // show incremented i XXX fix i_too_high
235
230
}
236
231
}
237
- /*
238
- if (prev_i !== undefined && prev_i !== cur_j) {
239
- let real_i = cur_i;
240
- if (cur_i === undefined)
241
- real_i = right + 1;
242
- for (let k = prev_i; k < real_i && k <= right; k++)
243
- vis.array.selectColor(k, partLColor)
244
- if (cur_i !== undefined && cur_i <= right && (arr[cur_i] >> mask & 1) === 1)
245
- vis.array.selectColor(cur_i, partRColor)
246
- }
247
- if (arr && cur_i !== undefined)
248
- updateBinary(vis, arr[cur_i])
249
- */
250
232
} else if ( whereAreWe === MSD_BOOKMARKS . partition_right ) {
251
233
// note j can fall off LHS of array...
252
- if ( prev_j !== undefined && prev_j !== cur_i )
253
- for ( let k = prev_j ; k >= cur_j && k >= cur_i ; k -- )
254
- vis . array . selectColor ( k , partRColor )
255
- if ( prev_j !== undefined && cur_j !== undefined && cur_j > cur_i ) {
256
- vis . array . selectColor ( cur_j , partLColor ) ;
257
- // XXX probably best avoid updateBinary at swap
258
- 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
+ }
259
241
}
260
242
}
261
243
@@ -274,11 +256,13 @@ export default {
274
256
}
275
257
if ( isPartitionExpanded ( ) || isRecursionExpanded ( ) ) {
276
258
assignVariable ( vis , VIS_VARIABLE_STRINGS . i_left_index , cur_i ) ;
259
+ assignVariable ( vis , VIS_VARIABLE_STRINGS . i_eq_0 , cur_i_too_low ) ;
277
260
assignVariable ( vis , VIS_VARIABLE_STRINGS . i_gt_n , cur_i_too_high ) ;
278
261
}
279
262
if ( isPartitionExpanded ( ) ) {
280
263
assignVariable ( vis , VIS_VARIABLE_STRINGS . j_right_index , cur_j ) ;
281
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 ) ;
282
266
}
283
267
} ;
284
268
@@ -351,8 +335,8 @@ export default {
351
335
let DELAY_POPPER_SWAP = 700 ;
352
336
353
337
const partition = ( arr , left , right , mask , depth ) => {
354
- i = left
355
- j = right
338
+ i = left - 1
339
+ j = right + 1
356
340
357
341
const partitionChunkerWrapper = ( bookmark ) => {
358
342
partitionChunker ( bookmark , i , j , prev_i , prev_j , left , right , depth , arr , mask )
@@ -371,8 +355,6 @@ cur_i, cur_j, cur_depth, A) => {
371
355
372
356
vis . array . swapElements ( _n1 , _n2 ) ;
373
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 )
374
- vis . array . selectColor ( _n1 , partLColor ) ;
375
- vis . array . selectColor ( _n2 , partRColor ) ;
376
358
// redo poppers: swapping the elements keeps the
377
359
// contents of the poppers correct but the position needs
378
360
// to change. The documentation suggests update()
@@ -393,35 +375,30 @@ arr],
393
375
depth ) ;
394
376
}
395
377
396
- partitionChunkerWrapper ( MSD_BOOKMARKS . set_i )
378
+ partitionChunkerWrapper ( MSD_BOOKMARKS . set_i ) ;
397
379
// partitionChunkerWrapper(MSD_BOOKMARKS.set_j)
398
380
while ( i < j ) {
399
381
prev_i = i ; // save prev value for unhighlighting
400
382
prev_j = j ;
401
383
// Build the left group until it reaches the mask (find the big element)
402
- // leftCheck = true
403
- whereAreWe = MSD_BOOKMARKS . partition_left ;
404
- while ( i <= j && ( arr [ i ] >> mask & 1 ) === 0 ) {
405
- partitionChunkerWrapper ( MSD_BOOKMARKS . partition_left )
384
+ i ++ ;
385
+ partitionChunkerWrapper ( MSD_BOOKMARKS . partition_left )
386
+ while ( i < j && ( arr [ i ] >> mask & 1 ) === 0 ) {
406
387
i ++
388
+ partitionChunkerWrapper ( MSD_BOOKMARKS . partition_left )
407
389
}
408
- partitionChunkerWrapper ( MSD_BOOKMARKS . partition_left )
409
390
// Build the right group until it fails the mask (find the small element)
410
- // leftCheck = false
411
- whereAreWe = MSD_BOOKMARKS . partition_right ;
391
+ j -- ;
392
+ partitionChunkerWrapper ( MSD_BOOKMARKS . partition_right )
412
393
while ( j > i && ( arr [ j ] >> mask & 1 ) === 1 ) {
413
- partitionChunkerWrapper ( MSD_BOOKMARKS . partition_right )
414
394
j --
395
+ partitionChunkerWrapper ( MSD_BOOKMARKS . partition_right )
415
396
}
416
- partitionChunkerWrapper ( MSD_BOOKMARKS . partition_right )
417
397
418
398
// Swap if the bigger element is not in the right place
419
399
if ( i < j ) {
420
400
partitionChunkerWrapper ( MSD_BOOKMARKS . swap_condition )
421
401
swapAction ( MSD_BOOKMARKS . swap , i , j )
422
- i ++ ;
423
- j -- ;
424
- partitionChunkerWrapper ( MSD_BOOKMARKS . inc_dec )
425
402
} else {
426
403
// about to return i from partition. We update the "mid" of
427
404
// the partition on the stack here so it is displayed at the
0 commit comments