Skip to content

Improve Knuth-Morris-Pratt's String Search #14

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Oct 16, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions Backtracking/Knight's Tour Problem/code.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
// import visualization libraries {
const { Tracer, Array1DTracer, Array2DTracer, LogTracer, Layout, VerticalLayout } = require('algorithm-visualizer');
// }

/*
For N>3 the time taken by this algorithm is sufficiently high
Expand Down Expand Up @@ -26,13 +28,15 @@ const Y = [1, 2, 2, 1, -1, -2, -2, -1];
const pos = new Array(2);
pos[0] = pos[1] = -1;

// define tracer variables {
const boardTracer = new Array2DTracer('Board');
const posTracer = new Array1DTracer('Knight Position');
const logTracer = new LogTracer('Console');
boardTracer.set(board);
posTracer.set(pos);
Layout.setRoot(new VerticalLayout([boardTracer, posTracer, logTracer]));
Tracer.delay();
// }

function knightTour(x, y, moveNum) {
if (moveNum === N * N) {
Expand All @@ -43,37 +47,48 @@ function knightTour(x, y, moveNum) {
const nextX = x + X[i];
const nextY = y + Y[i];

// visualize {
posTracer.patch(0, nextX);
Tracer.delay();
posTracer.patch(1, nextY);
Tracer.delay();
posTracer.depatch(0);
posTracer.depatch(1);
// }
/*
Check if knight is still in the board
Check that knight does not visit an already visited square
*/
if (nextX >= 0 && nextX < N && nextY >= 0 && nextY < N && board[nextX][nextY] === -1) {
board[nextX][nextY] = moveNum;

// visualize {
logTracer.println(`Move to ${nextX},${nextY}`);
boardTracer.patch(nextX, nextY, moveNum);
Tracer.delay();
boardTracer.depatch(nextX, nextY);
boardTracer.select(nextX, nextY);
// }

const nextMoveNum = moveNum + 1;
if (knightTour(nextX, nextY, nextMoveNum) === true) {
return true;
}

// logger {
logTracer.println(`No place to move from ${nextX},${nextY}: Backtrack`);
// }
board[nextX][nextY] = -1; // backtrack
// visualize {
boardTracer.patch(nextX, nextY, -1);
Tracer.delay();
boardTracer.depatch(nextX, nextY);
boardTracer.deselect(nextX, nextY);
// }
} else {
// logger {
logTracer.println(`${nextX},${nextY} is not a valid move`);
// }
}
}
return false;
Expand All @@ -83,6 +98,7 @@ board[0][0] = 0; // start from this position
pos[0] = 0;
pos[0] = 0;

// visualize {
boardTracer.patch(0, 0, 0);
Tracer.delay();
posTracer.patch(0, 0);
Expand All @@ -93,9 +109,12 @@ boardTracer.depatch(0, 0);
boardTracer.depatch(0, 0);
posTracer.depatch(0);
posTracer.depatch(1);
// }

// logger {
if (knightTour(0, 0, 1) === false) {
logTracer.println('Solution does not exist');
} else {
logTracer.println('Solution found');
}
// }
22 changes: 20 additions & 2 deletions Backtracking/N-Queens Problem/code.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
// import visualization libraries {
const { Tracer, Array2DTracer, LogTracer, Layout, VerticalLayout } = require('algorithm-visualizer');
// }

