Advertisement
Guest User

Untitled

a guest
Apr 24th, 2019
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.93 KB | None | 0 0
  1. class Percolation {
  2. constructor(UnionFind, SquareGrid) {}
  3.  
  4. init(gridSize) {
  5. // init union-find
  6. this.uf = new UnionFind(gridSize ** 2 + 2);
  7.  
  8. // init top virtual node
  9. let top = 0;
  10. for (let i = 1; i <= gridSize; i++) {
  11. this.uf.union(top, i);
  12. }
  13.  
  14. // init bottom virtual node
  15. let bottom = gridSize ** 2 + 1;
  16. for (let i = 1; i <= gridSize; i++) {
  17. this.uf.union(bottom, bottom - i);
  18. }
  19.  
  20. // init grid
  21. this.grid = new SquareGrid(gridSize);
  22. }
  23.  
  24. open(row, col) {
  25. this.grid.setCell(row, col, 1);
  26.  
  27. let adjacent = this.grid.getAdjacent(row, col);
  28. for (let cell of adjacent) {
  29. let [cellRow, cellCol] = cell;
  30.  
  31. if (this.isOpen(...cell)) {
  32. this.uf.union(
  33. row * this.grid.size + col + 1,
  34. cellRow * this.grid.size + cellCol + 1
  35. );
  36. }
  37. }
  38. }
  39.  
  40. isOpen(row, col) {
  41. return this.grid.getCell(row, col) === 1;
  42. }
  43.  
  44. percolate() {
  45. return this.uf.connected(0, this.grid.size ** 2 + 1);
  46. }
  47. }
  48.  
  49. class SquareGrid {
  50. constructor(size, canvasWidth, canvasHeight) {
  51. this.size = size;
  52. this.matrix = [...Array(size)].map(() => Array(size).fill(0));
  53. }
  54.  
  55. getAdjacent(row, col) {
  56. let dir = [
  57. [0, 1],
  58. [1, 0],
  59. [0, -1],
  60. [-1, 0]
  61. ];
  62.  
  63. let adjacent = [];
  64. for (let d of dir) {
  65. let [dy, dx] = d;
  66.  
  67. if (row + dy in this.matrix && col + dx in this.matrix[row + dy]) {
  68. adjacent.push([row + dy, col + dx]);
  69. }
  70. }
  71. return adjacent;
  72. }
  73.  
  74. getRandom() {
  75. // returns [randRow, randCol]
  76. return [(Math.random() * this.size) | 0, (Math.random() * this.size) | 0];
  77. }
  78.  
  79. setCell(row, col, value) {
  80. (this.matrix[row] || {})[col] = value;
  81. }
  82.  
  83. getCell(row, col) {
  84. return (this.matrix[row] || {})[col];
  85. }
  86.  
  87. traverse(fn) {
  88. for (let i = 0; i < this.matrix.length; i++) {
  89. for (let j = 0; j < this.matrix[0].length; j++) {
  90. fn(i, j);
  91. }
  92. }
  93. }
  94. }
  95.  
  96. class UnionFind {
  97. constructor(n) {
  98. this.id = [...Array(n)].map((_, i) => i);
  99. this.sz = [...Array(n)].map(_ => 1);
  100. }
  101.  
  102. _root(i) {
  103. while (i !== this.id[i]) i = this.id[i];
  104. return i;
  105. }
  106.  
  107. union(j, k) {
  108. let jroot = this._root(j);
  109. let kroot = this._root(k);
  110.  
  111. if (jroot === kroot) return;
  112.  
  113. if (this.sz[jroot] > this.sz[kroot]) {
  114. this.id[kroot] = jroot;
  115. this.sz[jroot] += this.sz[kroot];
  116. } else {
  117. this.id[jroot] = kroot;
  118. this.sz[kroot] += this.sz[jroot];
  119. }
  120. }
  121.  
  122. connected(k, m) {
  123. return this._root(k) === this._root(m);
  124. }
  125. }
  126.  
  127. // speedtest logics
  128. function run(gridSize) {
  129.  
  130. // measures running time
  131. console.time('Percolated in')
  132.  
  133. // injection is used for debugging
  134. percolation = new Percolation(UnionFind, SquareGrid);
  135. percolation.init(gridSize);
  136.  
  137. // while it does not percolate keep opening new sites
  138. while(!percolation.percolate()) {
  139. percolation.open(...percolation.grid.getRandom());
  140. }
  141. console.timeEnd('Percolated in')
  142. }
  143.  
  144. run(200)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement