diff --git a/2018/internal/tree/findorder.go b/2018/internal/tree/findorder.go index 03f027e..b68e5ec 100644 --- a/2018/internal/tree/findorder.go +++ b/2018/internal/tree/findorder.go @@ -1,51 +1,46 @@ package tree -import "fmt" // debug - // FindOrder determines the correct order according to these rules: // 1. A node cannot come before all of its parents have been included. -// 2. At any given time, the lowest-lettered step must be executed. +// 2. At any given time, the lowest-lettered available step must be executed. func FindOrder(root *Node) []*Node { - seen := make(map[rune]bool) - return findOrderR(root, seen) -} - -func findOrderR(node *Node, seen map[rune]bool) []*Node { + seen := map[rune]bool{ + 0: true, + } order := []*Node{} - // debug - fmt.Printf("In node: %c | Children: ", node.Name) - for _, child := range node.Children { - fmt.Printf("%c ", child.Name) + for { + // continuously loop over the tree, retrieving the next usable node. + candidates := findCandidates(root, seen) + + if len(candidates) == 0 { + return order + } + sortNodes(candidates) + order = append(order, candidates[0]) + seen[candidates[0].Name] = true } - fmt.Printf("| Parents: ") - for _, parent := range node.Parents { - fmt.Printf("%c ", parent.Name) +} + +func findCandidates(node *Node, seen map[rune]bool) []*Node { + candidates := []*Node{} + + // 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)...) + } + return candidates } - fmt.Println() - // end debug // add the node, but only if all its parents have been seen - if len(node.Parents) == 0 { - seen[node.Name] = true - } else { - for _, parent := range node.Parents { - if _, ok := seen[parent.Name]; !ok { - return order - } - } - - if _, ok := seen[node.Name]; !ok { - order = append(order, node) - fmt.Printf("Added node: %c\n", node.Name) - seen[node.Name] = true + for _, parent := range node.Parents { + if seen[parent.Name] == false { + return candidates } } - // recurse - for _, child := range node.Children { - order = append(order, findOrderR(child, seen)...) - } - - return order + // We haven't seen this one before, and its parents are seen. + // Return it as a candidate. + return append(candidates, node) } diff --git a/2018/internal/tree/tree.go b/2018/internal/tree/tree.go index 9c97033..9479098 100644 --- a/2018/internal/tree/tree.go +++ b/2018/internal/tree/tree.go @@ -39,16 +39,15 @@ func BuildDependencyTree(data []string) *Node { // sort the children in each node for _, node := range depMap { - sortChildren(node) + sortNodes(node.Children) } return BuildTreeRoot(depMap) } -func sortChildren(node *Node) { - children := node.Children - sort.Slice(children[:], func(i, j int) bool { - return children[i].Name < children[j].Name +func sortNodes(nodes []*Node) { + sort.Slice(nodes[:], func(i, j int) bool { + return nodes[i].Name < nodes[j].Name }) } @@ -62,6 +61,6 @@ func BuildTreeRoot(depMap map[rune]*Node) *Node { } } - sortChildren(root) + sortNodes(root.Children) return root }