const N = 4; // just change the value of N and the visuals will reflect the configuration!
const board = (function createArray(N) {
Expand All @@ -16,6 +18,7 @@ const queens = (function qSetup(N) {
return result;
}(N));

// define tracer variables {
const boardTracer = new Array2DTracer('Board');
const queenTracer = new Array2DTracer('Queen Positions');
const logger = new LogTracer('Progress');
Expand All @@ -25,6 +28,7 @@ boardTracer.set(board);
queenTracer.set(queens);
logger.println(`N Queens: ${N}X${N}matrix, ${N} queens`);
Tracer.delay();
// }

function validState(row, col, currentQueen) {
for (let q = 0; q < currentQueen; q++) {
Expand All @@ -37,24 +41,31 @@ function validState(row, col, currentQueen) {
}

function nQ(currentQueen, currentCol) {
// logger {
logger.println(`Starting new iteration of nQueens () with currentQueen = ${currentQueen} & currentCol = ${currentCol}`);
logger.println('------------------------------------------------------------------');
// }
if (currentQueen >= N) {
// logger {
logger.println('The recursion has BOTTOMED OUT. All queens have been placed successfully');
// }
return true;
}

let found = false;
let row = 0;
while ((row < N) && (!found)) {
// visualize {
boardTracer.select(row, currentCol);
Tracer.delay();
logger.println(`Trying queen ${currentQueen} at row ${row} & col ${currentCol}`);

// }

if (validState(row, currentCol, currentQueen)) {
queens[currentQueen][0] = row;
queens[currentQueen][1] = currentCol;

// visualize {
queenTracer.patch(currentQueen, 0, row);
Tracer.delay();
queenTracer.patch(currentQueen, 1, currentCol);
Expand All @@ -63,21 +74,28 @@ function nQ(currentQueen, currentCol) {
Tracer.delay();
queenTracer.depatch(currentQueen, 1);
Tracer.delay();

// }

found = nQ(currentQueen + 1, currentCol + 1);
}

if (!found) {
// visualize {
boardTracer.deselect(row, currentCol);
Tracer.delay();
logger.println(`row ${row} & col ${currentCol} didn't work out. Going down`);
// }
}
row++;
}

return found;
}

// logger {
logger.println('Starting execution');
// }
nQ(0, 0);
// logger {
logger.println('DONE');
// }
17 changes: 17 additions & 0 deletions Branch and Bound/Binary Search Tree/insertion.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
// import visualization libraries {
const { Tracer, Array1DTracer, GraphTracer, LogTracer, Layout, VerticalLayout } = require('algorithm-visualizer');
// }

const T = {};

const elements = [5, 8, 10, 3, 1, 6, 9, 7, 2, 0, 4]; // item to be inserted

// define tracer variables {
const graphTracer = new GraphTracer(' BST - Elements marked red indicates the current status of tree ');
const elemTracer = new Array1DTracer(' Elements ');
const logger = new LogTracer(' Log ');
Layout.setRoot(new VerticalLayout([graphTracer, elemTracer, logger]));
elemTracer.set(elements);
graphTracer.log(logger);
Tracer.delay();
// }

function bstInsert(root, element, parent) { // root = current node , parent = previous node
// visualize {
graphTracer.visit(root, parent);
Tracer.delay();
// }
const treeNode = T[root];
let propName = '';
if (element < root) {
Expand All @@ -25,30 +32,40 @@ function bstInsert(root, element, parent) { // root = current node , parent = pr
if (!(propName in treeNode)) { // insert as left child of root
treeNode[propName] = element;
T[element] = {};
// visualize {
graphTracer.addNode(element);
graphTracer.addEdge(root, element);
graphTracer.select(element, root);
Tracer.delay();
graphTracer.deselect(element, root);
logger.println(`${element} Inserted`);
// }
} else {
bstInsert(treeNode[propName], element, root);
}
}
// visualize {
graphTracer.leave(root, parent);
Tracer.delay();
// }
}

const Root = elements[0]; // take first element as root
T[Root] = {};
// visualize {
graphTracer.addNode(Root);
graphTracer.layoutTree(Root, true);
logger.println(`${Root} Inserted as root of tree `);
// }

for (let i = 1; i < elements.length; i++) {
// visualize {
elemTracer.select(i);
Tracer.delay();
// }
bstInsert(Root, elements[i]); // insert ith element
// visualize {
elemTracer.deselect(i);
Tracer.delay();
// }
}
14 changes: 14 additions & 0 deletions Branch and Bound/Binary Search Tree/search.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
// import visualization libraries {
const { Tracer, GraphTracer, LogTracer, Randomize, Layout, VerticalLayout } = require('algorithm-visualizer');
// }

const G = [ // G[i][j] indicates whether the path from the i-th node to the j-th node exists or not
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
Expand Down Expand Up @@ -29,33 +31,45 @@ const T = [ // mapping to G as a binary tree , [i][0] indicates left child, [i][
];

const key = Randomize.Integer({ min: 0, max: G.length - 1 }); // item to be searched
// define tracer variables {
const tracer = new GraphTracer(' Binary Search Tree ');
const logger = new LogTracer(' Log ');
Layout.setRoot(new VerticalLayout([tracer, logger]));
tracer.set(G);
tracer.layoutTree(5);
tracer.log(logger);
Tracer.delay();
// }

function bst(item, node, parent) { // node = current node , parent = previous node
// visualize {
tracer.visit(node, parent);
Tracer.delay();
// }
if (item === node) { // key found
// logger {
logger.println(' Match Found ');
// }
} else if (item < node) { // key less than value of current node
if (T[node][0] === -1) {
// logger {
logger.println(' Not Found ');
// }
} else {
bst(item, T[node][0], node);
}
} else { // key greater than value of current node
if (T[node][1] === -1) {
// logger {
logger.println(' Not Found ');
// }
} else {
bst(item, T[node][1], node);
}
}
}

// logger {
logger.println(`Finding number ${key}`);
// }
bst(key, 5); // node with key 5 is the root
16 changes: 16 additions & 0 deletions Branch and Bound/Binary Search/iterative.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
// import visualization libraries {
const { Tracer, Array1DTracer, ChartTracer, LogTracer, Randomize, Layout, VerticalLayout } = require('algorithm-visualizer');
// }

// define tracer variables {
const chart = new ChartTracer();
const tracer = new Array1DTracer();
const logger = new LogTracer();
Expand All @@ -8,6 +11,7 @@ const D = Randomize.Array1D({ N: 15, value: () => Randomize.Integer({ min: 0, ma
tracer.set(D);
tracer.chart(chart);
Tracer.delay();
// }

function BinarySearch(array, element) { // array = sorted array, element = element to be found
let minIndex = 0;
Expand All @@ -18,33 +22,45 @@ function BinarySearch(array, element) { // array = sorted array, element = eleme
const middleIndex = Math.floor((minIndex + maxIndex) / 2);
testElement = array[middleIndex];

// visualize {
tracer.select(minIndex, maxIndex);
Tracer.delay();
tracer.patch(middleIndex);
logger.println(`Searching at index: ${middleIndex}`);
Tracer.delay();
tracer.depatch(middleIndex);
tracer.deselect(minIndex, maxIndex);
// }

if (testElement < element) {
// logger {
logger.println('Going right.');
// }
minIndex = middleIndex + 1;
} else if (testElement > element) {
// logger {
logger.println('Going left.');
// }
maxIndex = middleIndex - 1;
} else {
// visualize {
logger.println(`${element} is found at position ${middleIndex}!`);
tracer.select(middleIndex);
// }

return middleIndex;
}
}

// logger {
logger.println(`${element} is not found!`);
// }
return -1;
}

const element = D[Randomize.Integer({ min: 0, max: D.length - 1 })];

// logger {
logger.println(`Using iterative binary search to find ${element}`);
// }
BinarySearch(D, element);
Loading