2018-12-10 06:06:47 +00:00
|
|
|
package day07
|
2018-12-10 04:46:35 +00:00
|
|
|
|
|
|
|
// FindOrder determines the correct order according to these rules:
|
|
|
|
// 1. A node cannot come before all of its parents have been included.
|
2018-12-10 05:29:13 +00:00
|
|
|
// 2. At any given time, the lowest-lettered available step must be executed.
|
2018-12-10 04:46:35 +00:00
|
|
|
func FindOrder(root *Node) []*Node {
|
2018-12-10 05:29:13 +00:00
|
|
|
seen := map[rune]bool{
|
|
|
|
0: true,
|
|
|
|
}
|
2018-12-10 04:46:35 +00:00
|
|
|
order := []*Node{}
|
|
|
|
|
2018-12-10 05:29:13 +00:00
|
|
|
for {
|
|
|
|
// continuously loop over the tree, retrieving the next usable node.
|
|
|
|
candidates := findCandidates(root, seen)
|
2018-12-10 04:46:35 +00:00
|
|
|
|
2018-12-10 05:29:13 +00:00
|
|
|
if len(candidates) == 0 {
|
|
|
|
return order
|
2018-12-10 04:46:35 +00:00
|
|
|
}
|
2018-12-10 05:29:13 +00:00
|
|
|
sortNodes(candidates)
|
|
|
|
order = append(order, candidates[0])
|
|
|
|
seen[candidates[0].Name] = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func findCandidates(node *Node, seen map[rune]bool) []*Node {
|
|
|
|
candidates := []*Node{}
|
2018-12-10 04:46:35 +00:00
|
|
|
|
2018-12-10 05:29:13 +00:00
|
|
|
// if we've been seen before, we're clear to recurse
|
|
|
|
if seen[node.Name] == true {
|
|
|
|
for _, child := range node.Children {
|
|
|
|
candidates = append(candidates, findCandidates(child, seen)...)
|
2018-12-10 04:46:35 +00:00
|
|
|
}
|
2018-12-10 05:29:13 +00:00
|
|
|
return candidates
|
2018-12-10 04:46:35 +00:00
|
|
|
}
|
|
|
|
|
2018-12-10 05:29:13 +00:00
|
|
|
// add the node, but only if all its parents have been seen
|
|
|
|
for _, parent := range node.Parents {
|
|
|
|
if seen[parent.Name] == false {
|
|
|
|
return candidates
|
|
|
|
}
|
2018-12-10 04:46:35 +00:00
|
|
|
}
|
|
|
|
|
2018-12-10 05:29:13 +00:00
|
|
|
// We haven't seen this one before, and its parents are seen.
|
|
|
|
// Return it as a candidate.
|
|
|
|
return append(candidates, node)
|
2018-12-10 04:46:35 +00:00
|
|
|
}
|