Skip to content

Commit

Permalink
Merge pull request #526 from vaskoz/day255
Browse files Browse the repository at this point in the history
Day255
  • Loading branch information
vaskoz committed May 4, 2019
2 parents 56e38f6 + 3cc0390 commit 0326ccf
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -265,3 +265,4 @@ problems from
* [Day 252](https://github.com/vaskoz/dailycodingproblem-go/issues/519)
* [Day 253](https://github.com/vaskoz/dailycodingproblem-go/issues/521)
* [Day 254](https://github.com/vaskoz/dailycodingproblem-go/issues/523)
* [Day 255](https://github.com/vaskoz/dailycodingproblem-go/issues/525)
49 changes: 49 additions & 0 deletions day255/problem.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package day255

// Graph is an integer based ajacency matrix.
type Graph map[int][]int

// TransitiveClosure returns the transitive closure
// matrix.
func TransitiveClosure(g Graph) [][]int {
var largest int
for start, ends := range g {
if start > largest {
largest = start
}
for _, node := range ends {
if node > largest {
largest = node
}
}
}
result := make([][]int, largest+1)
for i := range result {
result[i] = make([]int, largest+1)
}
visited := make(map[int]struct{}, largest+1)
result = transitiveClosure(-1, g, result, visited)
return result
}

func transitiveClosure(node int, g Graph, result [][]int, visited map[int]struct{}) [][]int {
if node == -1 {
for start := range g {
result = transitiveClosure(start, g, result, visited)
}
} else {
for start := range visited {
result[start][node] = 1
}
visited[node] = struct{}{}
for _, n := range g[node] {
if n == node {
result[node][n] = 1
} else if _, found := visited[n]; !found {
result = transitiveClosure(n, g, result, visited)
}
}
delete(visited, node)
}
return result
}
72 changes: 72 additions & 0 deletions day255/problem_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package day255

import (
"reflect"
"testing"
)

// nolint
var testcases = []struct {
g Graph
expected [][]int
}{
{
Graph{
0: {0, 1, 3},
1: {1, 2},
2: {2},
3: {3},
},
[][]int{
{1, 1, 1, 1},
{0, 1, 1, 0},
{0, 0, 1, 0},
{0, 0, 0, 1},
},
},
{
Graph{
0: {1, 3},
1: {2},
2: {},
3: {},
},
[][]int{
{0, 1, 1, 1},
{0, 0, 1, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
},
},
{
Graph{
0: {1, 3},
1: {2},
2: {3},
3: {2},
},
[][]int{
{0, 1, 1, 1},
{0, 0, 1, 1},
{0, 0, 0, 1},
{0, 0, 1, 0},
},
},
}

func TestTransitiveClosure(t *testing.T) {
t.Parallel()
for _, tc := range testcases {
if result := TransitiveClosure(tc.g); !reflect.DeepEqual(result, tc.expected) {
t.Errorf("Expected %v, got %v", tc.expected, result)
}
}
}

func BenchmarkTransitiveClosure(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, tc := range testcases {
TransitiveClosure(tc.g)
}
}
}

0 comments on commit 0326ccf

Please sign in to comment.