Advertisement
1lann

immutable graph

Feb 26th, 2018
198
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 1.61 KB | None | 0 0
  1. package graph
  2.  
  3. type Node struct {
  4.     Value interface{}
  5.  
  6.     id    int
  7.     edges []Node
  8. }
  9.  
  10. type Graph struct {
  11.     idCounter int
  12.     nodes     map[int]Node
  13. }
  14.  
  15. func NewGraph(root Node) Graph {
  16.     return Graph{
  17.         idCounter: 1,
  18.         nodes:     map[int]Node{0: root},
  19.     }
  20. }
  21.  
  22. func (g Graph) AddNode(from int, node Node) (Graph, int) {
  23.     newG := g.Copy()
  24.     start, found := newG.nodes[from]
  25.     if !found {
  26.         panic("cannot add node from non-existent node")
  27.     }
  28.  
  29.     newN := node
  30.     newG.nodes[newG.idCounter] = newN
  31.     newG.idCounter++
  32.     start.edges = make([]Node, len(start.edges)+1)
  33.     copy(start.edges, g.nodes[from].edges)
  34.     start.edges[len(start.edges)-1] = newN
  35.  
  36.     return newG, newG.idCounter - 1
  37. }
  38.  
  39. func (g Graph) Copy() Graph {
  40.     newG := Graph{
  41.         idCounter: g.idCounter,
  42.         nodes:     make(map[int]Node),
  43.     }
  44.  
  45.     for k, v := range g.nodes {
  46.         newG.nodes[k] = v
  47.     }
  48.  
  49.     return newG
  50. }
  51.  
  52. func (g Graph) RemoveNode(id int) Graph {
  53.     newG := g.Copy()
  54.  
  55.     for id, n := range newG.nodes {
  56.         newG.nodes[id] = n.removeEdge(id)
  57.     }
  58.  
  59.     delete(newG.nodes, id)
  60.  
  61.     return newG
  62. }
  63.  
  64. func (g Graph) GetNode(id int) Node {
  65.     return g.nodes[id]
  66. }
  67.  
  68. func (g Graph) Nodes() []Node {
  69.     results := make([]Node, 0, len(g.nodes))
  70.     for _, node := range g.nodes {
  71.         results = append(results, node)
  72.     }
  73.  
  74.     return results
  75. }
  76.  
  77. func (n Node) Edges() []Node {
  78.     results := make([]Node, len(n.edges))
  79.     copy(results, n.edges)
  80.     return results
  81. }
  82.  
  83. func (n Node) removeEdge(id int) Node {
  84.     n.edges = make([]Node, 0, len(n.edges))
  85.  
  86.     for _, otherN := range n.edges {
  87.         if otherN.id == id {
  88.             continue
  89.         }
  90.         n.edges = append(n.edges, otherN)
  91.     }
  92.  
  93.     return n
  94. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement