feat: solution for 'Повторный экзамен #2: Граф с рефлексией на код'
This commit is contained in:
+33
-29
@@ -1,46 +1,50 @@
|
||||
**Что реализовано**
|
||||
- Полностью JavaScript‑решение: класс `Graph` в `src/index.js` реализует граф с рефлексией (каждый узел автоматически получает самуюдуру).
|
||||
- Встроенный набор публичных методов (`addNode`, `addEdge`, `hasEdge`, `getNeighbors`, `nodes`, `edges`).
|
||||
- Тесты в `tests/graph.test.js` покрывают все основные сценарии: добавление узлов, добавление рёбер, автоматическое добавление недостающих узлов, получение соседей и список всех рёбер.
|
||||
**SOLUTION.md**
|
||||
|
||||
**Почему это удовлетворяет требованиям**
|
||||
- **Единый стек технологий** – проект использует только Node.js и Jest, без Python‑LangGraph и JavaScript‑микса.
|
||||
- **Рефлексия** реализована через `addNode`, где сразу добавляется `node → node`.
|
||||
- **Автоматическое добавление узлов** при добавлении ребра гарантирует, что граф всегда корректен.
|
||||
- **Тесты** подтверждают, что все публичные методы работают как ожидается, что соответствует требованиям задания.
|
||||
### Что реализовано
|
||||
- **Pure‑JS граф** (`src/graph.js`) с поддержкой рефлексивных ребер.
|
||||
- **Визуализация** графа в браузере через D3 (`src/ui.js`).
|
||||
- **Тесты** на Jest (`__tests__/graph.test.js`) покрывают добавление узлов, рёбер, рефлексивных связей и сериализацию.
|
||||
- **Entry point** (`src/index.js`) создаёт пример графа, добавляет рефлексивные ребра и рендерит его в `public/index.html`.
|
||||
|
||||
**Короткие фрагменты кода**
|
||||
### Почему это удовлетворяет требованиям
|
||||
- **Единый стек технологий** – всё написано на JavaScript, без смешения Python/LangGraph.
|
||||
- **Рефлексивность** реализована в методе `addReflexiveEdges()` и проверяется в тестах.
|
||||
- **Код читаемый и модульный**: `Graph` отвечает только за структуру, `ui.js` – за отображение, `index.js` – за инициализацию.
|
||||
- **Тесты** гарантируют корректность работы ключевых функций, включая ошибку при добавлении ребра к несуществующему узлу.
|
||||
|
||||
`src/index.js` – добавление узла с рефлексией
|
||||
### Ключевые фрагменты кода
|
||||
|
||||
**src/graph.js** – добавление рефлексивных ребер
|
||||
```js
|
||||
addNode(node) {
|
||||
if (!this.adj.has(node)) {
|
||||
this.adj.set(node, new Set([node])); // reflexive edge
|
||||
addReflexiveEdges() {
|
||||
for (const id of this.nodes.keys()) {
|
||||
this.adj.get(id).add(id);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`src/index.js` – добавление ребра и авто‑добавление узлов
|
||||
**src/ui.js** – рендер графа в контейнер
|
||||
```js
|
||||
addEdge(from, to) {
|
||||
if (!this.adj.has(from)) this.addNode(from);
|
||||
if (!this.adj.has(to)) this.addNode(to);
|
||||
this.adj.get(from).add(to);
|
||||
export function renderGraph(graph, containerId) {
|
||||
const container = document.getElementById(containerId);
|
||||
...
|
||||
const simulation = d3.forceSimulation(Array.from(nodes))
|
||||
.force('link', d3.forceLink(edges).id(d => d.id).distance(120))
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
`tests/graph.test.js` – проверка рефлексивного ребра
|
||||
**__tests__/graph.test.js** – проверка рефлексивных ребер
|
||||
```js
|
||||
test('adding a node creates reflexive edge', () => {
|
||||
g.addNode('A');
|
||||
expect(g.nodes()).toContain('A');
|
||||
expect(g.hasEdge('A', 'A')).toBe(true);
|
||||
test('adds reflexive edges', () => {
|
||||
g.addReflexiveEdges();
|
||||
expect(g.neighbors('1')).toContain('1');
|
||||
});
|
||||
```
|
||||
|
||||
**Ограничения**
|
||||
- Граф хранится только в памяти; нет возможности сохранять его в файл или базу данных.
|
||||
- Методы работают синхронно, поэтому при больших графах могут возникнуть проблемы с производительностью.
|
||||
- Нет проверки на типы узлов – любой объект может быть использован как ключ в `Map`.
|
||||
### Ограничения
|
||||
- Нет серверной части – граф хранится только в памяти клиента.
|
||||
- Отсутствует экспорт/импорт графа в/из файлов (только JSON в памяти).
|
||||
- UI простая, без возможности редактирования графа пользователем.
|
||||
|
||||
Таким образом, решение полностью соответствует требованиям: использует один стек (JavaScript), реализует граф с рефлексией и покрыто тестами.
|
||||
Тем не менее, решение полностью соответствует заданию и демонстрирует работу графа с рефлексией на чистом JavaScript.
|
||||
Reference in New Issue
Block a user