68 lines
2.8 KiB
Markdown
68 lines
2.8 KiB
Markdown
**What was implemented**
|
||
- Added a `ReflectionNode` class that can duplicate the outgoing edges of a target node (`reflect` method).
|
||
- Added a `RewritingNode` class that can replace a target node with a new one (`rewrite` method).
|
||
- Extended `Graph` with `replaceNode` to preserve edges during a rewrite and `traverse` for DFS traversal.
|
||
|
||
**Why the main parts satisfy the requirements**
|
||
- The assignment explicitly asks for “узлы рефлексии и переписывания”.
|
||
- `ReflectionNode.reflect` creates a new node (`${targetId}_ref`) and copies all edges from the original target, ensuring the reflected node behaves like the original.
|
||
- `RewritingNode.rewrite` calls `Graph.replaceNode`, which removes the old node, rewires all incoming edges to the new node, and keeps the outgoing edges intact.
|
||
- Tests confirm that reflected nodes exist, have the correct type, and preserve edges; that rewriting removes the old node and connects the new one; and that traversal still visits all nodes without duplication.
|
||
|
||
**Short code excerpts**
|
||
|
||
*src/index.js – ReflectionNode*
|
||
```js
|
||
class ReflectionNode extends Node {
|
||
reflect(graph) {
|
||
const targets = graph.edges.get(this.id) || new Set();
|
||
for (const targetId of targets) {
|
||
const targetNode = graph.getNode(targetId);
|
||
if (!targetNode) continue;
|
||
const newId = `${targetId}_ref`;
|
||
if (graph.getNode(newId)) continue;
|
||
const newNode = new Node(newId, targetNode.type);
|
||
graph.addNode(newNode);
|
||
const targetTargets = graph.edges.get(targetId) || new Set();
|
||
for (const tt of targetTargets) {
|
||
graph.addEdge(newId, tt);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
*src/index.js – RewritingNode*
|
||
```js
|
||
class RewritingNode extends Node {
|
||
rewrite(graph, targetId, newNode) {
|
||
graph.replaceNode(targetId, newNode);
|
||
}
|
||
}
|
||
```
|
||
|
||
*src/index.js – Graph.replaceNode*
|
||
```js
|
||
replaceNode(oldId, newNode) {
|
||
const oldTargets = this.edges.get(oldId) ? new Set(this.edges.get(oldId)) : new Set();
|
||
this.edges.delete(oldId);
|
||
this.nodes.delete(oldId);
|
||
this.addNode(newNode);
|
||
for (const [from, targets] of this.edges.entries()) {
|
||
if (targets.has(oldId)) {
|
||
targets.delete(oldId);
|
||
targets.add(newNode.id);
|
||
}
|
||
}
|
||
for (const target of oldTargets) {
|
||
this.addEdge(newNode.id, target);
|
||
}
|
||
}
|
||
```
|
||
|
||
**Honest limitations**
|
||
- Reflection only copies outgoing edges; incoming edges to the original node are not duplicated.
|
||
- `replaceNode` rewires edges but does not detect or handle cycles that could arise during a rewrite.
|
||
- The DFS traversal is simple and may not be optimal for very large graphs, but it suffices for the assignment’s test cases.
|
||
|
||
These additions bring the solution in line with the assignment’s requirement to include reflection and rewriting nodes. |