Advertisement
Guest User

Untitled

a guest
Apr 28th, 2017
54
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.95 KB | None | 0 0
  1. 'use strict'
  2.  
  3. const filter = pred => function* (iterable) {
  4. for(let x of iterable) {
  5. if(pred(x)){
  6. yield x
  7. }
  8. }
  9. }
  10.  
  11. const collect = iterable => {
  12. const arr = []
  13. for(let x of iterable) {
  14. arr.push(x)
  15. }
  16. return arr
  17. }
  18.  
  19.  
  20. const update = (obj, ups) => {
  21. let res = {}
  22. for(let key in obj) {
  23. res[key] = ups[key] || obj[key]
  24. }
  25. return res
  26. }
  27.  
  28. const findIf = (array, first, last, pred) => {
  29. for(; first < last && !pred(array[first]); ++ first){}
  30. return first
  31. }
  32.  
  33. // private
  34. const shiftLeft = (array, first, last, n) => {
  35. for(; first + n < last; ++first) {
  36. array[first] = array[first + n]
  37. }
  38. }
  39.  
  40. const removeIf = (array, pred) => {
  41. if(array.length === 0) return 0
  42. let first = 0
  43. let p = 0
  44. let n = 0
  45. let last = array.length
  46. const notPred = x => !pred(x)
  47. //
  48. while(n < last) {
  49. p = findIf(array, first, last, notPred)
  50. n = findIf(array, p, last, pred)
  51. shiftLeft(array, first, n, p - first)
  52. first = first + (n - p)
  53. }
  54. array.splice(first)
  55. }
  56.  
  57.  
  58. /*
  59. no error cheking in this version, see comments for preconditions
  60. */
  61.  
  62. const DirectedGraph = function () {
  63. const _nodes = []
  64. const _edges = []
  65.  
  66. //
  67. this.node = name => _nodes.find(n => n.name === name)
  68.  
  69. this.edge = (from, to) => _edges.find(e => e.from === from && e.to === to)
  70.  
  71. //
  72. this.nodes = function* () {
  73. for(let node of _nodes){
  74. yield node
  75. }
  76. }
  77.  
  78. this.edges = function* () {
  79. for(let edge of _edges){
  80. yield edge
  81. }
  82. }
  83.  
  84. // edges that lead from nothing into nodes (into the graph)
  85. this.inEdges = function* () {
  86. for(let edge of _edges) {
  87. if(!edge.from) {
  88. yield edge
  89. }
  90. }
  91. }
  92.  
  93. // edges that lead from nodes to nothing (out of the graph)
  94. this.outEdges = function* () {
  95. for(let edge of _edges) {
  96. if(!edge.to) {
  97. yield edge
  98. }
  99. }
  100. }
  101.  
  102.  
  103. // name :: string
  104. // data :: any; user data
  105. this.addOrUpdateNode = (name, data) => {
  106. let node = _nodes.find(n => n.name === name)
  107. if(node){
  108. node.data = update(node.data, data)
  109. } else {
  110. _nodes.push({name:name, data:data})
  111. }
  112. }
  113.  
  114. // from :: string or null; has to be name of a node
  115. // to :: string or null; has to be name of a node
  116. // data :: any; user data
  117. // only one of `from` and `to` can be null
  118. this.addOrUpdateEdge = (from, to, data) => {
  119. let edge = _edges.find( e => e.from === from && e.to === to)
  120. if(edge) {
  121. edge.data = update(edge.data, data)
  122. } else {
  123. _edges.push({
  124. from: from,
  125. to: to,
  126. data: data
  127. })
  128. }
  129. }
  130.  
  131. this.removeNode = name => {
  132. removeIf(_nodes, n => n.name === name)
  133. for(let edge of _edges){
  134. if(edge.from === name) {
  135. edge.from = null
  136. }
  137. if(edge.to === name) {
  138. edge.to = null
  139. }
  140. }
  141. removeIf(_edges, e => e.from === null && e.to === null)
  142. }
  143.  
  144. this.removeEdge =(from, to) => removeIf(_edges, e => e.from === from && e.to === to )
  145.  
  146. //
  147. // `inEdges` and `outEdges` must be subset of `this.inEdges()` and `this.outEdges()`, respectively
  148. //
  149. // `namePrefix` is optional and is appended to names of nodes in `graph` before they are inserted
  150. // into `this` graph. `graph` is not modified
  151. //
  152. // number of `inEdges` must be same as number of `graph.outEdges()` (same for `outEdges` and
  153. // `graph.inEdges()`)
  154. //
  155. this.splice = (inEdges, outEdges, graph, namePrefix) => {
  156. let gInEdges = collect(graph.inEdges())
  157. let gOutEdges = collect(graph.outEdges())
  158.  
  159. }
  160. }
  161.  
  162.  
  163.  
  164. //
  165. //
  166. //
  167. let graph = new DirectedGraph()
  168.  
  169. graph.addOrUpdateNode('start', {})
  170. graph.addOrUpdateNode('first', {})
  171. graph.addOrUpdateNode('second', {})
  172. graph.addOrUpdateNode('end', {})
  173.  
  174. graph.addOrUpdateEdge('start', 'first', {})
  175. graph.addOrUpdateEdge('first', 'first', {})
  176. graph.addOrUpdateEdge('first', 'second', {})
  177. graph.addOrUpdateEdge('second', 'first', {})
  178. graph.addOrUpdateEdge('second', 'end', {})
  179. graph.addOrUpdateEdge(null, 'start', {})
  180. graph.addOrUpdateEdge('end', null, {})
  181.  
  182. graph.removeNode('first')
  183.  
  184. console.log("Nodes: ")
  185. for(let node of graph.nodes()){
  186. console.log(node)
  187. }
  188.  
  189. console.log("Edges: ")
  190. for(let edge of graph.edges()){
  191. console.log(edge)
  192. }
  193.  
  194. console.log("Edges (from and to 'second'): ")
  195. for(let edge of filter(e => e.from === 'second' || e.to === 'second')(graph.edges())){
  196. console.log(edge)
  197. }
  198.  
  199. console.log("In edges: ")
  200. for(let node of graph.inEdges()){
  201. console.log(node)
  202. }
  203.  
  204. console.log("Out edges: ")
  205. for(let edge of graph.outEdges()){
  206. console.log(edge)
  207. }
  208.  
  209.  
  210. console.log("\ninsert test\n")
  211.  
  212. let outerGraph = new DirectedGraph()
  213. let inEdges = []
  214. let outEdges = []
  215.  
  216. let innerGraph = new DirectedGraph()
  217.  
  218. outerGraph.splice(inEdges, outEdges, innerGraph, 'inner.')
  219.  
  220.  
  221. console.log("Nodes: ")
  222. for(let node of outerGraph.nodes()){
  223. console.log(node)
  224. }
  225.  
  226. console.log("Edges: ")
  227. for(let edge of outerGraph.edges()){
  228. console.log(edge)
  229. }
  230.  
  231. console.log("In edges: ")
  232. for(let node of outerGraph.inEdges()){
  233. console.log(node)
  234. }
  235.  
  236. console.log("Out edges: ")
  237. for(let edge of outerGraph.outEdges()){
  238. console.log(edge)
  239. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement