data-structure-typed 0.8.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/.idea/data-structure-typed.iml +12 -0
  2. package/.idea/modules.xml +8 -0
  3. package/.idea/vcs.xml +6 -0
  4. package/README.md +2 -0
  5. package/dist/data-structures/binary-tree/aa-tree.js +6 -0
  6. package/dist/data-structures/binary-tree/avl-tree.js +231 -0
  7. package/dist/data-structures/binary-tree/b-tree.js +6 -0
  8. package/dist/data-structures/binary-tree/binary-indexed-tree.js +31 -0
  9. package/dist/data-structures/binary-tree/binary-tree.js +992 -0
  10. package/dist/data-structures/binary-tree/bst.js +431 -0
  11. package/dist/data-structures/binary-tree/index.js +20 -0
  12. package/dist/data-structures/binary-tree/rb-tree.js +6 -0
  13. package/dist/data-structures/binary-tree/segment-tree.js +151 -0
  14. package/dist/data-structures/binary-tree/splay-tree.js +6 -0
  15. package/dist/data-structures/binary-tree/tree-multiset.js +16 -0
  16. package/dist/data-structures/binary-tree/two-three-tree.js +6 -0
  17. package/dist/data-structures/graph/abstract-graph.js +648 -0
  18. package/dist/data-structures/graph/directed-graph.js +268 -0
  19. package/dist/data-structures/graph/index.js +19 -0
  20. package/dist/data-structures/graph/undirected-graph.js +142 -0
  21. package/dist/data-structures/hash/coordinate-map.js +24 -0
  22. package/dist/data-structures/hash/coordinate-set.js +21 -0
  23. package/dist/data-structures/hash/hash-table.js +2 -0
  24. package/dist/data-structures/hash/index.js +17 -0
  25. package/dist/data-structures/hash/pair.js +2 -0
  26. package/dist/data-structures/hash/tree-map.js +2 -0
  27. package/dist/data-structures/hash/tree-set.js +2 -0
  28. package/dist/data-structures/heap/heap.js +114 -0
  29. package/dist/data-structures/heap/index.js +19 -0
  30. package/dist/data-structures/heap/max-heap.js +22 -0
  31. package/dist/data-structures/heap/min-heap.js +22 -0
  32. package/dist/data-structures/index.js +25 -0
  33. package/dist/data-structures/linked-list/doubly-linked-list.js +259 -0
  34. package/dist/data-structures/linked-list/index.js +18 -0
  35. package/dist/data-structures/linked-list/singly-linked-list.js +660 -0
  36. package/dist/data-structures/linked-list/skip-linked-list.js +2 -0
  37. package/dist/data-structures/matrix/index.js +19 -0
  38. package/dist/data-structures/matrix/matrix.js +14 -0
  39. package/dist/data-structures/matrix/matrix2d.js +119 -0
  40. package/dist/data-structures/matrix/navigator.js +78 -0
  41. package/dist/data-structures/matrix/vector2d.js +161 -0
  42. package/dist/data-structures/priority-queue/index.js +19 -0
  43. package/dist/data-structures/priority-queue/max-priority-queue.js +15 -0
  44. package/dist/data-structures/priority-queue/min-priority-queue.js +15 -0
  45. package/dist/data-structures/priority-queue/priority-queue.js +174 -0
  46. package/dist/data-structures/queue/deque.js +132 -0
  47. package/dist/data-structures/queue/index.js +17 -0
  48. package/dist/data-structures/queue/queue.js +113 -0
  49. package/dist/data-structures/stack/index.js +17 -0
  50. package/dist/data-structures/stack/stack.js +97 -0
  51. package/dist/data-structures/trampoline.js +52 -0
  52. package/dist/data-structures/trie/index.js +17 -0
  53. package/dist/data-structures/trie/trie.js +141 -0
  54. package/dist/index.js +17 -0
  55. package/dist/types/data-structures/binary-tree/aa-tree.d.ts +2 -0
  56. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +21 -0
  57. package/dist/types/data-structures/binary-tree/b-tree.d.ts +2 -0
  58. package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +8 -0
  59. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +140 -0
  60. package/dist/types/data-structures/binary-tree/bst.d.ts +32 -0
  61. package/dist/types/data-structures/binary-tree/index.d.ts +4 -0
  62. package/dist/types/data-structures/binary-tree/rb-tree.d.ts +2 -0
  63. package/dist/types/data-structures/binary-tree/segment-tree.d.ts +33 -0
  64. package/dist/types/data-structures/binary-tree/splay-tree.d.ts +2 -0
  65. package/dist/types/data-structures/binary-tree/tree-multiset.d.ts +11 -0
  66. package/dist/types/data-structures/binary-tree/two-three-tree.d.ts +2 -0
  67. package/dist/types/data-structures/graph/abstract-graph.d.ts +126 -0
  68. package/dist/types/data-structures/graph/directed-graph.d.ts +51 -0
  69. package/dist/types/data-structures/graph/index.d.ts +3 -0
  70. package/dist/types/data-structures/graph/undirected-graph.d.ts +24 -0
  71. package/dist/types/data-structures/hash/coordinate-map.d.ts +8 -0
  72. package/dist/types/data-structures/hash/coordinate-set.d.ts +7 -0
  73. package/dist/types/data-structures/hash/hash-table.d.ts +1 -0
  74. package/dist/types/data-structures/hash/index.d.ts +1 -0
  75. package/dist/types/data-structures/hash/pair.d.ts +1 -0
  76. package/dist/types/data-structures/hash/tree-map.d.ts +1 -0
  77. package/dist/types/data-structures/hash/tree-set.d.ts +1 -0
  78. package/dist/types/data-structures/heap/heap.d.ts +72 -0
  79. package/dist/types/data-structures/heap/index.d.ts +3 -0
  80. package/dist/types/data-structures/heap/max-heap.d.ts +14 -0
  81. package/dist/types/data-structures/heap/min-heap.d.ts +14 -0
  82. package/dist/types/data-structures/index.d.ts +9 -0
  83. package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +59 -0
  84. package/dist/types/data-structures/linked-list/index.d.ts +2 -0
  85. package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +358 -0
  86. package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +1 -0
  87. package/dist/types/data-structures/matrix/index.d.ts +3 -0
  88. package/dist/types/data-structures/matrix/matrix.d.ts +9 -0
  89. package/dist/types/data-structures/matrix/matrix2d.d.ts +25 -0
  90. package/dist/types/data-structures/matrix/navigator.d.ts +31 -0
  91. package/dist/types/data-structures/matrix/vector2d.d.ts +74 -0
  92. package/dist/types/data-structures/priority-queue/index.d.ts +3 -0
  93. package/dist/types/data-structures/priority-queue/max-priority-queue.d.ts +4 -0
  94. package/dist/types/data-structures/priority-queue/min-priority-queue.d.ts +4 -0
  95. package/dist/types/data-structures/priority-queue/priority-queue.d.ts +36 -0
  96. package/dist/types/data-structures/queue/deque.d.ts +37 -0
  97. package/dist/types/data-structures/queue/index.d.ts +1 -0
  98. package/dist/types/data-structures/queue/queue.d.ts +76 -0
  99. package/dist/types/data-structures/stack/index.d.ts +1 -0
  100. package/dist/types/data-structures/stack/stack.d.ts +69 -0
  101. package/dist/types/data-structures/trampoline.d.ts +25 -0
  102. package/dist/types/data-structures/trie/index.d.ts +1 -0
  103. package/dist/types/data-structures/trie/trie.d.ts +28 -0
  104. package/dist/types/index.d.ts +1 -0
  105. package/dist/types/index.js +17 -0
  106. package/dist/types/types/index.d.ts +1 -0
  107. package/dist/types/types/utils.d.ts +46 -0
  108. package/dist/types/utils.d.ts +122 -0
  109. package/dist/types/utils.js +53 -0
  110. package/dist/utils.js +569 -0
  111. package/package.json +75 -0
  112. package/src/data-structures/binary-tree/aa-tree.ts +3 -0
  113. package/src/data-structures/binary-tree/avl-tree.ts +232 -0
  114. package/src/data-structures/binary-tree/b-tree.ts +3 -0
  115. package/src/data-structures/binary-tree/binary-indexed-tree.ts +33 -0
  116. package/src/data-structures/binary-tree/binary-tree.ts +1088 -0
  117. package/src/data-structures/binary-tree/bst.ts +404 -0
  118. package/src/data-structures/binary-tree/index.ts +4 -0
  119. package/src/data-structures/binary-tree/rb-tree.ts +3 -0
  120. package/src/data-structures/binary-tree/segment-tree.ts +164 -0
  121. package/src/data-structures/binary-tree/splay-tree.ts +3 -0
  122. package/src/data-structures/binary-tree/tree-multiset.ts +21 -0
  123. package/src/data-structures/binary-tree/two-three-tree.ts +3 -0
  124. package/src/data-structures/graph/abstract-graph.ts +789 -0
  125. package/src/data-structures/graph/directed-graph.ts +322 -0
  126. package/src/data-structures/graph/index.ts +3 -0
  127. package/src/data-structures/graph/undirected-graph.ts +154 -0
  128. package/src/data-structures/hash/coordinate-map.ts +24 -0
  129. package/src/data-structures/hash/coordinate-set.ts +20 -0
  130. package/src/data-structures/hash/hash-table.ts +1 -0
  131. package/src/data-structures/hash/index.ts +1 -0
  132. package/src/data-structures/hash/pair.ts +1 -0
  133. package/src/data-structures/hash/tree-map.ts +1 -0
  134. package/src/data-structures/hash/tree-set.ts +1 -0
  135. package/src/data-structures/heap/heap.ts +136 -0
  136. package/src/data-structures/heap/index.ts +3 -0
  137. package/src/data-structures/heap/max-heap.ts +22 -0
  138. package/src/data-structures/heap/min-heap.ts +24 -0
  139. package/src/data-structures/index.ts +10 -0
  140. package/src/data-structures/linked-list/doubly-linked-list.ts +258 -0
  141. package/src/data-structures/linked-list/index.ts +2 -0
  142. package/src/data-structures/linked-list/singly-linked-list.ts +750 -0
  143. package/src/data-structures/linked-list/skip-linked-list.ts +1 -0
  144. package/src/data-structures/matrix/index.ts +3 -0
  145. package/src/data-structures/matrix/matrix.ts +13 -0
  146. package/src/data-structures/matrix/matrix2d.ts +125 -0
  147. package/src/data-structures/matrix/navigator.ts +99 -0
  148. package/src/data-structures/matrix/vector2d.ts +189 -0
  149. package/src/data-structures/priority-queue/index.ts +3 -0
  150. package/src/data-structures/priority-queue/max-priority-queue.ts +12 -0
  151. package/src/data-structures/priority-queue/min-priority-queue.ts +12 -0
  152. package/src/data-structures/priority-queue/priority-queue.ts +208 -0
  153. package/src/data-structures/queue/deque.ts +139 -0
  154. package/src/data-structures/queue/index.ts +1 -0
  155. package/src/data-structures/queue/queue.ts +123 -0
  156. package/src/data-structures/stack/index.ts +1 -0
  157. package/src/data-structures/stack/stack.ts +104 -0
  158. package/src/data-structures/trampoline.ts +91 -0
  159. package/src/data-structures/trie/index.ts +1 -0
  160. package/src/data-structures/trie/trie.ts +153 -0
  161. package/src/index.ts +1 -0
  162. package/src/types/index.ts +1 -0
  163. package/src/types/patches/index.d.ts +0 -0
  164. package/src/types/utils.ts +158 -0
  165. package/src/utils.ts +605 -0
  166. package/tsconfig.json +52 -0
