2018-12-10 04:46:35 +00:00
|
|
|
// BreadthFirstOrder and its companion functions ended up not giving the
|
|
|
|
// right solution, but I'm leaving them here as a useful generic tree
|
|
|
|
// algorithm.
|
2018-12-10 06:06:47 +00:00
|
|
|
package day07
|
2018-12-10 04:46:35 +00:00
|
|
|
|
|
|
|
func BreadthFirstOrder(root *Node) []*Node {
|
|
|
|
seen := make(map[rune]bool)
|
|
|
|
return breadthFirstOrderR(root, seen)
|
|
|
|
}
|
|
|
|
|
|
|
|
func findTreeRoot(depMap map[rune]*Node) *Node {
|
|
|
|
for _, node := range depMap {
|
|
|
|
if len(node.Parents) == 0 {
|
|
|
|
return node
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func breadthFirstOrderR(node *Node, seen map[rune]bool) []*Node {
|
|
|
|
order := []*Node{}
|
|
|
|
|
|
|
|
// handle root
|
|
|
|
if len(node.Parents) == 0 {
|
|
|
|
order = append(order, node)
|
|
|
|
seen[node.Name] = true
|
|
|
|
}
|
|
|
|
|
|
|
|
// add children we haven't seen before
|
|
|
|
for _, child := range node.Children {
|
|
|
|
if _, ok := seen[child.Name]; !ok {
|
|
|
|
order = append(order, child)
|
|
|
|
seen[child.Name] = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// recurse
|
|
|
|
for _, child := range node.Children {
|
|
|
|
order = append(order, breadthFirstOrderR(child, seen)...)
|
|
|
|
}
|
|
|
|
|
|
|
|
return order
|
|
|
|
}
|