Skip to content

Commit 04e86f3

Browse files
committed
Added in placeholder files for all needed file changes. Prototype algorithm isn't up and running yet with issues around parameters and controllers not being recognised.
1 parent 92db845 commit 04e86f3

File tree

16 files changed

+1204
-2
lines changed

16 files changed

+1204
-2
lines changed

.idea/vcs.xml

Lines changed: 0 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 301 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,301 @@
1+
// Heapsort animation
2+
//
3+
// It's worth looking at this code if you are planning to write any new
4+
// modules.
5+
//
6+
// This was the first animation done and the code is reasonably simple -
7+
// the abstractions supported match what we need for this algorithm.
8+
// For various other algorithms, the code seems much more messy - maybe
9+
// the abstractions for the data structures/rendering are not quite what
10+
// is needed or the coding is done with a sledgehammer, so to speak.
11+
//
12+
// The original version of this code was not quite right in the way it
13+
// adapted (or didn't adapt) to expansion/collapse of code blocks. This
14+
// was added later in a reasonably simple way (again, other algorithms
15+
// may use the sledgehammer style).
16+
//
17+
// One thing that could make the code here more readable is to use
18+
// meaningful strings for bookmarks rather than numbers.
19+
20+
/* eslint-disable no-multi-spaces,indent,prefer-destructuring,brace-style */
21+
import GraphTracer from '../../components/DataStructures/Graph/GraphTracer';
22+
import ArrayTracer from '../../components/DataStructures/Array/Array1DTracer';
23+
import {areExpanded} from './collapseChunkPlugin';
24+
25+
// k displayed only if first BuildHeap is expanded
26+
// Note: This is only needed in the last chunk of BuildHeap. The code
27+
// looks like it displays k throughout BuildHeap but when BuildHeap is
28+
// collapsed, only the last chunk is rendered so the other chunks don't
29+
// matter and we can avoid testing what is expanded there. Another
30+
// approach would be to use a wrapper function for assigning to k, which
31+
// checks isBuildHeapExpanded() (it doesn't generalise well for i and j
32+
// though).
33+
function isBuildHeapExpanded() {
34+
return areExpanded(['BuildHeap']);
35+
}
36+
37+
// i, j (in build) displayed only if first DownHeap is expanded
38+
// See Note in isBuildHeapExpanded()
39+
function isDownHeapkExpanded() {
40+
return areExpanded(['BuildHeap', 'DownHeapk']);
41+
}
42+
43+
export default {
44+
initVisualisers() {
45+
return {
46+
array: {
47+
instance: new ArrayTracer('array', null, 'Array view', { arrayItemMagnitudes: true }), // Label the input array as array view
48+
order: 0,
49+
},
50+
heap: {
51+
instance: new GraphTracer('heap', null, 'Tree view'), // Label the animation of the heap as tree view
52+
order: 1,
53+
},
54+
};
55+
},
56+
57+
58+
/**
59+
*
60+
* @param {object} chunker
61+
* @param {array} nodes array of numbers needs to be sorted
62+
*/
63+
run(chunker, { nodes }) {
64+
// create a copy, can't simply let A = nodes because it creates a reference
65+
// sort A in-place will cause nodes sorted as well
66+
const A = [...nodes];
67+
let n = nodes.length;
68+
let i;
69+
let heap;
70+
let swap;
71+
72+
chunker.add(
73+
1,
74+
(vis, array) => {
75+
vis.heap.setHeap(array);
76+
// tell the graph renderer that it is heapsort
77+
// so that the array index should start from 1
78+
vis.array.set(array, 'heapsort');
79+
},
80+
[nodes],
81+
);
82+
83+
const highlight = (vis, index, primaryColor = true) => {
84+
if (primaryColor) {
85+
vis.heap.visit(index + 1);
86+
vis.array.select(index);
87+
} else {
88+
vis.heap.select(index + 1);
89+
vis.array.patch(index);
90+
}
91+
};
92+
93+
const unhighlight = (vis, index, primaryColor = true) => {
94+
if (primaryColor) {
95+
vis.heap.leave(index + 1);
96+
vis.array.deselect(index);
97+
} else {
98+
vis.heap.deselect(index + 1);
99+
vis.array.depatch(index);
100+
}
101+
};
102+
103+
const swapAction = (b, n1, n2) => {
104+
chunker.add(b, (vis, _n1, _n2) => {
105+
vis.heap.swapNodes(_n1 + 1, _n2 + 1);
106+
vis.array.swapElements(_n1, _n2);
107+
}, [n1, n2]);
108+
};
109+
110+
/** NOTE: In Lee's code, array index starts from 1
111+
* however, in JS, array index naturally starts from 0
112+
* index start from 0:
113+
* parent = k , left child = 2*k + 1, right child = 2*k + 2
114+
* index start from 1:
115+
* parent = k , left child = 2*k, right child = 2*k + 1
116+
*/
117+
118+
// keep track of last node highlighted due to i (or k) so we can
119+
// unhighlight it of buildHeap is collapsed
120+
let lastiHighlight;
121+
122+
// build heap
123+
// start from the last non-leaf node, work backwards to maintain the heap
124+
for (let k = Math.floor(n / 2) - 1; k >= 0; k -= 1) {
125+
126+
let j;
127+
const tmp = i;
128+
i = k;
129+
130+
chunker.add(4, (vis, index1, index2) => {
131+
vis.array.assignVariable('k', index1);
132+
// if (tmp != null) { // XXX looks dodgy using tmp here?
133+
if (index2 != null) {
134+
unhighlight(vis, index2);
135+
vis.array.removeVariable('j');
136+
}
137+
highlight(vis, index1);
138+
}, [i, tmp]);
139+
140+
chunker.add(6, (vis, index1, index2) => {
141+
vis.array.assignVariable('i', index1);
142+
}, [i, tmp]);
143+
144+
lastiHighlight = k;
145+
heap = false;
146+
chunker.add(7);
147+
148+
chunker.add(8);
149+
// if current node's left child's index is greater than array length,
150+
// then current node is a leaf
151+
while (!(2 * i + 1 >= n || heap)) {
152+
chunker.add(10);
153+
154+
// left child is smaller than right child
155+
if (2 * i + 2 < n && A[2 * i + 1] < A[2 * i + 2]) {
156+
j = 2 * i + 2;
157+
chunker.add(11, (vis, index) => {
158+
highlight(vis, index, false);
159+
vis.array.assignVariable('j', index);
160+
}, [j]);
161+
} else {
162+
j = 2 * i + 1;
163+
chunker.add(13, (vis, index) => {
164+
highlight(vis, index, false);
165+
vis.array.assignVariable('j', index);
166+
}, [j]);
167+
}
168+
169+
chunker.add(14);
170+
// parent is greater than largest child, so it is already a valid heap
171+
if (A[i] >= A[j]) {
172+
heap = true;
173+
chunker.add(15, (vis, index, lastH) => {
174+
unhighlight(vis, index, false);
175+
// possible last chunk in BuildHeap/DownHeapk
176+
// remove i, j if !isDownHeapkExpanded
177+
if (!isDownHeapkExpanded()) {
178+
vis.array.removeVariable('i');
179+
vis.array.removeVariable('j');
180+
}
181+
// remove k+highlighting if !isBuildHeapExpanded
182+
if (!isBuildHeapExpanded()) {
183+
vis.array.removeVariable('k');
184+
unhighlight(vis, lastH);
185+
}
186+
}, [j, lastiHighlight]);
187+
} else {
188+
swap = A[i];
189+
A[i] = A[j];
190+
A[j] = swap;
191+
swapAction(17, i, j);
192+
lastiHighlight = j;
193+
chunker.add(18, (vis, p, c, lastH) => {
194+
unhighlight(vis, p, false);
195+
vis.array.assignVariable('i', c);
196+
// remove i, j if !isDownHeapkExpanded
197+
if (!isDownHeapkExpanded()) {
198+
vis.array.removeVariable('i');
199+
vis.array.removeVariable('j');
200+
}
201+
// remove k+highlighting if !isDownHeapkExpanded
202+
if (!isBuildHeapExpanded()) {
203+
vis.array.removeVariable('k');
204+
unhighlight(vis, lastH);
205+
}
206+
}, [i, j, lastiHighlight]);
207+
i = j;
208+
}
209+
}
210+
}
211+
212+
// sort heap
213+
214+
while (n > 1) {
215+
chunker.add(20, (vis, nVal, index) => {
216+
// clear variables & show 'n'
217+
vis.array.clearVariables();
218+
vis.array.assignVariable('n', nVal - 1);
219+
unhighlight(vis, index); // XXX skip for first loop iteration?
220+
}, [n, i]);
221+
222+
let j;
223+
swap = A[n - 1];
224+
A[n - 1] = A[0];
225+
A[0] = swap;
226+
227+
chunker.add(21, (vis, index) => {
228+
highlight(vis, index);
229+
highlight(vis, 0, false);
230+
}, [n - 1]);
231+
swapAction(21, 0, n - 1);
232+
233+
chunker.add(22, (vis, index) => {
234+
unhighlight(vis, index, false);
235+
vis.array.sorted(index);
236+
vis.heap.sorted(index + 1);
237+
238+
vis.array.assignVariable('n', index - 1);
239+
}, [n - 1]);
240+
n -= 1;
241+
242+
i = 0;
243+
chunker.add(24, (vis, index1, nVal) => {
244+
vis.array.assignVariable('i', index1);
245+
}, [i, n]);
246+
247+
chunker.add(25);
248+
heap = false;
249+
250+
chunker.add(26, (vis, nVal) => {
251+
// if (nVal === 0) vis.array.clearVariables();
252+
}, [n]);
253+
// need to maintain the heap after swap
254+
while (!(2 * i + 1 >= n || heap)) {
255+
chunker.add(28);
256+
257+
if (2 * i + 2 < n && A[2 * i + 1] < A[2 * i + 2]) {
258+
j = 2 * i + 2;
259+
chunker.add(29, (vis, index) => {
260+
highlight(vis, index, false);
261+
vis.array.assignVariable('j', index);
262+
}, [j]);
263+
} else {
264+
j = 2 * i + 1;
265+
chunker.add(31, (vis, index) => {
266+
highlight(vis, index, false);
267+
vis.array.assignVariable('j', index);
268+
}, [j]);
269+
}
270+
271+
chunker.add(32);
272+
if (A[i] >= A[j]) {
273+
heap = true;
274+
chunker.add(33, (vis, index) => {
275+
unhighlight(vis, index, false);
276+
}, [j]);
277+
} else {
278+
swap = A[i];
279+
A[i] = A[j];
280+
A[j] = swap;
281+
swapAction(35, i, j);
282+
chunker.add(36, (vis, p, c) => {
283+
unhighlight(vis, p, false);
284+
vis.array.assignVariable('i', c);
285+
}, [i, j]);
286+
i = j;
287+
}
288+
}
289+
}
290+
chunker.add(37, (vis) => {
291+
// Put in done state
292+
vis.array.clearVariables();
293+
vis.array.deselect(0);
294+
vis.array.sorted(0);
295+
vis.heap.sorted(1);
296+
unhighlight(vis, 0, true);
297+
});
298+
// for test
299+
return A;
300+
},
301+
};

