Skip to content

Commit a13b0c3

Browse files
committed
Extra colors, straight radix sort
1 parent 83d0cf7 commit a13b0c3

File tree

7 files changed

+122
-77
lines changed

7 files changed

+122
-77
lines changed

src/algorithms/controllers/straightRadixSort.js

Lines changed: 67 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,20 @@ import ArrayTracer from '../../components/DataStructures/Array/Array1DTracer';
33
import MaskTracer from '../../components/DataStructures/Mask/MaskTracer';
44
import { areExpanded } from './collapseChunkPlugin';
55
import { createPopper } from '@popperjs/core';
6+
import {colors} from '../../components/DataStructures/colors';
67

78
// radix must be a power of two; we use radix 4 here but code should work
89
// with another radix except vis.mask.setAddBase4() would need to be
9-
// generalised and that call deleted if radix = 2
10+
// generalised and that call deleted if radix = 2, plus digitColor
11+
// would need generalising
1012
const RADIX_BITS = 2;
1113
const RADIX = 1 << RADIX_BITS;
1214

15+
const highlightColor = colors.apple; // various highlights
16+
const changedColor = colors.wood; // for cumulative sums
17+
// colors for the 4 digits
18+
const digitColor = [colors.peach, colors.leaf, colors.sky, colors.plum];
19+
1320
const SRS_BOOKMARKS = {
1421
radix_sort: 1,
1522
max_number: 2,
@@ -37,19 +44,28 @@ const isCountExpanded = () => {
3744

3845
const highlight = (array, index, isPrimaryColor = true) => {
3946
if (isPrimaryColor) {
40-
array.select(index);
47+
array.selectColor(index, highlightColor);
4148
} else {
42-
array.patch(index);
49+
array.selectColor(index, changedColor);
4350
}
4451
};
4552

46-
const unhighlight = (array, index, isPrimaryColor = true) => {
47-
if (isPrimaryColor) {
48-
array.deselect(index);
49-
} else {
50-
array.depatch(index);
53+
// color all digits in array according to digit value
54+
const colorDigits = (A, visA, digit, n) => {
55+
for (let i = 0; i < n; i++) {
56+
if (A[i] !== undefined) {
57+
visA.deselect(i);
58+
visA.selectColor(i, digitColor[bitsAtIndex(A[i], digit, RADIX_BITS)]);
59+
}
5160
}
52-
};
61+
}
62+
63+
// color all counts in array according to index
64+
const colorCounts = (visA, n) => {
65+
for (let i = 0; i < n; i++) {
66+
visA.selectColor(i, digitColor[i]);
67+
}
68+
}
5369

5470
const updateMask = (vis, index, bits) => {
5571
const mask = ((1 << bits) - 1) << (index * bits);
@@ -120,42 +136,38 @@ export default {
120136
(vis, count) => {
121137
if (isCountExpanded()) {
122138
setArray(vis.countArray, count);
139+
colorCounts(vis.countArray, RADIX);
123140
}
124141
},
125142
[count]
126143
);
127144

128145
for (let i = 0; i < n; i++) {
129146
chunker.add(SRS_BOOKMARKS.add_count_for_loop,
130-
(vis, i, lastBit, count) => {
147+
(vis, i, lastBit, count, A, n, k) => {
131148
if (isCountExpanded()) {
132149
setArray(vis.countArray, count);
150+
colorCounts(vis.countArray, RADIX);
133151
}
134-
if (i !== 0) {
135-
unhighlight(vis.array, i - 1);
136-
}
137-
138-
if (lastBit !== -1 && isCountExpanded()) {
139-
unhighlight(vis.countArray, lastBit);
140-
}
141-
152+
colorDigits(A, vis.array, k, n);
142153
highlight(vis.array, i);
143154
updateBinary(vis, A[i]);
144155
},
145-
[i, lastBit, count]
156+
[i, lastBit, count, A, n, k]
146157
);
147158

148159
const bit = bitsAtIndex(A[i], k, radixBits);
149160
count[bit]++;
150161

151162
chunker.add(SRS_BOOKMARKS.add_to_count,
152-
(vis, count) => {
163+
(vis, i, count, A, n, k) => {
153164
if (isCountExpanded()) {
154165
setArray(vis.countArray, count);
155-
highlight(vis.countArray, bit);
166+
colorCounts(vis.countArray, RADIX);
156167
}
168+
colorDigits(A, vis.array, k, n);
157169
},
158-
[count]
170+
[i, count, A, n, k]
159171
);
160172

161173
lastBit = bit;
@@ -176,19 +188,13 @@ export default {
176188

177189
for (let i = 1; i < count.length; i++) {
178190
chunker.add(SRS_BOOKMARKS.cum_sum_for_loop,
179-
(vis, i, n, lastBit) => {
191+
(vis, i, A, n, lastBit) => {
180192
if (isCountExpanded()) {
181-
if (i === 1) {
182-
unhighlight(vis.array, n - 1);
183-
} else
184-
unhighlight(vis.countArray, i-1, false);
185-
if (i === 1 && isCountExpanded()) {
186-
unhighlight(vis.countArray, lastBit);
187-
}
193+
colorCounts(vis.countArray, RADIX);
188194
highlight(vis.countArray, i);
189195
}
190196
},
191-
[i, n, lastBit]
197+
[i, A, n, lastBit]
192198
);
193199

194200
count[i] += count[i - 1];
@@ -197,7 +203,7 @@ export default {
197203
(vis, count, i) => {
198204
if (isCountExpanded()) {
199205
setArray(vis.countArray, count);
200-
highlight(vis.countArray, i, false);
206+
colorCounts(vis.countArray, RADIX);
201207
}
202208
},
203209
[count, i]
@@ -224,54 +230,60 @@ export default {
224230
for (let i = n - 1; i >= 0; i--) {
225231
const num = A[i];
226232
chunker.add(SRS_BOOKMARKS.populate_for_loop,
227-
(vis, num, i, bit, count, sortedA) => {
233+
(vis, num, i, bit, count, A, sortedA, k, n) => {
228234
if (i === n - 1) {
229235
if (isCountExpanded()) {
230-
unhighlight(vis.countArray, count.length - 1, false);
236+
// unhighlight(vis.countArray, count.length - 1, false);
231237
}
232238
} else {
233-
unhighlight(vis.array, i + 1);
239+
colorDigits(A, vis.array, k, n);
234240
if (isCountExpanded()) {
235241
setArray(vis.countArray, count);
242+
colorCounts(vis.countArray, RADIX);
236243
setArray(vis.tempArray, sortedA);
237-
unhighlight(vis.countArray, bit);
238-
unhighlight(vis.tempArray, count[bit]);
244+
colorDigits(sortedA, vis.tempArray, k, n);
239245
}
240246
}
241247
updateBinary(vis, num);
242-
highlight(vis.array, i);
248+
// highlight(vis.array, i);
243249
},
244-
[num, i, bit, count, sortedA]
250+
[num, i, bit, count, A, sortedA, k, n]
245251
);
246252
bit = bitsAtIndex(num, k, radixBits);
247253
count[bit]--;
248254
chunker.add(SRS_BOOKMARKS.dec_count,
249-
(vis, num, i, bit, count, sortedA) => {
255+
(vis, num, i, bit, count, A, sortedA, k, n) => {
250256

251257
if (isCountExpanded()) {
252258
setArray(vis.countArray, count);
253-
highlight(vis.countArray, bit);
259+
colorCounts(vis.countArray, RADIX);
260+
// highlight(vis.countArray, bit);
254261
}
262+
colorDigits(A, vis.array, k, n);
255263
},
256-
[num, i, bit, count, sortedA]
264+
[num, i, bit, count, A, sortedA, k, n]
257265
);
258266
sortedA[count[bit]] = num;
267+
A[i] = undefined; // blank out array element
259268
chunker.add(SRS_BOOKMARKS.insert_into_array,
260-
(vis, num, i, bit, count, sortedA) => {
269+
(vis, num, i, bit, count, A, sortedA, k, n) => {
261270

271+
setArray(vis.array, A);
272+
colorDigits(A, vis.array, k, n);
262273
if (isCountExpanded()) {
263274
setArray(vis.tempArray, sortedA);
264-
highlight(vis.tempArray, count[bit]);
275+
colorDigits(sortedA, vis.tempArray, k, n);
276+
// highlight(vis.tempArray, count[bit]);
265277
}
266278
},
267-
[num, i, bit, count, sortedA]
279+
[num, i, bit, count, A, sortedA, k, n]
268280
);
269281
}
270282

271283
chunker.add(SRS_BOOKMARKS.copy,
272-
(vis, array, n, countLength, bits) => {
284+
(vis, array, n, countLength, k) => {
273285
setArray(vis.array, array);
274-
286+
colorDigits(array, vis.array, k, n);
275287
if (isCountExpanded()) {
276288
setArray(vis.tempArray, Array.apply(null, Array(n)).map(() => undefined));
277289
setArray(vis.countArray, Array.apply(null, Array(countLength)).map(() => undefined));
@@ -284,7 +296,7 @@ export default {
284296
}
285297
}, DELAY_POPPER_UPDATE);
286298
},
287-
[sortedA, n, count.length, bits]
299+
[sortedA, n, count.length, k]
288300
);
289301

290302
return sortedA;
@@ -310,6 +322,7 @@ export default {
310322

311323
if (isCountExpanded()) {
312324
setArray(vis.countArray, Array.apply(null, Array(1 << RADIX_BITS)).map(() => undefined));
325+
colorCounts(vis.countArray, RADIX);
313326
setArray(vis.tempArray, Array.apply(null, Array(n)).map(() => undefined));
314327
}
315328
// create poppers or reset poppers if they already exist
@@ -358,9 +371,14 @@ export default {
358371

359372
for (let k = 0; k < bits / RADIX_BITS; k++) {
360373
chunker.add(SRS_BOOKMARKS.counting_sort_for_loop,
361-
vis => {
374+
(vis, A, k) => {
362375
updateMask(vis, k, RADIX_BITS);
376+
for (let i = 0; i < n; i++) {
377+
vis.array.deselect(i);
378+
vis.array.selectColor(i, digitColor[bitsAtIndex(A[i], k, RADIX_BITS)]);
363379
}
380+
},
381+
[A, k]
364382
);
365383

366384
A = countingSort(A, k, n, RADIX_BITS);

src/algorithms/pseudocode/straightRadixSort.js

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ Radixsort(A, n) // Sort array A[0]..A[n-1] in ascending order. \\B 1
2525
\\Expl}
2626
2727
Find maximum number of "digits" used in the data \\B 2
28-
\\Expl{ This depends on the radix (base) we use to view the data.
28+
\\Expl{ This depends on the radix (base) we use to view the data.
2929
Here we use radix 4 for illustration (the digits are 0-3 and use
30-
two bits; we show the binary representation of the keys and the
30+
two bits; we show the bsae 4 and binary representation of the keys and the
3131
mask used to extract the current digit).
3232
We could use radix 10 (decimal digits), radix 2
3333
(binary) or anything else. Radix 256 (one byte) is a
@@ -54,18 +54,19 @@ Radixsort(A, n) // Sort array A[0]..A[n-1] in ascending order. \\B 1
5454
Countingsort
5555
Array Count <- counts of each kth digit value \\Ref CountNums
5656
\\Expl{ We count the number of occurrences of each digit value (here 0-3
57-
or binary 00-11) in the kth digits of the data.
57+
or binary 00-11) in the kth digits of the data. Consistent colors are
58+
used for the different digit values in this and other arrays).
5859
\\Expl}
5960
Cumulatively sum digit value counts \\Ref CumSum
6061
\\Expl{ For each digit value, we compute the count for that digit value
6162
plus all smaller digit values. This allows us to determine where the
6263
last occurrence of each digit value will appear in the sorted array
6364
(the counts are one greater than the index because we start at index 0).
6465
\\Expl}
65-
Array B <- sorted numbers \\Ref Populate
66+
Array B <- numbers sorted on digit k \\Ref Populate
6667
\\Expl{ We copy the data to temporary array B, using the digit
6768
value counts to determine where each element is copied to, so the result
68-
is sorted on this digit.
69+
is sorted on this digit. We scan right to left to make the sorting stable.
6970
\\Expl}
7071
Copy B back to A \\B 10
7172
\\Expl{ Array A is now sorted on digit k and all less significant digits
@@ -80,7 +81,8 @@ initialise array Count to all zeros \\B 16
8081
for num in A \\B 13
8182
\\In{
8283
digit <- kth digit value in num \\B 17
83-
\\Expl{ The digit is the two highlighted bits in the binary representation.
84+
\\Expl{ The digit is highlighted in the base 4 display (and the two
85+
bits in the binary representation).
8486
To extract the kth digit we can use div and mod operations.
8587
If the radix is a power of two we can use bit-wise operations
8688
(right shift and bit-wise and) instead.
@@ -114,7 +116,8 @@ for each num in A in reverse order \\B 8
114116
\\Expl}
115117
\\In{
116118
digit <- kth digit value in num \\B 19
117-
\\Expl{ The digit is the two highlighted bits in the binary representation.
119+
\\Expl{ The digit is highlighted in the base 4 representation (and
120+
the two bits in the binary representation).
118121
To extract the kth digit we can use div and mod operations.
119122
If the radix is a power of two we can use bit-wise operations
120123
(right shift and bit-wise and) instead.

src/components/DataStructures/Array/Array1DRenderer/Array1DRenderer.module.scss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,15 +102,15 @@
102102
}
103103

104104
&.selected4 {
105-
background-color: var(--array-2d-row-col-bg-selected4);
105+
background-color: var(--plum);
106106

107107
span {
108108
color: var(--array-2d-row-col-selected);
109109
}
110110
}
111111

112112
&.selected5 {
113-
background-color: var(--array-2d-row-col-bg-selected5);
113+
background-color: var(--wood);
114114

115115
span {
116116
color: var(--array-2d-row-col-selected);

src/components/DataStructures/Array/Array2DRenderer/Array2DRenderer.module.scss

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -94,50 +94,47 @@
9494
}
9595
}
9696

97-
&.variableGreen {
98-
background-color: var(--leaf);
97+
&.selected4 {
98+
background-color: var(--plum);
9999

100100
span {
101101
color: var(--array-2d-row-col-selected);
102102
}
103103
}
104104

105-
&.variableOrange {
106-
// more of a yellow, really
107-
background-color: var(--peach);
105+
&.selected5 {
106+
background-color: var(--wood);
108107

109108
span {
110-
color: var(--array-2d-row-col);
109+
color: var(--array-2d-row-col-selected);
111110
}
112111
}
113112

114-
&.variableRed {
115-
background-color: var(--apple);
113+
&.variableGreen {
114+
background-color: var(--leaf);
116115

117116
span {
118117
color: var(--array-2d-row-col-selected);
119118
}
120119
}
121120

122-
123-
&.selected4 {
124-
background-color: var(--array-2d-row-col-bg-selected4);
121+
&.variableOrange {
122+
// more of a yellow, really
123+
background-color: var(--peach);
125124

126125
span {
127-
color: var(--array-2d-row-col-selected);
126+
color: var(--array-2d-row-col);
128127
}
129128
}
130129

131-
&.selected5 {
132-
background-color: var(--array-2d-row-col-bg-selected5);
130+
&.variableRed {
131+
background-color: var(--apple);
133132

134133
span {
135134
color: var(--array-2d-row-col-selected);
136135
}
137136
}
138137

139-
140-
141138
&.patched {
142139
background-color: var(--peach);
143140

0 commit comments

Comments
 (0)