feat: solution for 'Повторный экзамен #2: Граф с рефлексией на код'

This commit is contained in:
2026-06-30 17:00:41 +03:00
parent 898f43bf73
commit 7832ec4f07
4 changed files with 193 additions and 120 deletions
+82 -4
View File
@@ -1,5 +1,83 @@
const Graph = require('./graph');
class Graph {
constructor() {
this.adj = new Map();
this[Graph._logSymbol] = [];
}
module.exports = {
Graph
};
addNode(node) {
if (!this.adj.has(node)) {
this.adj.set(node, new Set());
}
}
addEdge(u, v) {
if (!this.adj.has(u)) this.adj.set(u, new Set());
if (!this.adj.has(v)) this.adj.set(v, new Set());
const uSet = this.adj.get(u);
const vSet = this.adj.get(v);
if (!uSet.has(v)) {
uSet.add(v);
vSet.add(u);
}
}
removeNode(node) {
if (!this.adj.has(node)) return;
for (const neighbor of this.adj.get(node)) {
this.adj.get(neighbor).delete(node);
}
this.adj.delete(node);
}
removeEdge(u, v) {
if (this.adj.has(u)) this.adj.get(u).delete(v);
if (this.adj.has(v)) this.adj.get(v).delete(u);
}
getNeighbors(node) {
return this.adj.has(node) ? Array.from(this.adj.get(node)) : [];
}
hasEdge(u, v) {
return this.adj.has(u) && this.adj.get(u).has(v);
}
getNodes() {
return Array.from(this.adj.keys());
}
getLog() {
return this[Graph._logSymbol].slice();
}
}
Graph._logSymbol = Symbol('log');
function createGraph() {
const graph = new Graph();
const handler = {
get(target, prop, receiver) {
const value = target[prop];
if (typeof value === 'function') {
// Mutating methods that should be logged
if (['addNode', 'addEdge', 'removeNode', 'removeEdge'].includes(prop)) {
return function (...args) {
const result = value.apply(target, args);
target[Graph._logSymbol].push({ method: prop, args });
return result;
};
}
// Non-mutating methods (including getLog)
return value.bind(target);
}
return value;
},
};
return new Proxy(graph, handler);
}
module.exports = { Graph, createGraph };