diff --git a/README.md b/README.md index 4adb15a..f171ed5 100644 --- a/README.md +++ b/README.md @@ -205,6 +205,28 @@ declare const topologicalSort: (graph: Graph) => Array; Given a [DAG](https://en.wikipedia.org/wiki/Directed_acyclic_graph), returns an array of the graph's vertices sorted using a [topological sort](https://en.wikipedia.org/wiki/Topological_sorting). +### transpose + +```ts +declare const transpose: (graph: Graph) => Graph; +``` + +Flips the orientation of all edges in a directed graph. + +```js +let graph = create(3, (i) => String.fromCharCode(65 + i)); +//=> [Graph] { A, B, C } + +graph = addEdge(graph, ["A", "B"]); +//=> [Graph] { A -> B, C } + +graph = addEdge(graph, ["B", "C"]); +//=> [Graph] { A -> B -> C } + +graph = transpose(graph); +//=> [Graph] { A <- B <- C } +``` + ## Roadmap 1. Interactive demo. diff --git a/index.ts b/index.ts index abda366..3172f65 100644 --- a/index.ts +++ b/index.ts @@ -240,6 +240,22 @@ const topologicalSort = (graph: Graph): Array => { return result; }; +const transpose = (graph: Graph): Graph => { + const adjacencyMatrix: Graph["adjacencyMatrix"] = {}; + + for (let u in graph.adjacencyMatrix) { + adjacencyMatrix[u] = {}; + for (let v in graph.adjacencyMatrix[u]) { + adjacencyMatrix[u][v] = graph.adjacencyMatrix[v][u]; + } + } + + return { + size: graph.size, + adjacencyMatrix, + }; +}; + export { D3Graph, Graph, @@ -254,4 +270,5 @@ export { removeVertex, toD3, topologicalSort, + transpose, }; diff --git a/test.ts b/test.ts index b683247..0f3cdcf 100644 --- a/test.ts +++ b/test.ts @@ -10,6 +10,7 @@ import { removeVertex, toD3, topologicalSort, + transpose, } from "./index"; import test from "tape"; @@ -382,3 +383,77 @@ test("topologicalSort", (t) => { }); }); }); + +test("transpose", (t) => { + t.plan(4); + + t.deepEqual( + transpose({ + size: 1, + adjacencyMatrix: { + a: { a: 0 }, + }, + }), + { + size: 1, + adjacencyMatrix: { + a: { a: 0 }, + }, + }, + ); + + t.deepEqual( + transpose({ + size: 2, + adjacencyMatrix: { + a: { a: 0, b: 1 }, + b: { a: 0, b: 0 }, + }, + }), + { + size: 2, + adjacencyMatrix: { + a: { a: 0, b: 0 }, + b: { a: 1, b: 0 }, + }, + }, + ); + + t.deepEqual( + transpose({ + size: 3, + adjacencyMatrix: { + a: { a: 0, b: 1, c: 1 }, + b: { a: 0, b: 0, c: 1 }, + c: { a: 0, b: 0, c: 0 }, + }, + }), + { + size: 3, + adjacencyMatrix: { + a: { a: 0, b: 0, c: 0 }, + b: { a: 1, b: 0, c: 0 }, + c: { a: 1, b: 1, c: 0 }, + }, + }, + ); + + t.deepEqual( + transpose({ + size: 3, + adjacencyMatrix: { + a: { a: 1, b: 1, c: 1 }, + b: { a: 1, b: 1, c: 1 }, + c: { a: 1, b: 1, c: 1 }, + }, + }), + { + size: 3, + adjacencyMatrix: { + a: { a: 1, b: 1, c: 1 }, + b: { a: 1, b: 1, c: 1 }, + c: { a: 1, b: 1, c: 1 }, + }, + }, + ); +});