Skip to content

Commit c4a637f

Browse files
authored
Merge pull request #8 from zanliang4tz/color-refactor
Color refactor
2 parents d6cf36a + 9e657c7 commit c4a637f

File tree

2 files changed

+155
-37
lines changed

2 files changed

+155
-37
lines changed

src/algorithms/controllers/msort_arr_bup.js

Lines changed: 154 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,58 @@ function highlight2Runlength(vis, left, mid, right, colorA, colorB) {
9696
for (let j = mid + 1; j <= right; j++) highlight(vis, j, colorB);
9797
}
9898

99+
// Highlight entire array alternating colors for runlength
100+
function highlightAllRunlengths(vis, runlength, colorA, colorB, size) {
101+
let toggle = 0; // 0 = colorA, 1 = colorB
102+
103+
for (let i = 0; i < size; i++) {
104+
if (toggle == 0) {
105+
highlight(vis, i, colorA);
106+
console.log("toggle == 0");
107+
}
108+
if (toggle == 1) {
109+
highlight(vis, i, colorB);
110+
console.log("toggle == 1");
111+
}
112+
console.log("(i + 1) % runlength = " + (runlength % (i + 1)));
113+
console.log("(runlength = " + (runlength));
114+
// Switch color after completing a run of length 'runlength'
115+
if ((i + 1) % runlength == 0) {
116+
117+
console.log("(i + 1) % runlength == 0");
118+
119+
toggle = 1 - toggle; // Flip toggle between 0 and 1
120+
121+
} console.log("toggle = " + toggle);
122+
}
123+
}
124+
125+
// Unhighlight entire array alternating colors for runlength
126+
function unhighlightAllRunlengths(vis, runlength, colorA, colorB, size) {
127+
let toggle = 0; // 0 = colorA, 1 = colorB
128+
129+
for (let i = 0; i < size; i++) {
130+
if (toggle == 0) {
131+
unhighlight(vis, i, colorA);
132+
console.log("toggle == 0");
133+
}
134+
if (toggle == 1) {
135+
unhighlight(vis, i, colorB);
136+
console.log("toggle == 1");
137+
}
138+
console.log("(i + 1) % runlength = " + (runlength % (i + 1)));
139+
console.log("(runlength = " + (runlength));
140+
// Switch color after completing a run of length 'runlength'
141+
if ((i + 1) % runlength == 0) {
142+
143+
console.log("(i + 1) % runlength == 0");
144+
145+
toggle = 1 - toggle; // Flip toggle between 0 and 1
146+
147+
} console.log("toggle = " + toggle);
148+
}
149+
}
150+
99151
// unhighlights arrayA
100152
function unhighlight(vis, index, color) {
101153
if (color == 'red') {
@@ -106,6 +158,22 @@ function unhighlight(vis, index, color) {
106158
}
107159
}
108160

161+
function highlightAPointers(vis, ap1, max1, ap2, max2, color) {
162+
if (ap1 <= max1) {
163+
highlight(vis, ap1, color);
164+
}
165+
if (ap2 <= max2) {
166+
highlight(vis, ap2, color);
167+
}
168+
}
169+
170+
// this function sets array a, highlighting from left to mid red, and set the stack
171+
function resetArrayA(vis, A, left, mid, right, runlength) {
172+
vis.array.set(A, 'msort_arr_bup');
173+
highlight2Runlength(vis, left, mid, right, colorA, colorA);
174+
set_simple_stack(vis.array, [runlength]);
175+
}
176+
109177
// Assigns label to array A at index, checks if index is greater than size of array
110178
// if index is greater than size, assign label to last element in array
111179
function assignVarToA(vis, variable_name, index, size) {
@@ -146,6 +214,8 @@ function displayMergeLabels(vis, ap1, max1, ap2, max2, bp, size) {
146214
if (isMergeExpanded()) assignVarToB(vis, 'bp', bp, size);
147215
}
148216

217+
218+
149219
function set_simple_stack(vis_array, c_stk) {
150220
console.log("set_simple_stack" + c_stk);
151221
console.log(c_stk);
@@ -190,27 +260,34 @@ export function run_msort() {
190260

191261
chunker.add('runlength', (vis, c_rlength) => {
192262
displayRunlength(vis, c_rlength, size);
263+
193264
set_simple_stack(vis.array, [c_rlength]);
265+
highlightAllRunlengths(vis, c_rlength, colorA, colorB, size);
194266
}, [runlength, simple_stack]);
195267

196268
while (runlength < size) {
197269
let left = 0;
198270

199271
chunker.add('MainWhile', (vis, c_rlength, c_left) => {
272+
200273
// display size label
201274
assignVarToA(vis, ("size = " + size), size, size);
202275

203-
let left_2 = c_left;
204-
let mid_2 = (c_rlength + c_left - 1);
205-
let right_2 = (Math.min(c_rlength * 2, size) - 1);
206276

207-
highlight2Runlength(vis, left_2, mid_2, right_2, colorA, colorB);
208277

209278
}, [runlength, left]);
210279

211-
chunker.add('left', (vis, c_left) => {
280+
chunker.add('left', (vis, c_left, c_rlength) => {
212281
assignVarToA(vis, 'left', c_left, size);
213-
}, [left]);
282+
283+
unhighlightAllRunlengths(vis, c_rlength, colorA, colorB, size);
284+
285+
let left_2 = c_left;
286+
let mid_2 = (c_rlength + c_left - 1);
287+
let right_2 = (Math.min(c_rlength * 2, size) - 1);
288+
289+
highlight2Runlength(vis, left_2, mid_2, right_2, colorA, colorB);
290+
}, [left, runlength]);
214291

215292
while ((left + runlength) <= size) {
216293

@@ -236,14 +313,23 @@ export function run_msort() {
236313

237314
chunker.add('right', (vis, c_right) => {
238315
assignVarToA(vis, 'right', c_right, size);
316+
239317
}, [right]);
240318

241-
chunker.add('ap1', (vis, c_ap1) => {
319+
chunker.add('ap1', (vis, a, c_ap1, c_left, c_mid, c_right, c_rlength) => {
242320
if (isMergeExpanded()) {
321+
322+
// now in the nitty gritty of Merge
323+
// highlight the two parts you want to merge red
324+
resetArrayA(vis, a, c_left, c_mid, c_right, c_rlength);
325+
243326
assignVarToA(vis, 'left', undefined, size); // ap1 replaces left
244327
assignVarToA(vis, 'ap1', c_ap1, size);
328+
assignVarToA(vis, 'mid', c_mid, size);
329+
assignVarToA(vis, 'right', c_right, size);
330+
245331
}
246-
}, [ap1]);
332+
}, [A, ap1, left, mid, right, runlength]);
247333

248334
chunker.add('max1', (vis, c_max1) => {
249335
if (isMergeExpanded()) {
@@ -258,10 +344,11 @@ export function run_msort() {
258344
}
259345
}, [ap2]);
260346

261-
chunker.add('max2', (vis, c_max2) => {
347+
chunker.add('max2', (vis, c_max2, c) => {
262348
if (isMergeExpanded()) {
263349
assignVarToA(vis, 'right', undefined, size); // max2 replaces right
264350
assignVarToA(vis, 'max2', c_max2, size);
351+
265352
}
266353
}, [max2]);
267354

@@ -277,16 +364,19 @@ export function run_msort() {
277364
if (!(ap1 <= max1 && ap2 <= max2)) break;
278365

279366
chunker.add('MergeWhile', (vis, a, c_left, c_right, c_mid, c_ap1, c_max1, c_ap2, c_max2, c_bp, c_rlength) => {
280-
vis.array.set(a, 'msort_arr_bup');
367+
368+
resetArrayA(vis, a, c_left, c_mid, c_right, c_rlength);
369+
281370
displayMergeLabels(vis, c_ap1, c_max1, c_ap2, c_max2, c_bp, size);
371+
282372
// future color: should be colorA & colorB
283-
highlight2Runlength(vis, c_left, c_mid, c_right, colorA, colorA);
284-
set_simple_stack(vis.array, [c_rlength]);
373+
highlightAPointers(vis, c_ap1, c_max1, c_ap2, c_max2, colorB);
374+
285375
}, [A, left, right, mid, ap1, max1, ap2, max2, bp, runlength]);
286376

287-
chunker.add('findSmaller', () => {
377+
chunker.add('findSmaller', (vis, c_ap1, c_max1, c_ap2, c_max2) => {
288378
// no animation
289-
}, []);
379+
}, [ap1, max1, ap2, max2]);
290380

291381
if (A[ap1] < A[ap2]) {
292382

@@ -296,20 +386,28 @@ export function run_msort() {
296386
chunker.add('copyap1', (vis, a, b, c_ap1, c_max1, c_ap2, c_max2, c_bp, c_left, c_right, c_mid, c_rlength) => {
297387

298388
if (isMergeExpanded()) vis.arrayB.set(b, 'msort_arr_bup');
299-
vis.array.set(a, 'msort_arr_bup');
389+
390+
resetArrayA(vis, a, c_left, c_mid, c_right, c_rlength);
391+
300392

301393
displayMergeLabels(vis, c_ap1, c_max1, c_ap2, c_max2, c_bp, size);
302394
// future color: should be colorA & colorB
303-
highlight2Runlength(vis, c_left, c_mid, c_right, colorA, colorA);
395+
396+
highlightAPointers(vis, c_ap1, c_max1, c_ap2, c_max2, colorB);
304397
// highlight sorted elements green (colorC)
305398
for (let i = c_left; i <= c_bp; i++) highlightB(vis, i, colorC);
306-
set_simple_stack(vis.array, [c_rlength]);
399+
307400
}, [A, B, ap1, max1, ap2, max2, bp, left, right, mid, runlength]);
308401

309402
ap1 = ap1 + 1;
310-
chunker.add('ap1++', (vis, c_ap1) => {
403+
chunker.add('ap1++', (vis, a, c_left, c_mid, c_right, c_rlength,
404+
c_ap1, c_max1, c_ap2, c_max2, c_bp) => {
405+
resetArrayA(vis, a, c_left, c_mid, c_right, c_rlength);
406+
displayMergeLabels(vis, c_ap1, c_max1, c_ap2, c_max2, c_bp, size);
407+
311408
assignVarToA(vis, 'ap1', c_ap1, size);
312-
}, [ap1]);
409+
highlightAPointers(vis, c_ap1, c_max1, c_ap2, c_max2, colorB);
410+
}, [A, left, mid, right, runlength, ap1, max1, ap2, max2, bp]);
313411

314412
bp = bp + 1;
315413
chunker.add('bp++', (vis, c_bp) => {
@@ -318,29 +416,40 @@ export function run_msort() {
318416
}
319417

320418
else {
321-
chunker.add('findSmallerB', () => {
419+
chunker.add('findSmallerB', (vis, c_ap1, c_max1, c_ap2, c_max2) => {
322420
// no animation
323-
}, []);
421+
highlightAPointers(vis, c_ap1, c_max1, c_ap2, c_max2, colorB);
422+
423+
}, [ap1, max1, ap2, max2]);
324424

325425
B[bp] = A[ap2];
326426
A[ap2] = undefined;
327427

328428
chunker.add('copyap2', (vis, a, b, c_ap1, c_ap2, c_bp, c_max1, c_max2, c_left, c_right, c_mid, c_rlength) => {
329429
if (isMergeExpanded()) vis.arrayB.set(b, 'msort_arr_bup');
330-
vis.array.set(a, 'msort_arr_bup');
430+
resetArrayA(vis, a, c_left, c_mid, c_right, c_rlength);
431+
331432
displayMergeLabels(vis, c_ap1, c_max1, c_ap2, c_max2, c_bp, size);
332433

333434
// future color: should be colorA & colorB
334-
highlight2Runlength(vis, c_left, c_mid, c_right, colorA, colorA);
435+
436+
highlightAPointers(vis, c_ap1, c_max1, c_ap2, c_max2, colorB);
437+
335438
// highlight sorted elements green / colorB
336439
for (let i = c_left; i <= c_bp; i++) highlightB(vis, i, 'green')
337-
set_simple_stack(vis.array, [c_rlength]);
440+
338441
}, [A, B, ap1, ap2, bp, max1, max2, left, right, mid, runlength]);
339442

340443
ap2 = ap2 + 1;
341-
chunker.add('ap2++', (vis, c_ap2) => {
444+
chunker.add('ap2++', (vis, a, c_left, c_mid, c_right, c_rlength,
445+
c_ap1, c_max1, c_ap2, c_max2, c_bp) => {
446+
resetArrayA(vis, a, c_left, c_mid, c_right, c_rlength);
447+
displayMergeLabels(vis, c_ap1, c_max1, c_ap2, c_max2, c_bp, size);
448+
342449
assignVarToA(vis, "ap2", c_ap2, size);
343-
}, [ap2]);
450+
highlightAPointers(vis, c_ap1, c_max1, c_ap2, c_max2, colorB);
451+
452+
}, [A, left, mid, right, runlength, ap1, max1, ap2, max2, bp]);
344453

345454
bp = bp + 1;
346455
chunker.add('bp++_2', (vis, c_bp) => {
@@ -357,7 +466,8 @@ export function run_msort() {
357466

358467
chunker.add('CopyRest1', (vis, a, b, c_ap1, c_max1, c_left, c_right, c_mid, c_bp, c_rlength) => {
359468

360-
vis.array.set(a, 'msort_arr_bup');
469+
resetArrayA(vis, a, c_left, c_mid, c_right, c_rlength);
470+
361471
if (isMergeExpanded()) vis.arrayB.set(b, 'msort_arr_bup');
362472

363473
// copying A[ap1..max1]
@@ -368,9 +478,7 @@ export function run_msort() {
368478
// to highlight the solrted elements of B array green / colorC
369479
for (let i = c_left; i < c_bp; i++) highlightB(vis, i, colorC);
370480

371-
// future color: should be colorA & colorB
372-
highlight2Runlength(vis, c_left, c_mid, c_right, colorA, colorA);
373-
set_simple_stack(vis.array, [c_rlength]);
481+
374482
}, [A, B, ap1, max1, left, right, mid, bp, runlength]);
375483

376484
for (let i = ap2; i <= max2; i++) {
@@ -380,7 +488,8 @@ export function run_msort() {
380488
}
381489

382490
chunker.add('CopyRest2', (vis, a, b, c_ap2, c_max2, c_left, c_right, c_mid, c_rlength) => {
383-
vis.array.set(a, 'msort_arr_bup');
491+
resetArrayA(vis, a, c_left, c_mid, c_right, c_rlength);
492+
384493
if (isMergeExpanded()) vis.arrayB.set(b, 'msort_arr_bup');
385494
assignVarToA(vis, 'ap2', c_ap2, size);
386495
assignVarToA(vis, 'max2', c_max2, size);
@@ -389,8 +498,7 @@ export function run_msort() {
389498
for (let i = c_left; i <= c_right; i++) highlightB(vis, i, colorC);
390499

391500
// future color: should be colorA & colorB
392-
highlight2Runlength(vis, c_left, c_mid, c_right, colorA, colorA);
393-
set_simple_stack(vis.array, [c_rlength]);
501+
394502
}, [A, B, ap2, max2, left, right, mid, runlength]);
395503

396504
// copy merged elements from B to A
@@ -400,19 +508,22 @@ export function run_msort() {
400508
}
401509

402510
chunker.add('copyBA', (vis, a, b, c_left, c_right, c_rlength) => {
511+
403512
vis.array.set(a, 'msort_arr_bup');
513+
set_simple_stack(vis.array, [c_rlength]);
514+
404515
if (isMergeExpanded()) vis.arrayB.set(b, 'msort_arr_bup');
405516

406517
// highlight all sorted elements green
407518
for (let i = c_left; i <= c_right; i++) highlight(vis, i, colorC);
408-
set_simple_stack(vis.array, [c_rlength]);
519+
409520
}, [A, B, left, right, runlength]);
410521

411522
let left2 = left; // this is the old left before it was updated
412523

413524
left = right + 1;
414525

415-
chunker.add('left2', (vis, old_left, c_left, c_right) => {
526+
chunker.add('left2', (vis, old_left, c_left, c_right, c_rlength) => {
416527
// unhighlight all elements in A
417528
for (let i = old_left; i <= c_right; i++) {
418529
unhighlight(vis, i, colorC);
@@ -421,13 +532,19 @@ export function run_msort() {
421532
assignVarToA(vis, 'left', c_left, size);
422533
}
423534

424-
}, [left2, left, right]);
535+
}, [left2, left, right, runlength]);
425536

426537
}
538+
runlength = 2 * runlength;
539+
540+
chunker.add('mergeDone', (vis, c_rlength) => {
541+
highlightAllRunlengths(vis, c_rlength, colorA, colorB, size);
542+
}, [runlength])
427543

428544

429-
runlength = 2 * runlength;
430545
chunker.add('runlength2', (vis, c_rlength) => {
546+
547+
// highlightAllRunlengths(vis, c_rlength, colorA, colorB, size);
431548
assignVarToA(vis, 'left', undefined, size);
432549
set_simple_stack(vis.array, [c_rlength]);
433550

src/algorithms/pseudocode/msort_arr_bup.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ MergeAll
3939
merge A[left..mid] and A[mid+1..right], with the result in A \\Ref MergeCopy
4040
left <- right + 1 // skip to the next pair of runs (if any) \\B left2
4141
\\In}
42+
// all consecutive pairs of runs merged \\B mergeDone
4243
\\Code}
4344
4445
\\Note{

0 commit comments

Comments
 (0)