Skip to content

Commit 27ba045

Browse files
Yee17264json
authored andcommitted
Try to solve code folding problem (algorithm-visualizer#15)
* Improve Knuth-Morris-Pratt's String Search The original code.js has both display and correctness errors. * Reconstruct Knuth-Morris-Pratt's String Search/code.js 1. Add code foldings 2. Delete log tracer to simplify the content 3. Delete redundant display steps 4. Indent using 4 spaces 5. Rename variables 6. Use fixed pattern and string to illustrate * Try to add code folding * Try to add code folding * Try to fix remain errors * Fix typo
1 parent a6f8cd5 commit 27ba045

File tree

46 files changed

+966
-50
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+966
-50
lines changed

Brute Force/Insertion Sort/code.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
// import visualization libraries {
12
const { Tracer, Array1DTracer, ChartTracer, LogTracer, Randomize, Layout, VerticalLayout } = require('algorithm-visualizer');
3+
// }
24

5+
// define tracer variables {
36
const chart = new ChartTracer();
47
const tracer = new Array1DTracer();
58
const logger = new LogTracer();
@@ -8,24 +11,35 @@ const D = Randomize.Array1D({ N: 15 });
811
tracer.set(D);
912
tracer.chart(chart);
1013
Tracer.delay();
14+
// }
1115

16+
// logger {
1217
logger.println(`original array = [${D.join(', ')}]`);
18+
// }
1319
for (let i = 1; i < D.length; i++) {
1420
const key = D[i];
21+
// visualize {
1522
logger.println(`insert ${key}`);
1623
tracer.select(i);
1724
Tracer.delay();
25+
// }
1826
let j;
1927
for (j = i - 1; (j >= 0) && (D[j] > key); j--) {
2028
D[j + 1] = D[j];
29+
// visualize {
2130
tracer.patch(j + 1, D[j + 1]);
2231
Tracer.delay();
2332
tracer.depatch(j + 1);
33+
// }
2434
}
2535
D[j + 1] = key;
36+
// visualize {
2637
tracer.patch(j + 1, D[j + 1]);
2738
Tracer.delay();
2839
tracer.depatch(j + 1);
2940
tracer.deselect(i);
41+
// }
3042
}
43+
// logger {
3144
logger.println(`sorted array = [${D.join(', ')}]`);
45+
// }

Brute Force/Lowest Common Ancestor/code.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
// import visualization libraries {
12
const { Tracer, GraphTracer, LogTracer, Layout, VerticalLayout } = require('algorithm-visualizer');
3+
// }
24

35
const G = [ // G[i][j] indicates whether the path from the i-th node to the j-th node exists or not
46
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
@@ -28,23 +30,31 @@ const T = [ // mapping to G as a binary tree , [i][0] indicates left child, [i][
2830
[9, -1],
2931
];
3032

33+
// define tracer variables {
3134
const treeTracer = new GraphTracer(' Traversal Pre-order ');
3235
const logger = new LogTracer(' Log ');
3336
Layout.setRoot(new VerticalLayout([treeTracer, logger]));
3437
treeTracer.set(G);
3538
treeTracer.layoutTree(5);
3639
Tracer.delay();
40+
// }
3741

3842
function lcaBT(parent, root, a, b) {
43+
// logger {
3944
logger.println(`Beginning new Iteration of lcaBT () with parent: ${parent}, current root: ${root}`);
45+
// }
4046
if (root === -1) {
47+
// logger {
4148
logger.println('Reached end of path & target node(s) not found');
49+
// }
4250
return null;
4351
}
4452

53+
// visualize {
4554
if (parent !== null) treeTracer.visit(root, parent);
4655
else treeTracer.visit(root);
4756
Tracer.delay();
57+
// visualize {
4858

4959
if (root === a || root === b) return root;
5060

@@ -53,13 +63,17 @@ function lcaBT(parent, root, a, b) {
5363

5464
if (left !== null && right !== null) return root;
5565
if (left === null && right === null) {
66+
// visualize {
5667
treeTracer.leave(root, parent);
5768
Tracer.delay();
69+
// }
5870
}
5971

6072
return (left !== null ? left : right);
6173
}
6274

6375
const a = 7;
6476
const b = 2;
77+
// logger {
6578
logger.println(`Lowest common ancestor of ${a} & ${b} is: ${lcaBT(null, 5, a, b)}`);
79+
// }

Brute Force/PageRank/code.js

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
// import visualization libraries {
12
const { Tracer, Array1DTracer, Array2DTracer, GraphTracer, LogTracer, Randomize, Layout, VerticalLayout } = require('algorithm-visualizer');
3+
// }
24

35
function filledArray(length, value) {
46
return Array(...Array(length)).map(Number.prototype.valueOf, value);
57
}
68

9+
// define tracer variables {
710
const G = Randomize.Graph({ N: 5, ratio: .4 });
811
let ranks;
912
const outgoingEdgeCounts = filledArray(G.length, 0);
@@ -22,6 +25,7 @@ oecTracer.set(outgoingEdgeCounts);
2225
for (incomingNodes = []; incomingNodes.length < G.length; incomingNodes.push(filledArray(G.length, -1))) ;
2326
inTracer.set(incomingNodes);
2427
Tracer.delay();
28+
// }
2529

2630
/*
2731
PageRank Algorithm Version 2
@@ -41,47 +45,59 @@ function arraySum(array) {
4145
function showOutgoingEdges(i) {
4246
G[i].forEach((edgeExists, j) => {
4347
if (edgeExists) {
48+
// visualize {
4449
graphTracer.visit(j, i);
4550
Tracer.delay();
4651
graphTracer.leave(j, i);
4752
Tracer.delay();
53+
// }
4854
}
4955
});
5056
}
5157

5258
// PRECOMPUTATIONS
5359

60+
// logger {
5461
logger.println('Calculate Outgoing Edge Count for each Node');
62+
// }
5563
(function calculateOEC() {
5664
G.forEach((relations, i) => {
5765
outgoingEdgeCounts[i] = arraySum(relations);
5866
showOutgoingEdges(i);
5967

68+
// visualize {
6069
oecTracer.patch(i, outgoingEdgeCounts[i]);
6170
Tracer.delay();
6271
oecTracer.depatch(i);
6372
Tracer.delay();
73+
// }
6474
});
6575
}());
6676

77+
// logger {
6778
logger.println('determine incoming nodes for each node');
79+
// }
6880
(function determineIN() {
6981
for (let i = 0; i < G.length; i++) {
7082
for (let j = 0; j < G.length; j++) {
7183
if (G[i][j]) {
7284
// there's an edge FROM i TO j
85+
// visualize {
7386
graphTracer.visit(j, i);
7487
Tracer.delay();
88+
// }
7589

7690
const nextPos = incomingNodes[j].indexOf(-1);
7791
incomingNodes[j][nextPos] = i;
92+
// visualize {
7893
inTracer.patch(j, nextPos, i);
7994
Tracer.delay();
8095
inTracer.depatch(j, nextPos);
8196
Tracer.delay();
8297

8398
graphTracer.leave(j, i);
8499
Tracer.delay();
100+
// }
85101
}
86102
}
87103
}
@@ -96,55 +112,75 @@ function updateRank(nodeIndex) {
96112
let inNodeSummation = 0;
97113
let result;
98114

115+
// logger {
99116
logger.println(`Updating rank of ${nodeIndex}`);
100117
logger.println(`The incoming Nodes of ${nodeIndex} are being highlighted`);
118+
// }
101119

102120
incomingNodes[nodeIndex].forEach((incoming, i) => {
121+
// visualize {
103122
inTracer.select(nodeIndex, i);
104123
Tracer.delay();
105124
logger.println(`Outgoing edge count of ${incoming} is ${outgoingEdgeCounts[incoming]}`);
106125
oecTracer.select(incoming);
107126
Tracer.delay();
127+
// }
108128

109129
inNodeSummation += (ranks[incoming] / outgoingEdgeCounts[incoming]);
110130

131+
// visualize {
111132
oecTracer.deselect(incoming);
112133
Tracer.delay();
113134
inTracer.deselect(nodeIndex, i);
114135
Tracer.delay();
136+
// }
115137
});
138+
// logger {
116139
logger.println(`In-Node summation of ${nodeIndex} = ${inNodeSummation}`);
117-
140+
// }
141+
118142
result = ((1 - damping) / G.length) + (damping * inNodeSummation); // notice the subtle difference between equations of Basic PR & PR version 2 (divide by N)
143+
// logger {
119144
logger.println(`Therefore, using Equation, new rank of ${nodeIndex} = ${result}`);
145+
// }
120146
return result;
121147
}
122148

123149
let damping = 0.85;
124150
let iterations = 7;
125151
const initialRank = 1.0;
126152

153+
// logger {
127154
logger.println(`Initialized all Page ranks to ${initialRank}`);
155+
// }
128156
ranks = filledArray(G.length, initialRank);
129157

158+
// visualize {
130159
rankTracer.set(ranks);
160+
// }
161+
// logger {
131162
logger.println('Begin execution of PageRank Version #1');
132163
logger.println('Equation used: PR (X) = (1 - D) + D (In-Node-Summation i->X (PR (I) / Out (i)))');
133164
logger.println('D = Damping Factor, PR (X) = Page rank of Node X, i = the ith In-Node of X, Out (i) = outgoing Edge Count of i');
134165
logger.println('');
166+
// }
135167

136168
while (iterations--) {
137169
for (let node = 0; node < ranks.length; node++) {
138170
ranks[node] = updateRank(node);
171+
// visualize {
139172
rankTracer.patch(node, ranks[node]);
140173
Tracer.delay();
141174
rankTracer.patch(node);
142175
Tracer.delay();
176+
// }
143177
}
144178
}
145179

180+
// logger {
146181
logger.println('Page Ranks have been converged to.');
147182
ranks.forEach((rank, node) => {
148183
logger.println(`Rank of Node #${node} = ${rank}`);
149184
});
150185
logger.println('Done');
186+
// }

Brute Force/Pancake Sort/code.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
// import visualization libraries {
12
const { Tracer, Array1DTracer, ChartTracer, LogTracer, Randomize, Layout, VerticalLayout } = require('algorithm-visualizer');
3+
// }
24

5+
// define tracer variables {
36
const chart = new ChartTracer();
47
const tracer = new Array1DTracer();
58
const logger = new LogTracer();
@@ -8,43 +11,63 @@ const D = Randomize.Array1D({ N: 10 });
811
tracer.set(D);
912
tracer.chart(chart);
1013
Tracer.delay();
14+
// }
1115

16+
// logger {
1217
logger.println(`original array = [${D.join(', ')}]`);
18+
// }
1319
const N = D.length;
1420

1521
function flip(start) {
22+
// visualize {
1623
tracer.select(start, N - 1);
1724
Tracer.delay();
25+
// }
1826
let idx = 0;
1927
for (let i = start; i < (start + N) / 2; i++) {
28+
// visualize {
2029
tracer.select(i);
2130
Tracer.delay();
31+
// }
2232
const temp = D[i];
2333
D[i] = D[N - idx - 1];
2434
D[N - idx - 1] = temp;
35+
// visualize {
2536
tracer.patch(i, D[i]);
2637
tracer.patch(N - idx - 1, D[N - idx - 1]);
2738
Tracer.delay();
2839
tracer.depatch(i);
2940
tracer.depatch(N - idx - 1);
3041
tracer.deselect(i);
42+
// }
3143
idx++;
3244
}
45+
// visualize {
3346
tracer.deselect(start, N - 1);
47+
// }
3448
}
3549

3650
for (let i = 0; i < N - 1; i++) {
51+
// logger {
3752
logger.println(`round ${i + 1}`);
53+
// }
3854
const currArr = D.slice(i, N);
3955
const currMax = currArr.reduce((prev, curr, idx) => ((curr > prev.val) ? { idx, val: curr } : prev), {
4056
idx: 0,
4157
val: currArr[0],
4258
});
4359
if (currMax.idx !== 0) { // if currMax.idx === 0 that means max element already at the bottom, no flip required
60+
// logger {
4461
logger.println(`flip at ${currMax.idx + i} (step 1)`);
62+
// }
4563
flip(currMax.idx + i, N);
64+
// logger {
4665
logger.println(`flip at ${i} (step 2)`);
66+
// }
4767
flip(i, N);
4868
}
4969
}
70+
71+
// logger {
5072
logger.println(`sorted array = [${D.join(', ')}]`);
73+
// }

Brute Force/Rabin-Karp's String Search/code.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,22 @@
1+
// import visualization libraries {
12
const { Tracer, Array1DTracer, LogTracer, Layout, VerticalLayout } = require('algorithm-visualizer');
3+
// }
24

35
const text = ['h', 'e', 'l', 'l', 'o', ' ', 's', 'i', 'r', ' ', 'h', 'e', 'l', 'l', 'o'];
46
const pattern = ['h', 'e', 'l', 'l', 'o'];
57

68
const Q = 101; // A prime number
79
const D = 256; // number of characters in the input alphabet
810

11+
// define tracer variables {
912
const logger = new LogTracer();
1013
const tracer1 = new Array1DTracer('Text');
1114
const tracer2 = new Array1DTracer('Pattern');
1215
Layout.setRoot(new VerticalLayout([logger, tracer1, tracer2]));
1316
tracer1.set(text);
1417
tracer2.set(pattern);
1518
Tracer.delay();
19+
// }
1620

1721
const N = text.length;
1822
const M = pattern.length;
@@ -38,27 +42,35 @@ for (let i = 0; i <= N - M; i++) {
3842
*/
3943
if (hashPattern === hashText) {
4044
let f = 0;
45+
// visualize {
4146
tracer1.select(i, i + M - 1);
4247
Tracer.delay();
4348
tracer2.select(0, M - 1);
4449
Tracer.delay();
50+
// }
4551
for (let j = 0; j < M; j++) {
52+
// visualize {
4653
tracer1.patch(i + j);
4754
Tracer.delay();
4855
tracer2.patch(j);
4956
Tracer.delay();
57+
// }
5058
if (text[i + j] !== pattern[j]) {
5159
f++;
5260
}
61+
// visualize {
5362
tracer1.depatch(i + j);
5463
tracer2.depatch(j);
64+
// }
5565
}
5666

67+
// visualize {
5768
if (f === 0) {
5869
logger.println(` Pattern found at index ${i}`);
5970
}
6071
tracer1.deselect(i, i + M);
6172
tracer2.deselect(0, M - 1);
73+
// }
6274
}
6375

6476
/*

0 commit comments

Comments
 (0)