src/algorithms/controllers/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,6 @@ export { default as DFSrec } from './DFSrec';
1919
export { default as prim_old } from './prim_old';
2020
export { default as prim } from './prim';
2121
export { default as kruskal } from './kruskal';
22+
23+
export { default as PROTOTYPE } from './Prototype';
24+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
JEFF IS THE BEST

src/algorithms/explanations/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,5 @@ export { default as ASTARExp } from './ASTExp.md';
1616
export { default as BFSExp } from './BFSExp.md';
1717
export { default as DFSExp } from './DFSExp.md';
1818
export { default as DFSrecExp } from './DFSrecExp.md';
19+
export { default as PROTOTYPE } from './PROTOTYPE.md';
20+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
JEFF IS SUPER THE BEST

src/algorithms/extra-info/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,5 @@ export { default as ASTARInfo } from './ASTInfo.md';
1616
export { default as BFSInfo } from './BFSInfo.md';
1717
export { default as DFSInfo } from './DFSInfo.md';
1818
export { default as DFSrecInfo } from './DFSrecInfo.md';
19+
export { default as PROTOTYPE } from './PROTOTYPE.md';
20+

src/algorithms/index.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import * as ExtraInfo from './extra-info';
66
import * as Controller from './controllers';
77
import * as Pseudocode from './pseudocode';
88
import * as Instructions from './instructions';
9+
import {PROTOTYPE_PARAM} from "./parameters";
910