@@ -0,0 +1,3 @@
1
+ export * from './matrix';
2
+ export * from './vector2d';
3
+ export * from './matrix2d';
@@ -0,0 +1,13 @@
1
+ // todo need to be improved
2
+ export class MatrixNTI2D<T = number> {
3
+ private readonly _matrix: Array<Array<T>>;
4
+
5
+ constructor(options: { row: number, col: number, initialVal?: T }) {
6
+ const {row, col, initialVal} = options;
7
+ this._matrix = new Array(row).fill(undefined).map(() => new Array(col).fill(initialVal || 0));
8
+ }
9
+
10
+ toArray(): Array<Array<T>> {
11
+ return this._matrix;
12
+ }
13
+ }
@@ -0,0 +1,125 @@
1
+ import Vector2D from './vector2d'
2
+
3
+ export class Matrix2D {
4
+ private readonly _matrix: number[][];
5
+
6
+ constructor(value?: number[][] | Vector2D) {
7
+ if (typeof value === 'undefined') {
8
+ this._matrix = Matrix2D.identity
9
+ } else if (value instanceof Vector2D) {
10
+ this._matrix = Matrix2D.identity
11
+ this._matrix[0][0] = value.x
12
+ this._matrix[1][0] = value.y
13
+ this._matrix[2][0] = value.w
14
+ } else {
15
+ this._matrix = value
16
+ }
17
+ }
18
+
19
+ /**
20
+ * Return the matrix values
21
+ */
22
+ public get m(): number[][] {
23
+ return this._matrix
24
+ }
25
+
26
+ public static get empty(): number[][] {
27
+ return [[], [], []]
28
+ }
29
+
30
+ public get toVector(): Vector2D {
31
+ return new Vector2D(this._matrix[0][0], this._matrix[1][0])
32
+ }
33
+
34
+ /**
35
+ * Initialize an identity matrix
36
+ */
37
+ public static get identity(): number[][] {
38
+ return [
39
+ [1, 0, 0],
40
+ [0, 1, 0],
41
+ [0, 0, 1]]
42
+ }
43
+
44
+ public static add(matrix1: Matrix2D, matrix2: Matrix2D): Matrix2D {
45
+ const result = Matrix2D.empty
46
+ for (let i = 0; i < 3; i++) {
47
+ for (let j = 0; j < 3; j++) {
48
+ result[i][j] = matrix1.m[i][j] + matrix2.m[i][j]
49
+ }
50
+ }
51
+ return new Matrix2D(result);
52
+ }
53
+
54
+ public static subtract(matrix1: Matrix2D, matrix2: Matrix2D): Matrix2D {
55
+ const result = Matrix2D.empty
56
+ for (let i = 0; i < 3; i++) {
57
+ for (let j = 0; j < 3; j++) {
58
+ result[i][j] = matrix1.m[i][j] - matrix2.m[i][j]
59
+ }
60
+ }
61
+ return new Matrix2D(result);
62
+ }
63
+
64
+ public static multiply(matrix1: Matrix2D, matrix2: Matrix2D): Matrix2D {
65
+ const result = Matrix2D.empty
66
+ for (let i = 0; i < 3; i++) {
67
+ for (let j = 0; j < 3; j++) {
68
+ result[i][j] = 0;
69
+ for (let k = 0; k < 3; k++) {
70
+ result[i][j] += matrix1.m[i][k] * matrix2.m[k][j];
71
+ }
72
+ }
73
+ }
74
+ return new Matrix2D(result);
75
+ }
76
+
77
+ public static multiplyByValue(matrix: Matrix2D, value: number): Matrix2D {
78
+ const result = Matrix2D.empty
79
+ for (let i = 0; i < 3; i++) {
80
+ for (let j = 0; j < 3; j++) {
81
+ result[i][j] = matrix.m[i][j] * value
82
+ }
83
+ }
84
+ return new Matrix2D(result);
85
+ }
86
+
87
+ public static multiplyByVector(matrix: Matrix2D, vector: Vector2D): Vector2D {
88
+ return Matrix2D.multiply(matrix, new Matrix2D(vector)).toVector
89
+ }
90
+
91
+ public static view(width: number, height: number): Matrix2D {
92
+ const scaleStep = 1 // Scale every vector * scaleStep
93
+ const centerX = width / 2
94
+ const centerY = height / 2
95
+ const flipX = Math.cos(Math.PI) // rotate 180deg / 3.14radian around X-axis
96
+
97
+ return new Matrix2D([
98
+ [scaleStep, 0, centerX],
99
+ [0, flipX * scaleStep, centerY],
100
+ [0, 0, 1]])
101
+ }
102
+
103
+ public static scale(factor: number) {
104
+ return Matrix2D.multiplyByValue(new Matrix2D(), factor)
105
+ }
106
+
107
+ public static rotate(radians: number) {
108
+ const cos = Math.cos(radians)
109
+ const sin = Math.sin(radians)
110
+
111
+ return new Matrix2D([
112
+ [cos, -sin, 0],
113
+ [sin, cos, 0],
114
+ [0, 0, 1]])
115
+ }
116
+
117
+ public static translate(vector: Vector2D): Matrix2D {
118
+ return new Matrix2D([
119
+ [1, 0, vector.x],
120
+ [0, 1, vector.y],
121
+ [0, 0, vector.w]])
122
+ }
123
+ }
124
+
125
+ export default Matrix2D
@@ -0,0 +1,99 @@
1
+ type Direction = 'up' | 'right' | 'down' | 'left';
2
+ type Turning = { [key in Direction]: Direction };
3
+
4
+ export class Character {
5
+ direction: Direction;
6
+ turn: () => Character;
7
+
8
+ constructor(direction: Direction, turning: Turning) {
9
+ this.direction = direction;
10
+ this.turn = () => new Character(turning[direction], turning);
11
+ }
12
+ }
13
+
14
+ interface NavigatorParams<T> {
15
+ matrix: T[][],
16
+ turning: Turning,
17
+ onMove: (cur: [number, number]) => void
18
+ init: {
19
+ cur: [number, number],
20
+ charDir: Direction,
21
+ VISITED: T,
22
+ }
23
+ }
24
+
25
+ export class Navigator<T = number> {
26
+ private readonly _matrix: T[][];
27
+ private readonly _cur: [number, number];
28
+ private _character: Character;
29
+ private readonly _VISITED: T;
30
+ onMove: (cur: [number, number]) => void;
31
+
32
+ constructor({matrix, turning, onMove, init: {cur, charDir, VISITED}}: NavigatorParams<T>) {
33
+ this._matrix = matrix;
34
+ this._cur = cur;
35
+ this._character = new Character(charDir, turning);
36
+ this.onMove = onMove;
37
+ this.onMove && this.onMove(this._cur);
38
+ this._VISITED = VISITED;
39
+ this._matrix[this._cur[0]][this._cur[1]] = this._VISITED;
40
+ }
41
+
42
+ start() {
43
+ while (this.check(this._character.direction) || this.check(this._character.turn().direction)) {
44
+ const {direction} = this._character;
45
+ if (this.check(direction)) {
46
+ this.move(direction);
47
+ } else if (this.check(this._character.turn().direction)) {
48
+ this._character = this._character.turn();
49
+ }
50
+ }
51
+ }
52
+
53
+ check(direction: Direction) {
54
+ let forward: T | undefined, row: T[] | undefined;
55
+ const matrix = this._matrix;
56
+ const [i, j] = this._cur;
57
+ switch (direction) {
58
+ case 'up':
59
+ row = matrix[i - 1];
60
+ if (!row) return false;
61
+ forward = row[j];
62
+ break;
63
+ case 'right':
64
+ forward = matrix[i][j + 1];
65
+ break;
66
+ case 'down':
67
+ row = matrix[i + 1];
68
+ if (!row) return false;
69
+ forward = row[j];
70
+ break;
71
+ case 'left':
72
+ forward = matrix[i][j - 1];
73
+ break;
74
+ }
75
+ return forward !== undefined && forward !== this._VISITED;
76
+ }
77
+
78
+ move(direction: Direction) {
79
+ switch (direction) {
80
+ case 'up':
81
+ this._cur[0]--;
82
+ break;
83
+ case 'right':
84
+ this._cur[1]++;
85
+ break;
86
+ case 'down':
87
+ this._cur[0]++;
88
+ break;
89
+ case 'left':
90
+ this._cur[1]--;
91
+ break;
92
+ }
93
+
94
+ const [i, j] = this._cur;
95
+ this._matrix[i][j] = this._VISITED;
96
+ this.onMove && this.onMove(this._cur);
97
+ }
98
+ }
99
+
@@ -0,0 +1,189 @@
1
+ class Vector2D {
2
+ public static add(vector1: Vector2D, vector2: Vector2D): Vector2D {
3
+ return new Vector2D(vector1.x + vector2.x, vector1.y + vector2.y)
4
+ }
5
+
6
+ public static subtract(vector1: Vector2D, vector2: Vector2D): Vector2D {
7
+ return new Vector2D(vector1.x - vector2.x, vector1.y - vector2.y)
8
+ }
9
+
10
+ public static subtractValue(vector: Vector2D, value: number): Vector2D {
11
+ return new Vector2D(vector.x - value, vector.y - value)
12
+ }
13
+
14
+ public static multiply(vector: Vector2D, value: number): Vector2D {
15
+ return new Vector2D(vector.x * value, vector.y * value)
16
+ }
17
+
18
+ public static divide(vector: Vector2D, value: number): Vector2D {
19
+ return new Vector2D(vector.x / value, vector.y / value)
20
+ }
21
+
22
+ public static equals(vector1: Vector2D, vector2: Vector2D): boolean {
23
+ return vector1.x === vector2.x && vector1.y === vector2.y
24
+ }
25
+
26
+ public static equalsRounded(vector1: Vector2D, vector2: Vector2D, roundingFactor = 12): boolean {
27
+ const vector = Vector2D.abs(Vector2D.subtract(vector1, vector2))
28
+ if (vector.x < roundingFactor && vector.y < roundingFactor) {
29
+ return true
30
+ }
31
+
32
+ return false
33
+ }
34
+
35
+ /**
36
+ * Normalizes the vector if it matches a certain condition
37
+ */
38
+ public static normalize(vector: Vector2D): Vector2D {
39
+ const length = vector.length
40
+ if (length > 2.220446049250313e-16) { // Epsilon
41
+ return Vector2D.divide(vector, length)
42
+ }
43
+
44
+ return vector
45
+ }
46
+
47
+ /**
48
+ * Adjusts x and y so that the length of the vector does not exceed max
49
+ */
50
+ public static truncate(vector: Vector2D, max: number): Vector2D {
51
+ if (vector.length > max) {
52
+ return Vector2D.multiply(Vector2D.normalize(vector), max)
53
+ }
54
+
55
+ return vector
56
+ }
57
+
58
+ /**
59
+ * The vector that is perpendicular to this one
60
+ */
61
+ public static perp(vector: Vector2D): Vector2D {
62
+ return new Vector2D(-vector.y, vector.x)
63
+ }
64
+
65
+ /**
66
+ * returns the vector that is the reverse of this vector
67
+ */
68
+ public static reverse(vector: Vector2D): Vector2D {
69
+ return new Vector2D(-vector.x, -vector.y)
70
+ }
71
+
72
+ public static abs(vector: Vector2D): Vector2D {
73
+ return new Vector2D(Math.abs(vector.x), Math.abs(vector.y))
74
+ }
75
+
76
+ /**
77
+ * The dot product of v1 and v2
78
+ */
79
+ public static dot(vector1: Vector2D, vector2: Vector2D): number {
80
+ return (vector1.x * vector2.x) + (vector1.y * vector2.y)
81
+ }
82
+
83
+ /**
84
+ * The distance between this and the vector
85
+ */
86
+ public static distance(vector1: Vector2D, vector2: Vector2D): number {
87
+ const ySeparation = vector2.y - vector1.y
88
+ const xSeparation = vector2.x - vector1.x
89
+ return Math.sqrt((ySeparation * ySeparation) + (xSeparation * xSeparation))
90
+ }
91
+
92
+ /**
93
+ * The distance between this and the vector squared
94
+ */
95
+ public static distanceSq(vector1: Vector2D, vector2: Vector2D): number {
96
+ const ySeparation = vector2.y - vector1.y
97
+ const xSeparation = vector2.x - vector1.x
98
+ return (ySeparation * ySeparation) + (xSeparation * xSeparation)
99
+ }
100
+
101
+ /**
102
+ * Returns positive if v2 is clockwise of this vector, negative if counterclockwise
103
+ * (assuming the Y axis is pointing down, X axis to right like a Window app)
104
+ */
105
+ public static sign(vector1: Vector2D, vector2: Vector2D): number {
106
+ if (vector1.y * vector2.x > vector1.x * vector2.y) {
107
+ return -1
108
+ }
109
+
110
+ return 1
111
+ }
112
+
113
+ /**
114
+ * Returns the angle between origin and the given vector in radians
115
+ * @param vector
116
+ */
117
+ public static angle(vector: Vector2D): number {
118
+ const origin = new Vector2D(0, -1)
119
+ const radian = Math.acos(Vector2D.dot(vector, origin) / (vector.length * origin.length))
120
+ return Vector2D.sign(vector, origin) === 1 ? ((Math.PI * 2) - radian) : radian
121
+ }
122
+
123
+ public static random(maxX: number, maxY: number): Vector2D {
124
+ const randX = Math.floor(Math.random() * maxX - (maxX / 2))
125
+ const randY = Math.floor(Math.random() * maxY - (maxY / 2))
126
+ return new Vector2D(randX, randY)
127
+ }
128
+
129
+ // /**
130
+ // * Transform vectors based on the current tranformation matrices: translation, rotation and scale
131
+ // * @param vectors The vectors to transform
132
+ // */
133
+ // public static transform(vector: Vector2D, transformation: Matrix2D): Vector2D {
134
+ // return Matrix2D.multiplyByVector(transformation, vector)
135
+ // }
136
+
137
+ // /**
138
+ // * Transform vectors based on the current tranformation matrices: translation, rotation and scale
139
+ // * @param vectors The vectors to transform
140
+ // */
141
+ // public static transformList(vectors: Vector2D[], transformation: Matrix2D): Vector2D[] {
142
+ // return vectors.map(vector => Matrix2D.multiplyByVector(transformation, vector))
143
+ // }
144
+
145
+ constructor(
146
+ public x: number = 0,
147
+ public y: number = 0,
148
+ public w: number = 1 // needed for matrix multiplication
149
+ ) {
150
+ }
151
+
152
+ /**
153
+ * Check wether both x and y are zero
154
+ */
155
+ public zero(): void {
156
+ this.x = 0
157
+ this.y = 0
158
+ }
159
+
160
+ /**
161
+ * Set x and y both to zero
162
+ */
163
+ public get isZero(): boolean {
164
+ return this.x === 0 && this.y === 0
165
+ }
166
+
167
+ /**
168
+ * The length / magnitude of the vector
169
+ */
170
+ public get length(): number {
171
+ return Math.sqrt((this.x * this.x) + (this.y * this.y))
172
+ }
173
+
174
+ /**
175
+ * The squared length of the vector
176
+ */
177
+ public get lengthSq(): number {
178
+ return (this.x * this.x) + (this.y * this.y)
179
+ }
180
+
181
+ /**
182
+ * Return the vector with rounded values
183
+ */
184
+ public get rounded(): Vector2D {
185
+ return new Vector2D(Math.round(this.x), Math.round(this.y))
186
+ }
187
+ }
188
+
189
+ export default Vector2D
@@ -0,0 +1,3 @@
1
+ export * from './priority-queue';
2
+ export * from './min-priority-queue';
3
+ export * from './max-priority-queue';
@@ -0,0 +1,12 @@
1
+ import {PriorityQueue, PriorityQueueOptions} from './priority-queue';
2
+
3
+ export class MaxPriorityQueue<T = number> extends PriorityQueue<T> {
4
+ constructor(options: PriorityQueueOptions<T>) {
5
+ super({
6
+ nodes: options.nodes, comparator: (a: T, b: T) => {
7
+ const aKey = a as unknown as number, bKey = b as unknown as number;
8
+ return bKey - aKey;
9
+ }
10
+ });
11
+ }
12
+ }
@@ -0,0 +1,12 @@
1
+ import {PriorityQueue, PriorityQueueOptions} from './priority-queue';
2
+
3
+ export class MinPriorityQueue<T = number> extends PriorityQueue<T> {
4
+ constructor(options: PriorityQueueOptions<T>) {
5
+ super({
6
+ nodes: options.nodes, comparator: (a: T, b: T) => {
7
+ const aKey = a as unknown as number, bKey = b as unknown as number;
8
+ return aKey - bKey;
9
+ }
10
+ });
11
+ }
12
+ }
@@ -0,0 +1,208 @@
1
+ export type PriorityQueueComparator<T> = (a: T, b: T) => number;
2
+
3
+ export interface PriorityQueueOptions<T> {
4
+ nodes?: T[];
5
+ isFix?: boolean;
6
+ comparator: PriorityQueueComparator<T>;
7
+ }
8
+
9
+ export type PriorityQueueDFSOrderPattern = 'pre' | 'in' | 'post';
10
+
11
+ export class PriorityQueue<T = number> {
12
+ protected nodes: T[] = [];
13
+
14
+ get size(): number {
15
+ return this.nodes.length;
16
+ }
17
+
18
+ protected readonly _comparator: PriorityQueueComparator<T> = (a: T, b: T) => {
19
+ const aKey = a as unknown as number, bKey = b as unknown as number;
20
+ return aKey - bKey;
21
+ };
22
+
23
+ constructor(options: PriorityQueueOptions<T>) {
24
+ const {nodes, comparator, isFix = true} = options;
25
+ this._comparator = comparator;
26
+
27
+ if (nodes && nodes instanceof Array && nodes.length > 0) {
28
+ // TODO support distinct
29
+ this.nodes = Array.isArray(nodes) ? [...nodes] : [];
30
+ isFix && this._fix();
31
+ }
32
+ }
33
+
34
+ protected _compare(a: number, b: number) {
35
+ return this._comparator(this.nodes[a], this.nodes[b]) > 0;
36
+ }
37
+
38
+ protected _swap(a: number, b: number) {
39
+ const temp = this.nodes[a];
40
+ this.nodes[a] = this.nodes[b];
41
+ this.nodes[b] = temp;
42
+ }
43
+
44
+ protected _isValidIndex(index: number): boolean {
45
+ return index > -1 && index < this.nodes.length;
46
+ }
47
+
48
+ protected _getParent(child: number): number {
49
+ return Math.floor((child - 1) / 2);
50
+ }
51
+
52
+ protected _getLeft(parent: number): number {
53
+ return (2 * parent) + 1;
54
+ }
55
+
56
+ protected _getRight(parent: number): number {
57
+ return (2 * parent) + 2;
58
+ }
59
+
60
+ protected _getComparedChild(parent: number) {
61
+ let min = parent;
62
+ const left = this._getLeft(parent), right = this._getRight(parent);
63
+
64
+ if (left < this.size && this._compare(min, left)) {
65
+ min = left;
66
+ }
67
+ if (right < this.size && this._compare(min, right)) {
68
+ min = right;
69
+ }
70
+ return min;
71
+ }
72
+
73
+ protected _heapifyUp(start: number) {
74
+ while (start > 0 && this._compare(this._getParent(start), start)) {
75
+ const parent = this._getParent(start);
76
+ this._swap(start, parent);
77
+ start = parent;
78
+ }
79
+ }
80
+
81
+ protected _heapifyDown(start: number) {
82
+ let min = this._getComparedChild(start);
83
+ while (this._compare(start, min)) {
84
+ this._swap(min, start);
85
+ start = min;
86
+ min = this._getComparedChild(start);
87
+ }
88
+ }
89
+
90
+ protected _fix() {
91
+ for (let i = Math.floor(this.size / 2); i > -1; i--) this._heapifyDown(i);
92
+ }
93
+
94
+ offer(node: T) {
95
+ this.nodes.push(node);
96
+ this._heapifyUp(this.size - 1);
97
+ }
98
+
99
+ peek(): T | null {
100
+ return this.size ? this.nodes[0] : null;
101
+ }
102
+
103
+ poll(): T | null {
104
+ let res: T | null = null;
105
+ if (this.size > 1) {
106
+ this._swap(0, this.nodes.length - 1);
107
+ res = this.nodes.pop() ?? null;
108
+ this._heapifyDown(0);
109
+ } else if (this.size === 1) {
110
+ res = this.nodes.pop() ?? null;
111
+ }
112
+ return res;
113
+ }
114
+
115
+ leaf(): T | null {
116
+ return this.nodes[this.size - 1] ?? null;
117
+ }
118
+
119
+ isEmpty() {
120
+ return this.size === 0;
121
+ }
122
+
123
+ clear() {
124
+ this.nodes = [];
125
+ }
126
+
127
+ toArray(): T[] {
128
+ return [...this.nodes];
129
+ }
130
+
131
+ clone(): PriorityQueue<T> {
132
+ return new PriorityQueue<T>({nodes: this.nodes, comparator: this._comparator});
133
+ }
134
+
135
+ // --- start additional methods ---
136
+ isValid(): boolean {
137
+ const isValidRecursive = (parentIndex: number): boolean => {
138
+ let isValidLeft = true;
139
+ let isValidRight = true;
140
+
141
+ if (this._getLeft(parentIndex) !== -1) {
142
+ const leftChildIndex = (parentIndex * 2) + 1;
143
+ if (!this._compare(parentIndex, leftChildIndex)) return false;
144
+ isValidLeft = isValidRecursive(leftChildIndex);
145
+ }
146
+
147
+ if (this._getRight(parentIndex) !== -1) {
148
+ const rightChildIndex = (parentIndex * 2) + 2;
149
+ if (!this._compare(parentIndex, rightChildIndex)) return false;
150
+ isValidRight = isValidRecursive(rightChildIndex);
151
+ }
152
+
153
+ return isValidLeft && isValidRight;
154
+ };
155
+
156
+ return isValidRecursive(0);
157
+ }
158
+
159
+ sort(): T[] {
160
+ const visitedNode: T[] = [];
161
+ while (this.size !== 0) {
162
+ const top = this.poll();
163
+ if (top) visitedNode.push(top);
164
+ }
165
+ return visitedNode;
166
+ }
167
+
168
+ DFS(dfsMode: PriorityQueueDFSOrderPattern): (T | null)[] {
169
+ const visitedNode: (T | null)[] = [];
170
+
171
+ const traverse = (cur: number) => {
172
+ const leftChildIndex = this._getLeft(cur);
173
+ const rightChildIndex = this._getRight(cur);
174
+ switch (dfsMode) {
175
+ case 'in':
176
+ this._isValidIndex(leftChildIndex) && traverse(leftChildIndex);
177
+ visitedNode.push(this.nodes[cur] ?? null);
178
+ this._isValidIndex(rightChildIndex) && traverse(rightChildIndex);
179
+ break;
180
+ case 'pre':
181
+ visitedNode.push(this.nodes[cur] ?? null);
182
+ this._isValidIndex(leftChildIndex) && traverse(leftChildIndex);
183
+ this._isValidIndex(rightChildIndex) && traverse(rightChildIndex);
184
+ break;
185
+ case 'post':
186
+ this._isValidIndex(leftChildIndex) && traverse(leftChildIndex);
187
+ this._isValidIndex(rightChildIndex) && traverse(rightChildIndex);
188
+ visitedNode.push(this.nodes[cur] ?? null);
189
+ break;
190
+ }
191
+ };
192
+
193
+ this._isValidIndex(0) && traverse(0);
194
+ return visitedNode;
195
+ }
196
+
197
+ static heapify<T>(options: PriorityQueueOptions<T>) {
198
+ const heap = new PriorityQueue(options);
199
+ heap._fix();
200
+ return heap;
201
+ }
202
+
203
+ static isPriorityQueueified<T>(options: Omit<PriorityQueueOptions<T>, 'isFix'>) {
204
+ return new PriorityQueue({...options, isFix: true}).isValid();
205
+ }
206
+
207
+ // --- end additional methods ---
208
+ }