Skip to content

Commit

Permalink
Merge pull request #581 from vaskoz/day262
Browse files Browse the repository at this point in the history
Day262
  • Loading branch information
vaskoz committed Jun 3, 2019
2 parents cff45a7 + b1e75cc commit 3b3f114
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ problems from
* [Day 259](https://github.com/vaskoz/dailycodingproblem-go/issues/531)
* [Day 260](https://github.com/vaskoz/dailycodingproblem-go/issues/533)
* [Day 261](https://github.com/vaskoz/dailycodingproblem-go/issues/534)
* [Day 262](https://github.com/vaskoz/dailycodingproblem-go/issues/538)
* [Day 263](https://github.com/vaskoz/dailycodingproblem-go/issues/539)
* [Day 266](https://github.com/vaskoz/dailycodingproblem-go/issues/542)
* [Day 267](https://github.com/vaskoz/dailycodingproblem-go/issues/543)
Expand Down
68 changes: 68 additions & 0 deletions day262/problem.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package day262

// Edge is an undirected edge from a Start node to an End node.
type Edge struct {
Start, End int
}

// undirectedGraph is an undirected graph.
// Edges will be inserted as 2-directed edges in opposite directions.
type undirectedGraph map[int]map[int]struct{}

// FindAllBridges returns all bridges in a given UndirectedGraph.
func FindAllBridges(edges []Edge) []Edge {
graph := make(undirectedGraph)
for _, e := range edges {
if _, found := graph[e.Start]; !found {
graph[e.Start] = make(map[int]struct{})
}
if _, found := graph[e.End]; !found {
graph[e.End] = make(map[int]struct{})
}
graph[e.Start][e.End] = struct{}{}
graph[e.End][e.Start] = struct{}{}
}
visited := make([]bool, len(graph))
disc := make([]int, len(graph))
low := make([]int, len(graph))
parent := make([]int, len(graph))
for i := range disc {
disc[i] = int(^uint(0) >> 1)
low[i] = int(^uint(0) >> 1)
parent[i] = -1
}
var result []Edge
for i := range visited {
if !visited[i] {
result = findAllBridges(graph, i, 0, visited, parent, low, disc, result)
}
}
return result
}

func findAllBridges(graph undirectedGraph, u, time int, visited []bool, parent, low, disc []int, result []Edge) []Edge {
visited[u] = true
disc[u] = time
low[u] = time
time++
for v := range graph[u] {
if !visited[v] {
parent[v] = u
result = findAllBridges(graph, v, time, visited, parent, low, disc, result)
low[u] = min(low[u], low[v])
if low[v] > disc[u] {
result = append(result, Edge{u, v})
}
} else if v != parent[u] {
low[u] = min(low[u], disc[v])
}
}
return result
}

func min(a, b int) int {
if a < b {
return a
}
return b
}
42 changes: 42 additions & 0 deletions day262/problem_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package day262

import (
"reflect"
"testing"
)

// nolint
var testcases = []struct {
graph []Edge
bridges []Edge
}{
{
[]Edge{{1, 0}, {0, 2}, {2, 1}, {0, 3}, {3, 4}},
[]Edge{{3, 4}, {0, 3}},
},
{
[]Edge{{0, 1}, {1, 2}, {2, 3}},
[]Edge{{2, 3}, {1, 2}, {0, 1}},
},
{
[]Edge{{0, 1}, {1, 2}, {2, 0}, {1, 3}, {1, 4}, {1, 6}, {3, 5}, {4, 5}},
[]Edge{{1, 6}},
},
}

func TestFindAllBridges(t *testing.T) {
t.Parallel()
for _, tc := range testcases {
if bridges := FindAllBridges(tc.graph); !reflect.DeepEqual(bridges, tc.bridges) {
t.Errorf("Expected %v, got %v", tc.bridges, bridges)
}
}
}

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

0 comments on commit 3b3f114

Please sign in to comment.