@gabrielrufino/cube
Version:
Data structures made in Typescript
183 lines (182 loc) • 7.79 kB
JavaScript
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var Dictionary_1 = __importDefault(require("../Dictionary"));
var Queue_1 = __importDefault(require("../Queue"));
var Set_1 = __importDefault(require("../Set"));
var GraphNodeNotFoundError_1 = __importDefault(require("./GraphNodeNotFoundError"));
var GraphSearchNodeStates_1 = __importDefault(require("./GraphSearchNodeStates"));
var Graph = /** @class */ (function () {
function Graph(_a) {
var _b = _a === void 0 ? {} : _a, _c = _b.inputs, inputs = _c === void 0 ? {} : _c, _d = _b.isDirected, isDirected = _d === void 0 ? false : _d;
this._isDirected = isDirected;
this._data = new Dictionary_1.default();
var nodes = Object.keys(inputs);
for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) {
var node = nodes_1[_i];
this.insert(node);
}
for (var _e = 0, nodes_2 = nodes; _e < nodes_2.length; _e++) {
var node = nodes_2[_e];
for (var _f = 0, _g = inputs[node]; _f < _g.length; _f++) {
var value = _g[_f];
this.connect(node, value);
}
}
}
Object.defineProperty(Graph.prototype, "isDirected", {
get: function () {
return this._isDirected;
},
enumerable: false,
configurable: true
});
Object.defineProperty(Graph.prototype, "data", {
get: function () {
return Object.entries(this._data.data)
.reduce(function (accumulator, _a) {
var _b;
var key = _a[0], value = _a[1];
return (__assign(__assign({}, accumulator), (_b = {}, _b[key] = value.data, _b)));
}, {});
},
enumerable: false,
configurable: true
});
Object.defineProperty(Graph.prototype, "size", {
get: function () {
return this._data.size;
},
enumerable: false,
configurable: true
});
Object.defineProperty(Graph.prototype, "nodes", {
get: function () {
return __spreadArray([], this._data.keys, true);
},
enumerable: false,
configurable: true
});
Object.defineProperty(Graph.prototype, "edges", {
get: function () {
if (this.isDirected) {
return Object.entries(this.data)
.flatMap(function (_a) {
var node = _a[0], links = _a[1];
return links.map(function (link) { return [node, link]; });
});
}
return Object.entries(this.data)
.reduce(function (accumulator, _a) {
var node = _a[0], links = _a[1];
var edges = links
.map(function (link) { return [node, link]; })
.filter(function (edge) { return !accumulator.find(function (item) { return item.includes(edge[0]) && item.includes(edge[1]); }); });
return __spreadArray(__spreadArray([], accumulator, true), edges, true);
}, []);
},
enumerable: false,
configurable: true
});
Graph.prototype.insert = function (node) {
if (this._data.hasKey(node)) {
return null;
}
this._data.set(node, new Set_1.default());
return node;
};
Graph.prototype.connect = function (node1, node2) {
if (!this._data.hasKey(node1)) {
throw new GraphNodeNotFoundError_1.default(node1);
}
if (!this._data.hasKey(node2)) {
throw new GraphNodeNotFoundError_1.default(node2);
}
this._data.get(node1).add(node2);
if (!this._isDirected) {
this._data.get(node2).add(node1);
}
return [node1, node2];
};
Graph.prototype.breadthFirstSearch = function (startNode, callback) {
var _a;
if (!this._data.hasKey(startNode)) {
throw new GraphNodeNotFoundError_1.default(startNode);
}
var nodes = this.nodes;
var states = nodes.reduce(function (accumulator, node) {
var _a;
return (__assign(__assign({}, accumulator), (_a = {}, _a[node] = GraphSearchNodeStates_1.default.UNEXPLORED, _a)));
}, {});
var queue = new Queue_1.default();
queue.enqueue(startNode);
while (!queue.isEmpty) {
var current = queue.dequeue();
states[current] = GraphSearchNodeStates_1.default.DISCOVERED;
var neighbors = (_a = this._data.get(current)) === null || _a === void 0 ? void 0 : _a.data;
var unexploredNeighbors = neighbors.filter(function (neighbor) { return states[neighbor] === GraphSearchNodeStates_1.default.UNEXPLORED; });
for (var _i = 0, unexploredNeighbors_1 = unexploredNeighbors; _i < unexploredNeighbors_1.length; _i++) {
var neighbor = unexploredNeighbors_1[_i];
states[neighbor] = GraphSearchNodeStates_1.default.DISCOVERED;
queue.enqueue(neighbor);
}
states[current] = GraphSearchNodeStates_1.default.EXPLORED;
callback(current);
}
};
Graph.prototype.getDistancesFrom = function (node) {
var _a;
if (!this._data.hasKey(node)) {
throw new GraphNodeNotFoundError_1.default(node);
}
var nodes = this.nodes;
var states = nodes.reduce(function (accumulator, node) {
var _a;
return (__assign(__assign({}, accumulator), (_a = {}, _a[node] = GraphSearchNodeStates_1.default.UNEXPLORED, _a)));
}, {});
var distances = nodes.reduce(function (accumulator, node) {
var _a;
return (__assign(__assign({}, accumulator), (_a = {}, _a[node] = 0, _a)));
}, {});
var queue = new Queue_1.default();
queue.enqueue(node);
while (!queue.isEmpty) {
var current = queue.dequeue();
states[current] = GraphSearchNodeStates_1.default.DISCOVERED;
var neighbors = (_a = this._data.get(current)) === null || _a === void 0 ? void 0 : _a.data;
var unexploredNeighbors = neighbors.filter(function (neighbor) { return states[neighbor] === GraphSearchNodeStates_1.default.UNEXPLORED; });
for (var _i = 0, unexploredNeighbors_2 = unexploredNeighbors; _i < unexploredNeighbors_2.length; _i++) {
var neighbor = unexploredNeighbors_2[_i];
states[neighbor] = GraphSearchNodeStates_1.default.DISCOVERED;
distances[neighbor] = distances[current] + 1;
queue.enqueue(neighbor);
}
states[current] = GraphSearchNodeStates_1.default.EXPLORED;
}
return distances;
};
return Graph;
}());
exports.default = Graph;