-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
154 changed files
with
7,849 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,4 @@ | ||
node_modules | ||
built | ||
dist | ||
tmp | ||
|
||
|
146 changes: 146 additions & 0 deletions
146
packages/scanner/built/algorithms/dataStructures/graph/Graph.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
class Graph { | ||
/** | ||
* @param {boolean} isDirected | ||
*/ | ||
constructor(isDirected = false) { | ||
this.vertices = {}; | ||
this.edges = {}; | ||
this.vertices = {}; | ||
this.edges = {}; | ||
this.isDirected = isDirected; | ||
} | ||
get vertexCount() { | ||
return Object.keys(this.vertices).length; | ||
} | ||
addVertex(newVertex) { | ||
this.vertices[newVertex.getKey()] = newVertex; | ||
return this; | ||
} | ||
getVertexByKey(vertexKey) { | ||
return this.vertices[vertexKey]; | ||
} | ||
getNeighbors(vertex) { | ||
return vertex.getNeighbors(); | ||
} | ||
getAllVertices() { | ||
return Object.values(this.vertices); | ||
} | ||
getAllEdges() { | ||
return Object.values(this.edges); | ||
} | ||
addEdge(edge) { | ||
// Try to find and end start vertices. | ||
let startVertex = this.getVertexByKey(edge.startVertex.getKey()); | ||
let endVertex = this.getVertexByKey(edge.endVertex.getKey()); | ||
// Insert start vertex if it wasn't inserted. | ||
if (!startVertex) { | ||
this.addVertex(edge.startVertex); | ||
startVertex = this.getVertexByKey(edge.startVertex.getKey()); | ||
} | ||
// Insert end vertex if it wasn't inserted. | ||
if (!endVertex) { | ||
this.addVertex(edge.endVertex); | ||
endVertex = this.getVertexByKey(edge.endVertex.getKey()); | ||
} | ||
// Check if edge has been already added. | ||
if (this.edges[edge.getKey()]) { | ||
throw new Error('Edge has already been added before'); | ||
} | ||
else { | ||
this.edges[edge.getKey()] = edge; | ||
} | ||
// Add edge to the vertices. | ||
if (this.isDirected) { | ||
// If graph IS directed then add the edge only to start vertex. | ||
startVertex.addEdge(edge); | ||
} | ||
else { | ||
// If graph ISN'T directed then add the edge to both vertices. | ||
startVertex.addEdge(edge); | ||
endVertex.addEdge(edge); | ||
} | ||
return this; | ||
} | ||
deleteEdge(edge) { | ||
// Delete edge from the list of edges. | ||
if (this.edges[edge.getKey()]) { | ||
delete this.edges[edge.getKey()]; | ||
} | ||
else { | ||
throw new Error('Edge not found in graph'); | ||
} | ||
// Try to find and end start vertices and delete edge from them. | ||
const startVertex = this.getVertexByKey(edge.startVertex.getKey()); | ||
const endVertex = this.getVertexByKey(edge.endVertex.getKey()); | ||
if (startVertex) { | ||
startVertex.deleteEdge(edge); | ||
} | ||
if (endVertex) { | ||
endVertex.deleteEdge(edge); | ||
} | ||
} | ||
findEdge(startVertex, endVertex) { | ||
const vertex = this.getVertexByKey(startVertex.getKey()); | ||
if (!vertex) { | ||
return null; | ||
} | ||
return vertex.findEdge(endVertex); | ||
} | ||
findVertexByKey(vertexKey) { | ||
if (this.vertices[vertexKey]) { | ||
return this.vertices[vertexKey]; | ||
} | ||
return null; | ||
} | ||
getWeight() { | ||
return this.getAllEdges().reduce((weight, graphEdge) => { | ||
return weight + graphEdge.weight; | ||
}, 0); | ||
} | ||
/** | ||
* Reverse all the edges in directed graph. | ||
*/ | ||
reverse() { | ||
this.getAllEdges().forEach((edge) => { | ||
// Delete straight edge from graph and from vertices. | ||
this.deleteEdge(edge); | ||
// Reverse the edge. | ||
edge.reverse(); | ||
// Add reversed edge back to the graph and its vertices. | ||
this.addEdge(edge); | ||
}); | ||
return this; | ||
} | ||
getVerticesIndices() { | ||
const verticesIndices = {}; | ||
this.getAllVertices().forEach((vertex, index) => { | ||
verticesIndices[vertex.getKey()] = index; | ||
}); | ||
return verticesIndices; | ||
} | ||
getAdjacencyMatrix() { | ||
const vertices = this.getAllVertices(); | ||
const verticesIndices = this.getVerticesIndices(); | ||
// Init matrix with infinities meaning that there is no ways of | ||
// getting from one vertex to another yet. | ||
const adjacencyMatrix = Array(vertices.length) | ||
.fill(null) | ||
.map(() => { | ||
return Array(vertices.length).fill(Infinity); | ||
}); | ||
// Fill the columns. | ||
vertices.forEach((vertex, vertexIndex) => { | ||
vertex.getNeighbors().forEach((neighbor) => { | ||
const neighborIndex = verticesIndices[neighbor.getKey()]; | ||
adjacencyMatrix[vertexIndex][neighborIndex] = this.findEdge(vertex, neighbor).weight; | ||
}); | ||
}); | ||
return adjacencyMatrix; | ||
} | ||
toString() { | ||
return Object.keys(this.vertices).toString(); | ||
} | ||
} | ||
exports.default = Graph; |
24 changes: 24 additions & 0 deletions
24
packages/scanner/built/algorithms/dataStructures/graph/GraphEdge.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
class GraphEdge { | ||
constructor(startVertex, endVertex, weight = 0) { | ||
this.startVertex = startVertex; | ||
this.endVertex = endVertex; | ||
this.weight = weight; | ||
} | ||
getKey() { | ||
const startVertexKey = this.startVertex.getKey(); | ||
const endVertexKey = this.endVertex.getKey(); | ||
return `${startVertexKey} - ${endVertexKey}`; | ||
} | ||
reverse() { | ||
const tmp = this.startVertex; | ||
this.startVertex = this.endVertex; | ||
this.endVertex = tmp; | ||
return this; | ||
} | ||
toString() { | ||
return this.getKey(); | ||
} | ||
} | ||
exports.default = GraphEdge; |
74 changes: 74 additions & 0 deletions
74
packages/scanner/built/algorithms/dataStructures/graph/GraphVertex.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const LinkedList_1 = __importDefault(require("../linked-list/LinkedList")); | ||
class GraphVertex { | ||
/** | ||
* @param {*} value | ||
*/ | ||
constructor(value) { | ||
if (value === '') { | ||
throw new Error('Graph vertex must have a non-empty value'); | ||
} | ||
const edgeComparator = (edgeA, edgeB) => { | ||
if (edgeA.getKey() === edgeB.getKey()) { | ||
return 0; | ||
} | ||
return edgeA.getKey() < edgeB.getKey() ? -1 : 1; | ||
}; | ||
// Normally you would store string value like vertex name. | ||
// But generally it may be any object as well | ||
this.value = value; | ||
this.edges = new LinkedList_1.default(edgeComparator); | ||
} | ||
addEdge(edge) { | ||
this.edges.append(edge); | ||
return this; | ||
} | ||
deleteEdge(edge) { | ||
this.edges.delete(edge); | ||
} | ||
getNeighbors() { | ||
const edges = this.edges.toArray(); | ||
const neighborsConverter = (node) => { | ||
return node.value.startVertex === this ? node.value.endVertex : node.value.startVertex; | ||
}; | ||
// Return either start or end vertex. | ||
// For undirected graphs it is possible that current vertex will be the end one. | ||
return edges.map(neighborsConverter); | ||
} | ||
getEdges() { | ||
return this.edges.toArray().map((linkedListNode) => linkedListNode.value); | ||
} | ||
getDegree() { | ||
return this.edges.toArray().length; | ||
} | ||
hasEdge(requiredEdge) { | ||
const edgeNode = this.edges.find(undefined, (edge) => edge === requiredEdge); | ||
return !!edgeNode; | ||
} | ||
hasNeighbor(vertex) { | ||
const vertexNode = this.edges.find(undefined, (edge) => edge.startVertex === vertex || edge.endVertex === vertex); | ||
return !!vertexNode; | ||
} | ||
findEdge(vertex) { | ||
const edgeFinder = (edge) => { | ||
return edge.startVertex === vertex || edge.endVertex === vertex; | ||
}; | ||
const edge = this.edges.find(undefined, edgeFinder); | ||
return edge ? edge.value : null; | ||
} | ||
getKey() { | ||
return this.value; | ||
} | ||
deleteAllEdges() { | ||
this.getEdges().forEach((edge) => this.deleteEdge(edge)); | ||
return this; | ||
} | ||
toString(callback = undefined) { | ||
return callback ? callback(this.value) : `${this.value}`; | ||
} | ||
} | ||
exports.default = GraphVertex; |
129 changes: 129 additions & 0 deletions
129
packages/scanner/built/algorithms/dataStructures/linked-list/LinkedList.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const LinkedListNode_1 = __importDefault(require("./LinkedListNode")); | ||
const Comparator_1 = __importDefault(require("../../utils/Comparator")); | ||
class LinkedList { | ||
constructor(comparatorFunction) { | ||
this.head = null; | ||
this.tail = null; | ||
this.compare = new Comparator_1.default(comparatorFunction); | ||
} | ||
prepend(value) { | ||
// Make new node to be a head. | ||
this.head = new LinkedListNode_1.default(value, this.head); | ||
return this; | ||
} | ||
append(value) { | ||
const newNode = new LinkedListNode_1.default(value); | ||
// If there is no head yet let's make new node a head. | ||
if (!this.head) { | ||
this.head = newNode; | ||
this.tail = newNode; | ||
return this; | ||
} | ||
// Attach new node to the end of linked list. | ||
this.tail.next = newNode; | ||
this.tail = newNode; | ||
return this; | ||
} | ||
delete(value) { | ||
if (!this.head) { | ||
return null; | ||
} | ||
let deletedNode = null; | ||
// If the head must be deleted then make 2nd node to be a head. | ||
while (this.head && this.compare.equal(this.head.value, value)) { | ||
deletedNode = this.head; | ||
this.head = this.head.next; | ||
} | ||
let currentNode = this.head; | ||
if (currentNode !== null) { | ||
// If next node must be deleted then make next node to be a next next one. | ||
while (currentNode.next) { | ||
if (this.compare.equal(currentNode.next.value, value)) { | ||
deletedNode = currentNode.next; | ||
currentNode.next = currentNode.next.next; | ||
} | ||
else { | ||
currentNode = currentNode.next; | ||
} | ||
} | ||
} | ||
// Check if tail must be deleted. | ||
if (this.compare.equal(this.tail.value, value)) { | ||
this.tail = currentNode; | ||
} | ||
return deletedNode; | ||
} | ||
find(value = undefined, callback = undefined) { | ||
if (!this.head) { | ||
return null; | ||
} | ||
let currentNode = this.head; | ||
while (currentNode) { | ||
// If callback is specified then try to find node by callback. | ||
if (callback && callback(currentNode.value)) { | ||
return currentNode; | ||
} | ||
// If value is specified then try to compare by value.. | ||
if (value !== undefined && this.compare.equal(currentNode.value, value)) { | ||
return currentNode; | ||
} | ||
currentNode = currentNode.next; | ||
} | ||
return null; | ||
} | ||
deleteTail() { | ||
if (this.head === this.tail) { | ||
const deletedTail = this.tail; | ||
this.head = null; | ||
this.tail = null; | ||
return deletedTail; | ||
} | ||
const deletedTail = this.tail; | ||
// Rewind to the last node and delete "next" link for the node before the last one. | ||
let currentNode = this.head; | ||
while (currentNode.next) { | ||
if (!currentNode.next.next) { | ||
currentNode.next = null; | ||
} | ||
else { | ||
currentNode = currentNode.next; | ||
} | ||
} | ||
this.tail = currentNode; | ||
return deletedTail; | ||
} | ||
deleteHead() { | ||
if (!this.head) { | ||
return null; | ||
} | ||
const deletedHead = this.head; | ||
if (this.head.next) { | ||
this.head = this.head.next; | ||
} | ||
else { | ||
this.head = null; | ||
this.tail = null; | ||
} | ||
return deletedHead; | ||
} | ||
toArray() { | ||
const nodes = []; | ||
let currentNode = this.head; | ||
while (currentNode) { | ||
nodes.push(currentNode); | ||
currentNode = currentNode.next; | ||
} | ||
return nodes; | ||
} | ||
toString(callback = undefined) { | ||
return this.toArray() | ||
.map((node) => node.toString(callback)) | ||
.toString(); | ||
} | ||
} | ||
exports.default = LinkedList; |
12 changes: 12 additions & 0 deletions
12
packages/scanner/built/algorithms/dataStructures/linked-list/LinkedListNode.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
class LinkedListNode { | ||
constructor(value, next = null) { | ||
this.value = value; | ||
this.next = next; | ||
} | ||
toString(callback = undefined) { | ||
return callback ? callback(this.value) : `${this.value}`; | ||
} | ||
} | ||
exports.default = LinkedListNode; |
Oops, something went wrong.