package pov const testVersion = 2 type Graph struct { leaves []Node } func New() *Graph { g := new(Graph) return g } // GetNode returns the node from the graph with label lbl func (g *Graph) GetNode(lbl string) *Node { for i := range g.leaves { if n := g.leaves[i].GetNode(lbl); n != nil { return n } } return nil } // AddNode adds a top level leaf with label lbl func (g *Graph) AddNode(lbl string) { g.leaves = append(g.leaves, Node{label: lbl}) } // addRealNode adds the node n to the top level func (g *Graph) addRealNode(n *Node) { g.leaves = append(g.leaves, *n) } // AddArc creates a new node after to named from func (g *Graph) AddArc(from, to string) { if n := g.GetNode(to); n != nil { n.AddNode(from) } } // ArcList returns a list of all arcs func (g *Graph) ArcList() []string { var ret []string for i := range g.leaves { ret = append(ret, g.leaves[i].ArcList()...) } return ret } // ChangeRoot changes the graph from starting at oldRoot going to newRoot func (g *Graph) ChangeRoot(oldRoot, newRoot string) *Graph { // First of all, find the newRoot node ret := New() // The new graph will start with newRoot and have newRoot's leaves var rt *Node if rt = g.GetNode(newRoot); rt == nil { return ret } // It'll have one more leaf, it's parent node //rt.addRealNode(g.GetNode(oldRoot)) ret.addRealNode(rt) return ret } func (g *Graph) getPath(from, to string) []string { var ret []string // Get the 'from' node frNode := g.GetNode(from) if frNode == nil { // Couldn't find the starting node return ret } // Just in case we got the same value for both if from == to { return []string{from} } // Found it return frNode.getPath(to) } type Node struct { label string leaves []Node } func (n *Node) AddNode(lbl string) { n.leaves = append(n.leaves, Node{label: lbl}) } func (n *Node) addRealNode(nd *Node) { n.leaves = append(n.leaves, *nd) } func (n *Node) GetNode(lbl string) *Node { if n.label == lbl { return n } for i := range n.leaves { if r := n.leaves[i].GetNode(lbl); r != nil { return r } } return nil } func (n *Node) ArcList() []string { var ret []string for i := range n.leaves { ret = append(ret, n.leaves[i].label+" -> "+n.label) ret = append(ret, n.leaves[i].ArcList()...) } return ret } func (n *Node) getPath(to string) []string { ret := []string{n.label} if n.label == to { return ret } var i int var found bool for i = range n.leaves { if n.leaves[i].GetNode(to) != nil { found = true break } } if !found { // We didn't find a path... :( return ret } // n.leaves[i] should be the right leaf now return append(ret, n.leaves[i].getPath(to)...) }