1011
/*
1112
This file lists all the algorithms in the program, and imports
@@ -307,6 +308,22 @@ const allalgs = {
307308
},
308309
},
309310

311+
'PROTOTYPE': {
312+
noDeploy: false,
313+
name: 'LINKED_LIST_PROTOTYPE',
314+
category: 'Insert/Search',
315+
explanation: Explanation.PROTOTYPE,
316+
param: <Param.PROTOTYPE_PARAM/>,
317+
instructions: Instructions.PROTOTYPEINSTRUCTION,
318+
extraInfo: ExtraInfo.PROTOTYPE,
319+
pseudocode: {
320+
Search: Pseudocode.PROTOTYPE,
321+
},
322+
controller: {
323+
Search: Controller.PROTOTYPE,
324+
},
325+
},
326+
310327
};
311328

312329
const algorithms =

src/algorithms/instructions/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const KEY_UF_UNION = 'UNION';
1313
const KEY_UF_FIND = 'FIND';
1414
const KEY_UF_PC_ON = 'ON';
1515
const KEY_UF_PC_OFF = 'OFF';
16+
const PROTOTYPE = 'PROTOTYPE';
1617

1718
export const KEY_WORDS = [
1819
KEY_CODE, KEY_INSERT, KEY_PLAY, KEY_SEARCH, KEY_SORT, KEY_LOAD,
@@ -109,6 +110,8 @@ const unionFindInstructions = [{
109110
}];
110111

111112
export const BSTInstruction = bstInstructions;
113+
114+
export const PROTOTYPEINSTRUCTION = bstInstructions;
112115
export const HSInstruction = sortInstructions;
113116
export const QSInstruction = sortInstructions;
114117
export const msort_arr_td = sortInstructions;

0 commit comments

Comments
 (0)