@calcit/ternary-tree 0.0.18 → 0.0.19-a1
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.
- package/lib/{hash.d.ts → hash.d.mts} +0 -0
- package/lib/{hash.js → hash.mjs} +0 -0
- package/lib/index.d.mts +4 -0
- package/lib/index.mjs +4 -0
- package/lib/{list.d.ts → list.d.mts} +1 -1
- package/lib/{list.js → list.mjs} +3 -3
- package/lib/main.d.mts +2 -0
- package/lib/{main.js → main.mjs} +6 -6
- package/lib/{map.d.ts → map.d.mts} +1 -1
- package/lib/{map.js → map.mjs} +2 -2
- package/lib/{test-list.d.ts → test-list.d.mts} +0 -0
- package/lib/{test-list.js → test-list.mjs} +18 -2
- package/lib/{test-map.d.ts → test-map.d.mts} +0 -0
- package/lib/{test-map.js → test-map.mjs} +3 -3
- package/lib/{types.d.ts → types.d.mts} +0 -0
- package/lib/{types.js → types.mjs} +0 -0
- package/lib/{utils.d.ts → utils.d.mts} +1 -1
- package/lib/{utils.js → utils.mjs} +2 -2
- package/package.json +9 -7
- package/assets/index.html +0 -2
- package/lib/bundle.js +0 -3022
- package/lib/bundle.js.map +0 -1
- package/lib/index.d.ts +0 -4
- package/lib/index.js +0 -4
- package/lib/main.d.ts +0 -2
- package/src/costs.nim +0 -62
- package/src/hash.ts +0 -78
- package/src/index.ts +0 -5
- package/src/list.ts +0 -996
- package/src/main.ts +0 -20
- package/src/map.ts +0 -1341
- package/src/shape.nim +0 -62
- package/src/test-list.ts +0 -271
- package/src/test-map.ts +0 -288
- package/src/types.ts +0 -87
- package/src/utils.ts +0 -124
package/src/shape.nim
DELETED
@@ -1,62 +0,0 @@
|
|
1
|
-
# TODO get a ts version
|
2
|
-
|
3
|
-
import random
|
4
|
-
import tables
|
5
|
-
import strformat
|
6
|
-
|
7
|
-
import ternary_tree
|
8
|
-
|
9
|
-
randomize()
|
10
|
-
|
11
|
-
proc tryListShape(): void =
|
12
|
-
var source: seq[int] = @[]
|
13
|
-
var data = initTernaryTreeList[int](@[0])
|
14
|
-
|
15
|
-
for i in 0..<18:
|
16
|
-
source.add i
|
17
|
-
|
18
|
-
data = initTernaryTreeList(source)
|
19
|
-
|
20
|
-
for i in 0..<18:
|
21
|
-
# echo data.formatInline
|
22
|
-
let newData = data.assocAfter(i, 888)
|
23
|
-
echo newData.getDepth, " : ", newData.formatInline
|
24
|
-
|
25
|
-
# data.forceInplaceBalancing
|
26
|
-
# echo data.getDepth, " : ", data.formatInline
|
27
|
-
|
28
|
-
|
29
|
-
proc tryMapShape(): void =
|
30
|
-
var dict: Table[string, int]
|
31
|
-
var data = initTernaryTreeMap(dict)
|
32
|
-
|
33
|
-
for idx in 0..<20:
|
34
|
-
data = data.assoc(fmt"x{idx}", idx + 10)
|
35
|
-
echo data.formatInline()
|
36
|
-
# echo "checked: ", data.checkStructure()
|
37
|
-
|
38
|
-
proc tryConcatList(): void =
|
39
|
-
let a = initTernaryTreeList(@[1,2,3,4])
|
40
|
-
let b = initTernaryTreeList(@[5,6,7,8])
|
41
|
-
let c = initTernaryTreeList(@[9,10,11,12])
|
42
|
-
|
43
|
-
echo a.formatInline
|
44
|
-
echo b.formatInline
|
45
|
-
echo c.formatInline
|
46
|
-
echo a.concat(b).formatInline
|
47
|
-
echo a.concat(b).concat(c).formatInline
|
48
|
-
|
49
|
-
let d = a.concat(b)
|
50
|
-
d.forceInplaceBalancing
|
51
|
-
|
52
|
-
echo d.formatInline
|
53
|
-
|
54
|
-
for i in 0..<8:
|
55
|
-
for j in i..<9:
|
56
|
-
echo fmt"{i}-{j} ", d.slice(i, j).formatInline
|
57
|
-
|
58
|
-
# tryListShape()
|
59
|
-
|
60
|
-
# tryMapShape()
|
61
|
-
|
62
|
-
tryConcatList()
|
package/src/test-list.ts
DELETED
@@ -1,271 +0,0 @@
|
|
1
|
-
import {
|
2
|
-
listToString,
|
3
|
-
initTernaryTreeList,
|
4
|
-
initTernaryTreeListFromRange,
|
5
|
-
indexOf,
|
6
|
-
findIndex,
|
7
|
-
reverse,
|
8
|
-
checkListStructure,
|
9
|
-
slice,
|
10
|
-
listToPairs,
|
11
|
-
listToItems,
|
12
|
-
formatListInline,
|
13
|
-
sameListShape,
|
14
|
-
assocBefore,
|
15
|
-
concat,
|
16
|
-
assocAfter,
|
17
|
-
prepend,
|
18
|
-
append,
|
19
|
-
rest,
|
20
|
-
butlast,
|
21
|
-
first,
|
22
|
-
assocList,
|
23
|
-
dissocList,
|
24
|
-
listGet,
|
25
|
-
insert,
|
26
|
-
initEmptyTernaryTreeList,
|
27
|
-
last,
|
28
|
-
listLen,
|
29
|
-
forceListInplaceBalancing,
|
30
|
-
listEqual,
|
31
|
-
indexToItems,
|
32
|
-
listMapValues,
|
33
|
-
} from "./list";
|
34
|
-
|
35
|
-
import { test, check, arrayEqual, checkEqual } from "./utils";
|
36
|
-
|
37
|
-
export let runListTests = () => {
|
38
|
-
test("init list", () => {
|
39
|
-
check(
|
40
|
-
listToString(
|
41
|
-
initTernaryTreeList<number>([1, 2, 3, 4])
|
42
|
-
) === "TernaryTreeList[4, ...]"
|
43
|
-
);
|
44
|
-
|
45
|
-
let origin11 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
|
46
|
-
let data11 = initTernaryTreeList<number>(origin11);
|
47
|
-
|
48
|
-
check(checkListStructure(data11));
|
49
|
-
|
50
|
-
checkEqual(formatListInline(data11), "((1 (2 3 _) 4) (5 6 7) (8 (9 10 _) 11))");
|
51
|
-
check(
|
52
|
-
arrayEqual<number>(origin11, [...listToItems(data11)])
|
53
|
-
);
|
54
|
-
|
55
|
-
check(arrayEqual<number>([...listToItems(data11)], [...indexToItems(data11)]));
|
56
|
-
|
57
|
-
let emptyXs = new Array<number>(0);
|
58
|
-
check(listEqual(initEmptyTernaryTreeList<number>(), initTernaryTreeList(emptyXs)));
|
59
|
-
});
|
60
|
-
|
61
|
-
test("list operations", () => {
|
62
|
-
let origin11 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
|
63
|
-
let data11 = initTernaryTreeList<number>(origin11);
|
64
|
-
|
65
|
-
// get
|
66
|
-
for (let idx = 0; idx < origin11.length; idx++) {
|
67
|
-
check(origin11[idx] === listGet(data11, idx));
|
68
|
-
}
|
69
|
-
|
70
|
-
check(first(data11) === 1);
|
71
|
-
check(last(data11) === 11);
|
72
|
-
|
73
|
-
// assoc
|
74
|
-
let origin5 = [1, 2, 3, 4, 5];
|
75
|
-
let data5 = initTernaryTreeList(origin5);
|
76
|
-
let updated = assocList(data5, 3, 10);
|
77
|
-
check(listGet(updated, 3) === 10);
|
78
|
-
check(listGet(data5, 3) === 4);
|
79
|
-
check(listLen(updated) === listLen(data5));
|
80
|
-
|
81
|
-
for (let idx = 0; idx < listLen(data5); idx++) {
|
82
|
-
// echo data5.dissoc(idx).formatInline
|
83
|
-
check(listLen(dissocList(data5, idx)) === listLen(data5) - 1);
|
84
|
-
}
|
85
|
-
|
86
|
-
checkEqual(formatListInline(data5), "((1 2 _) 3 (4 5 _))");
|
87
|
-
checkEqual(formatListInline(dissocList(data5, 0)), "(2 3 (4 5 _))");
|
88
|
-
checkEqual(formatListInline(dissocList(data5, 1)), "(1 3 (4 5 _))");
|
89
|
-
checkEqual(formatListInline(dissocList(data5, 2)), "((1 2 _) (4 5 _) _)");
|
90
|
-
checkEqual(formatListInline(dissocList(data5, 3)), "((1 2 _) 3 5)");
|
91
|
-
checkEqual(formatListInline(dissocList(data5, 4)), "((1 2 _) 3 4)");
|
92
|
-
|
93
|
-
checkEqual(formatListInline(rest(initTernaryTreeList([1]))), "_");
|
94
|
-
checkEqual(formatListInline(rest(initTernaryTreeList([1, 2]))), "2");
|
95
|
-
checkEqual(formatListInline(rest(initTernaryTreeList([1, 2, 3]))), "(2 3 _)");
|
96
|
-
checkEqual(formatListInline(rest(initTernaryTreeList([1, 2, 3, 4]))), "((2 3 _) 4 _)");
|
97
|
-
checkEqual(formatListInline(rest(initTernaryTreeList([1, 2, 3, 4, 5]))), "(2 3 (4 5 _))");
|
98
|
-
|
99
|
-
checkEqual(formatListInline(butlast(initTernaryTreeList([1]))), "_");
|
100
|
-
checkEqual(formatListInline(butlast(initTernaryTreeList([1, 2]))), "1");
|
101
|
-
checkEqual(formatListInline(butlast(initTernaryTreeList([1, 2, 3]))), "(1 2 _)");
|
102
|
-
checkEqual(formatListInline(butlast(initTernaryTreeList([1, 2, 3, 4]))), "(1 (2 3 _) _)");
|
103
|
-
checkEqual(formatListInline(butlast(initTernaryTreeList([1, 2, 3, 4, 5]))), "((1 2 _) 3 4)");
|
104
|
-
});
|
105
|
-
|
106
|
-
test("list insertions", () => {
|
107
|
-
let origin5 = [1, 2, 3, 4, 5];
|
108
|
-
let data5 = initTernaryTreeList(origin5);
|
109
|
-
|
110
|
-
checkEqual(formatListInline(data5), "((1 2 _) 3 (4 5 _))");
|
111
|
-
|
112
|
-
checkEqual(formatListInline(insert(data5, 0, 10, false)), "(10 ((1 2 _) 3 (4 5 _)) _)");
|
113
|
-
checkEqual(formatListInline(insert(data5, 0, 10, true)), "((1 10 2) 3 (4 5 _))");
|
114
|
-
checkEqual(formatListInline(insert(data5, 1, 10, false)), "((1 10 2) 3 (4 5 _))");
|
115
|
-
checkEqual(formatListInline(insert(data5, 1, 10, true)), "((1 2 10) 3 (4 5 _))");
|
116
|
-
checkEqual(formatListInline(insert(data5, 2, 10, false)), "((1 2 _) (10 3 _) (4 5 _))");
|
117
|
-
checkEqual(formatListInline(insert(data5, 2, 10, true)), "((1 2 _) (3 10 _) (4 5 _))");
|
118
|
-
checkEqual(formatListInline(insert(data5, 3, 10, false)), "((1 2 _) 3 (10 4 5))");
|
119
|
-
checkEqual(formatListInline(insert(data5, 3, 10, true)), "((1 2 _) 3 (4 10 5))");
|
120
|
-
checkEqual(formatListInline(insert(data5, 4, 10, false)), "((1 2 _) 3 (4 10 5))");
|
121
|
-
checkEqual(formatListInline(insert(data5, 4, 10, true)), "(((1 2 _) 3 (4 5 _)) 10 _)");
|
122
|
-
|
123
|
-
let origin4 = [1, 2, 3, 4];
|
124
|
-
let data4 = initTernaryTreeList(origin4);
|
125
|
-
|
126
|
-
checkEqual(formatListInline(assocBefore(data4, 3, 10)), "(1 (2 3 _) (10 4 _))");
|
127
|
-
checkEqual(formatListInline(assocAfter(data4, 3, 10)), "(1 (2 3 _) (4 10 _))");
|
128
|
-
|
129
|
-
checkEqual(formatListInline(prepend(data4, 10)), "((10 1 _) (2 3 _) 4)");
|
130
|
-
checkEqual(formatListInline(append(data4, 10)), "(1 (2 3 _) (4 10 _))");
|
131
|
-
});
|
132
|
-
|
133
|
-
test("concat", () => {
|
134
|
-
let data1 = initTernaryTreeList([1, 2]);
|
135
|
-
let data2 = initTernaryTreeList([3, 4]);
|
136
|
-
|
137
|
-
let data3 = initTernaryTreeList([5, 6]);
|
138
|
-
let data4 = initTernaryTreeList([7, 8]);
|
139
|
-
|
140
|
-
check(formatListInline(concat(data1, data2)) === "((1 2 _) (3 4 _) _)");
|
141
|
-
check(formatListInline(concat(initTernaryTreeList<number>([]), data1)) === "(1 2 _)");
|
142
|
-
check(formatListInline(concat(data1, data2, data3)) === "((1 2 _) (3 4 _) (5 6 _))");
|
143
|
-
check(formatListInline(concat(data1, data2, data3, data4)) === "((1 2 _) ((3 4 _) (5 6 _) _) (7 8 _))");
|
144
|
-
|
145
|
-
checkListStructure(concat(data1, data2));
|
146
|
-
checkListStructure(concat(data1, data2, data3));
|
147
|
-
checkListStructure(concat(data1, data2, data3, data4));
|
148
|
-
|
149
|
-
check(listLen(concat(data1, data2, data3, data4)) === 8);
|
150
|
-
});
|
151
|
-
|
152
|
-
test("check(equality", () => {
|
153
|
-
let origin4 = [1, 2, 3, 4];
|
154
|
-
let data4 = initTernaryTreeList(origin4);
|
155
|
-
let data4n = initTernaryTreeList(origin4);
|
156
|
-
let data4Made = prepend(initTernaryTreeList([2, 3, 4]), 1);
|
157
|
-
|
158
|
-
check(sameListShape(data4, data4) === true);
|
159
|
-
check(sameListShape(data4, data4n) === true);
|
160
|
-
check(sameListShape(data4, data4Made) === false);
|
161
|
-
|
162
|
-
check(listEqual(data4, data4n));
|
163
|
-
check(listEqual(data4, data4Made));
|
164
|
-
check(listEqual(data4n, data4Made));
|
165
|
-
check(data4 !== data4Made); // identical false
|
166
|
-
});
|
167
|
-
|
168
|
-
test("force balancing", () => {
|
169
|
-
var data = initTernaryTreeList<number>([]);
|
170
|
-
for (let idx = 0; idx < 20; idx++) {
|
171
|
-
data = append(data, idx, true);
|
172
|
-
}
|
173
|
-
// echo data.formatInline
|
174
|
-
check(formatListInline(data) === "(((0 1 2) (3 4 5) (6 7 8)) ((9 10 11) (12 13 14) (15 16 17)) (18 19 _))");
|
175
|
-
forceListInplaceBalancing(data);
|
176
|
-
check(formatListInline(data) === "(((0 1 _) (2 3 4) (5 6 _)) ((7 8 _) (9 10 _) (11 12 _)) ((13 14 _) (15 16 17) (18 19 _)))");
|
177
|
-
// echo data.formatInline
|
178
|
-
});
|
179
|
-
|
180
|
-
test("iterator", () => {
|
181
|
-
let origin4 = [1, 2, 3, 4];
|
182
|
-
let data4 = initTernaryTreeList(origin4);
|
183
|
-
|
184
|
-
var i = 0;
|
185
|
-
for (let item of listToItems(data4)) {
|
186
|
-
i = i + 1;
|
187
|
-
}
|
188
|
-
|
189
|
-
check(i === 4);
|
190
|
-
|
191
|
-
i = 0;
|
192
|
-
for (let [idx, item] of listToPairs(data4)) {
|
193
|
-
i = i + idx;
|
194
|
-
}
|
195
|
-
|
196
|
-
check(i === 6);
|
197
|
-
});
|
198
|
-
|
199
|
-
test("check structure", () => {
|
200
|
-
var data = initTernaryTreeList<number>([]);
|
201
|
-
for (let idx = 0; idx < 20; idx++) {
|
202
|
-
data = append(data, idx, true);
|
203
|
-
}
|
204
|
-
|
205
|
-
check(checkListStructure(data));
|
206
|
-
|
207
|
-
let origin11 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
|
208
|
-
let data11 = initTernaryTreeList<number>(origin11);
|
209
|
-
|
210
|
-
check(checkListStructure(data11));
|
211
|
-
});
|
212
|
-
|
213
|
-
test("slices", () => {
|
214
|
-
var data = initTernaryTreeList<number>([]);
|
215
|
-
for (let idx = 0; idx < 40; idx++) {
|
216
|
-
data = append(data, idx, true);
|
217
|
-
}
|
218
|
-
|
219
|
-
var list40: Array<number> = [];
|
220
|
-
for (let idx = 0; idx < 40; idx++) {
|
221
|
-
list40.push(idx);
|
222
|
-
}
|
223
|
-
|
224
|
-
for (let i = 0; i < 40; i++) {
|
225
|
-
for (let j = i; j < 40; j++) {
|
226
|
-
check(arrayEqual<number>([...listToItems(slice(data, i, j))], list40.slice(i, j)));
|
227
|
-
}
|
228
|
-
}
|
229
|
-
});
|
230
|
-
|
231
|
-
test("reverse", () => {
|
232
|
-
let data = initTernaryTreeList([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
233
|
-
let reversedData = reverse(data);
|
234
|
-
check(arrayEqual([...listToItems(data)].reverse(), [...listToItems(reversedData)]));
|
235
|
-
check(checkListStructure(reversedData));
|
236
|
-
});
|
237
|
-
|
238
|
-
test("list traverse", () => {
|
239
|
-
var i = 0;
|
240
|
-
let data = initTernaryTreeList<number>([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
241
|
-
for (let x of listToItems(data)) {
|
242
|
-
i = i + 1;
|
243
|
-
}
|
244
|
-
|
245
|
-
check(i === 10);
|
246
|
-
});
|
247
|
-
|
248
|
-
test("index of", () => {
|
249
|
-
let data = initTernaryTreeList<number>([1, 2, 3, 4, 5, 6, 7, 8]);
|
250
|
-
check(indexOf(data, 2) === 1);
|
251
|
-
check(findIndex(data, (x: number): boolean => x === 2) === 1);
|
252
|
-
check(indexOf(data, 9) === -1);
|
253
|
-
check(findIndex(data, (x: number): boolean => x === 9) === -1);
|
254
|
-
});
|
255
|
-
|
256
|
-
test("map values", () => {
|
257
|
-
let data = initTernaryTreeList<number>([1, 2, 3, 4]);
|
258
|
-
let data2 = initTernaryTreeList<number>([1, 4, 9, 16]);
|
259
|
-
let data3 = listMapValues(data, (x) => x * x);
|
260
|
-
|
261
|
-
checkListStructure(data3);
|
262
|
-
check(listEqual(data2, data3));
|
263
|
-
check(formatListInline(data2) === formatListInline(data3));
|
264
|
-
});
|
265
|
-
|
266
|
-
test("concat", () => {
|
267
|
-
let data1 = initTernaryTreeList([3, 4]);
|
268
|
-
let data2 = initTernaryTreeListFromRange([1, 2, 3, 4, 5, 6], 2, 4);
|
269
|
-
check(listEqual(data1, data2));
|
270
|
-
});
|
271
|
-
};
|
package/src/test-map.ts
DELETED
@@ -1,288 +0,0 @@
|
|
1
|
-
import { hashGenerator } from "./types";
|
2
|
-
import { test, check, cmp, deepEqual, justDisplay } from "./utils";
|
3
|
-
import {
|
4
|
-
initTernaryTreeMap,
|
5
|
-
initTernaryTreeMapFromArray,
|
6
|
-
toHashSortedPairs,
|
7
|
-
merge,
|
8
|
-
mergeSkip,
|
9
|
-
forceMapInplaceBalancing,
|
10
|
-
formatMapInline,
|
11
|
-
assocMap,
|
12
|
-
dissocMap,
|
13
|
-
contains,
|
14
|
-
toPairs,
|
15
|
-
initEmptyTernaryTreeMap,
|
16
|
-
sameMapShape,
|
17
|
-
checkMapStructure,
|
18
|
-
mapLen,
|
19
|
-
mapToString,
|
20
|
-
mapEqual,
|
21
|
-
toKeys,
|
22
|
-
toPairsArray,
|
23
|
-
mapMapValues,
|
24
|
-
mapGetDefault,
|
25
|
-
} from "./map";
|
26
|
-
|
27
|
-
export let runMapTests = () => {
|
28
|
-
test("init map", () => {
|
29
|
-
var dict: Map<string, number> = new Map();
|
30
|
-
var inList: Array<[string, number]> = [];
|
31
|
-
for (let idx = 0; idx < 10; idx++) {
|
32
|
-
dict.set(`${idx}`, idx + 10);
|
33
|
-
inList.push([`${idx}`, idx + 10]);
|
34
|
-
}
|
35
|
-
|
36
|
-
// TODO
|
37
|
-
inList.sort((x, y: [string, number]): number => {
|
38
|
-
let hx = hashGenerator(x[0]);
|
39
|
-
let hy = hashGenerator(y[0]);
|
40
|
-
return cmp(hx, hy);
|
41
|
-
});
|
42
|
-
|
43
|
-
let data10 = initTernaryTreeMap<string, number>(dict);
|
44
|
-
let data11 = initTernaryTreeMapFromArray<string, number>(inList);
|
45
|
-
checkMapStructure(data10);
|
46
|
-
checkMapStructure(data11);
|
47
|
-
|
48
|
-
// echo data10
|
49
|
-
justDisplay(formatMapInline(data10, true), " ((0:10 1:11 2:12) (3:13 (4:14 5:15 _) 6:16) (7:17 8:18 9:19))");
|
50
|
-
|
51
|
-
check(deepEqual(toHashSortedPairs(data10), inList));
|
52
|
-
check(deepEqual(toHashSortedPairs(data11), inList));
|
53
|
-
|
54
|
-
check(contains(data10, "1") === true);
|
55
|
-
check(contains(data10, "11") === false);
|
56
|
-
|
57
|
-
check(deepEqual(mapGetDefault(data10, "1", null), 11));
|
58
|
-
check(deepEqual(mapGetDefault(data10, "111", 0), 0));
|
59
|
-
// check(deepEqual(mapGetDefault(data10, "11", {} as any), null)); // should throws error
|
60
|
-
|
61
|
-
let emptyData: Map<string, number> = new Map();
|
62
|
-
check(mapEqual(initEmptyTernaryTreeMap<string, number>(), initTernaryTreeMap(emptyData)));
|
63
|
-
});
|
64
|
-
|
65
|
-
test("assoc and contains", () => {
|
66
|
-
var dict: Map<string, number> = new Map();
|
67
|
-
for (let idx = 0; idx < 100; idx++) {
|
68
|
-
dict.set(`${idx * 2}`, idx);
|
69
|
-
}
|
70
|
-
let data = initTernaryTreeMap(dict);
|
71
|
-
for (let idx = 0; idx < 100; idx++) {
|
72
|
-
dict.set(`${idx * 2 + 1}`, idx);
|
73
|
-
let data2 = assocMap(data, `${idx * 2 + 1}`, idx);
|
74
|
-
check(contains(data2, `${idx * 2 + 1}`));
|
75
|
-
}
|
76
|
-
|
77
|
-
var dict: Map<string, number> = new Map();
|
78
|
-
data = initTernaryTreeMap(dict);
|
79
|
-
for (let idx = 0; idx < 1000; idx++) {
|
80
|
-
let p = 100 - idx / 10;
|
81
|
-
data = assocMap(data, `${p}`, idx);
|
82
|
-
check(contains(data, `${p}`));
|
83
|
-
}
|
84
|
-
});
|
85
|
-
|
86
|
-
test("check structure", () => {
|
87
|
-
var dict: Map<string, number> = new Map();
|
88
|
-
for (let idx = 0; idx < 100; idx++) {
|
89
|
-
dict.set(`${idx}`, idx + 10);
|
90
|
-
}
|
91
|
-
|
92
|
-
let data = initTernaryTreeMap(dict);
|
93
|
-
|
94
|
-
check(checkMapStructure(data));
|
95
|
-
});
|
96
|
-
|
97
|
-
test("assoc map", () => {
|
98
|
-
var dict: Map<string, number> = new Map();
|
99
|
-
for (let idx = 0; idx < 10; idx++) {
|
100
|
-
dict.set(`${idx}`, idx + 10);
|
101
|
-
}
|
102
|
-
|
103
|
-
let data = initTernaryTreeMap(dict);
|
104
|
-
|
105
|
-
// echo data.formatInline
|
106
|
-
|
107
|
-
check(contains(data, "1") === true);
|
108
|
-
check(contains(data, "12") === false);
|
109
|
-
checkMapStructure(data);
|
110
|
-
|
111
|
-
justDisplay(formatMapInline(assocMap(data, "1", 2222), true), "((0:10 1:2222 2:12) (3:13 (4:14 5:15 _) 6:16) (7:17 8:18 9:19))");
|
112
|
-
justDisplay(formatMapInline(assocMap(data, "23", 2222), true), "(((0:10 1:11 2:12) (3:13 (4:14 5:15 _) 6:16) (7:17 8:18 9:19)) 23:2222 _)");
|
113
|
-
});
|
114
|
-
|
115
|
-
test("dissoc", () => {
|
116
|
-
var dict: Map<string, number> = new Map();
|
117
|
-
for (let idx = 0; idx < 10; idx++) {
|
118
|
-
dict.set(`${idx}`, idx + 10);
|
119
|
-
}
|
120
|
-
|
121
|
-
let data = initTernaryTreeMap(dict);
|
122
|
-
checkMapStructure(data);
|
123
|
-
|
124
|
-
// echo data.formatInline
|
125
|
-
|
126
|
-
for (let idx = 0; idx < 10; idx++) {
|
127
|
-
let v = dissocMap(data, `${idx}`);
|
128
|
-
check(contains(v, `${idx}`) === false);
|
129
|
-
check(contains(data, `${idx}`) === true);
|
130
|
-
check(mapLen(v) === mapLen(data) - 1);
|
131
|
-
}
|
132
|
-
|
133
|
-
for (let idx = 10; idx < 12; idx++) {
|
134
|
-
let v = dissocMap(data, `${idx}`);
|
135
|
-
check(contains(v, `${idx}`) === false);
|
136
|
-
check(mapLen(v) === mapLen(data));
|
137
|
-
}
|
138
|
-
});
|
139
|
-
|
140
|
-
test("to array", () => {
|
141
|
-
var dict: Map<string, number> = new Map();
|
142
|
-
for (let idx = 0; idx < 10; idx++) {
|
143
|
-
dict.set(`${idx}`, idx + 10);
|
144
|
-
}
|
145
|
-
|
146
|
-
let data = initTernaryTreeMap(dict);
|
147
|
-
checkMapStructure(data);
|
148
|
-
|
149
|
-
// TODO
|
150
|
-
// justDisplay((mapToString(toPairs(data))) , "@[2:12, 3:13, 7:17, 9:19, 6:16, 5:15, 1:11, 8:18, 0:10, 4:14]")
|
151
|
-
justDisplay([...toKeys(data)], ["2", "3", "7", "9", "6", "5", "1", "8", "0", "4"]);
|
152
|
-
|
153
|
-
check(deepEqual(toPairsArray(data), [...toPairs(data)]));
|
154
|
-
});
|
155
|
-
|
156
|
-
test("Equality", () => {
|
157
|
-
var dict: Map<string, number> = new Map();
|
158
|
-
for (let idx = 0; idx < 10; idx++) {
|
159
|
-
dict.set(`${idx}`, idx + 10);
|
160
|
-
}
|
161
|
-
|
162
|
-
let data = initTernaryTreeMap(dict);
|
163
|
-
let b = dissocMap(data, "3");
|
164
|
-
checkMapStructure(data);
|
165
|
-
checkMapStructure(b);
|
166
|
-
|
167
|
-
check(mapEqual(data, data));
|
168
|
-
check(!mapEqual(data, b));
|
169
|
-
|
170
|
-
let c = assocMap(data, "3", 15);
|
171
|
-
check(sameMapShape(data, data));
|
172
|
-
check(sameMapShape(data, b) === false);
|
173
|
-
check(sameMapShape(data, c) === false);
|
174
|
-
|
175
|
-
let d = assocMap(c, "3", 13);
|
176
|
-
check(mapEqual(data, d));
|
177
|
-
check(data !== d); // not identical
|
178
|
-
});
|
179
|
-
|
180
|
-
test("Merge", () => {
|
181
|
-
var dict: Map<string, number> = new Map();
|
182
|
-
var dictBoth: Map<string, number> = new Map();
|
183
|
-
for (let idx = 0; idx < 4; idx++) {
|
184
|
-
dict.set(`${idx}`, idx + 10);
|
185
|
-
dictBoth.set(`${idx}`, idx + 10);
|
186
|
-
}
|
187
|
-
|
188
|
-
let data = initTernaryTreeMap(dict);
|
189
|
-
checkMapStructure(data);
|
190
|
-
|
191
|
-
var dictB: Map<string, number> = new Map();
|
192
|
-
for (let idx = 10; idx < 14; idx++) {
|
193
|
-
dictB.set(`${idx}`, idx + 23);
|
194
|
-
dictBoth.set(`${idx}`, idx + 23);
|
195
|
-
}
|
196
|
-
let b = initTernaryTreeMap(dictB);
|
197
|
-
|
198
|
-
let merged = merge(data, b);
|
199
|
-
let both = initTernaryTreeMap(dictBoth);
|
200
|
-
|
201
|
-
check(mapEqual(merged, both));
|
202
|
-
});
|
203
|
-
|
204
|
-
test("Merge skip", () => {
|
205
|
-
var dict: Map<string, number> = new Map();
|
206
|
-
for (let idx = 0; idx < 4; idx++) {
|
207
|
-
dict.set(`${idx}`, idx + 10);
|
208
|
-
}
|
209
|
-
let a = initTernaryTreeMap(dict);
|
210
|
-
checkMapStructure(a);
|
211
|
-
|
212
|
-
var dict2: Map<string, number> = new Map();
|
213
|
-
for (let idx = 0; idx < 4; idx++) {
|
214
|
-
dict2.set(`${idx}`, idx + 11);
|
215
|
-
}
|
216
|
-
let b = initTernaryTreeMap(dict2);
|
217
|
-
checkMapStructure(b);
|
218
|
-
|
219
|
-
let c = mergeSkip(a, b, 11);
|
220
|
-
check(deepEqual(mapGetDefault(c, "0", null), 10));
|
221
|
-
check(deepEqual(mapGetDefault(c, "1", null), 12));
|
222
|
-
check(deepEqual(mapGetDefault(c, "2", null), 13));
|
223
|
-
check(deepEqual(mapGetDefault(c, "3", null), 14));
|
224
|
-
});
|
225
|
-
|
226
|
-
test("iterator", () => {
|
227
|
-
var dict: Map<string, number> = new Map();
|
228
|
-
var dictBoth: Map<string, number> = new Map();
|
229
|
-
for (let idx = 0; idx < 4; idx++) {
|
230
|
-
dict.set(`${idx}`, idx + 10);
|
231
|
-
dictBoth.set(`${idx}`, idx + 10);
|
232
|
-
}
|
233
|
-
|
234
|
-
let data = initTernaryTreeMap(dict);
|
235
|
-
checkMapStructure(data);
|
236
|
-
|
237
|
-
var i = 0;
|
238
|
-
for (let [k, v] of toPairs(data)) {
|
239
|
-
i = i + 1;
|
240
|
-
}
|
241
|
-
|
242
|
-
check(i === 4);
|
243
|
-
|
244
|
-
i = 0;
|
245
|
-
for (let key of toPairs(data)) {
|
246
|
-
i = i + 1;
|
247
|
-
}
|
248
|
-
check(i === 4);
|
249
|
-
});
|
250
|
-
|
251
|
-
test("each map", () => {
|
252
|
-
var dict: Map<string, number> = new Map();
|
253
|
-
for (let idx = 0; idx < 100; idx++) {
|
254
|
-
dict.set(`${idx}`, idx + 10);
|
255
|
-
}
|
256
|
-
|
257
|
-
let data = initTernaryTreeMap(dict);
|
258
|
-
checkMapStructure(data);
|
259
|
-
|
260
|
-
var i = 0;
|
261
|
-
for (let [k, v] of toPairs(data)) {
|
262
|
-
// echo "..{k}-{v}.."
|
263
|
-
i = i + 1;
|
264
|
-
}
|
265
|
-
check(i === 100);
|
266
|
-
});
|
267
|
-
|
268
|
-
test("map values", () => {
|
269
|
-
var dict: Map<string, number> = new Map();
|
270
|
-
for (let idx = 0; idx < 4; idx++) {
|
271
|
-
dict.set(`${idx}`, idx + 10);
|
272
|
-
}
|
273
|
-
let data = initTernaryTreeMap(dict);
|
274
|
-
|
275
|
-
var dict2: Map<string, number> = new Map();
|
276
|
-
for (let idx = 0; idx < 4; idx++) {
|
277
|
-
dict2.set(`${idx}`, idx + 20);
|
278
|
-
}
|
279
|
-
let data2 = initTernaryTreeMap(dict2);
|
280
|
-
|
281
|
-
let data3 = mapMapValues(data, (x) => x + 10);
|
282
|
-
checkMapStructure(data3);
|
283
|
-
|
284
|
-
checkMapStructure(data3);
|
285
|
-
check(mapEqual(data2, data3));
|
286
|
-
check(formatMapInline(data2) === formatMapInline(data3));
|
287
|
-
});
|
288
|
-
};
|
package/src/types.ts
DELETED
@@ -1,87 +0,0 @@
|
|
1
|
-
export enum TernaryTreeKind {
|
2
|
-
ternaryTreeBranch,
|
3
|
-
ternaryTreeLeaf,
|
4
|
-
}
|
5
|
-
|
6
|
-
export type TernaryTreeListTheBranch<T> = {
|
7
|
-
size: number;
|
8
|
-
kind: TernaryTreeKind.ternaryTreeBranch;
|
9
|
-
depth: number;
|
10
|
-
left: TernaryTreeList<T>;
|
11
|
-
middle: TernaryTreeList<T>;
|
12
|
-
right: TernaryTreeList<T>;
|
13
|
-
};
|
14
|
-
|
15
|
-
export type TernaryTreeListTheLeaf<T> = {
|
16
|
-
size: number;
|
17
|
-
kind: TernaryTreeKind.ternaryTreeLeaf;
|
18
|
-
value: T;
|
19
|
-
};
|
20
|
-
|
21
|
-
export type TernaryTreeList<T> = TernaryTreeListTheBranch<T> | TernaryTreeListTheLeaf<T>;
|
22
|
-
|
23
|
-
export type TernaryTreeMapHashEntry<K, V> = {
|
24
|
-
hash: Hash;
|
25
|
-
pairs: Array<[K, V]>;
|
26
|
-
};
|
27
|
-
|
28
|
-
export type TernaryTreeMapTheBranch<K, T> = {
|
29
|
-
kind: TernaryTreeKind.ternaryTreeBranch;
|
30
|
-
depth: number;
|
31
|
-
maxHash: number;
|
32
|
-
minHash: number;
|
33
|
-
left: TernaryTreeMap<K, T>;
|
34
|
-
middle: TernaryTreeMap<K, T>;
|
35
|
-
right: TernaryTreeMap<K, T>;
|
36
|
-
};
|
37
|
-
export type TernaryTreeMapTheLeaf<K, T> = {
|
38
|
-
kind: TernaryTreeKind.ternaryTreeLeaf;
|
39
|
-
hash: number;
|
40
|
-
elements: Array<[K, T]>; // handle hash collapsing
|
41
|
-
};
|
42
|
-
|
43
|
-
export type TernaryTreeMap<K, T> = TernaryTreeMapTheBranch<K, T> | TernaryTreeMapTheLeaf<K, T>;
|
44
|
-
|
45
|
-
export type RefInt = {
|
46
|
-
value: number;
|
47
|
-
};
|
48
|
-
|
49
|
-
export type Hash = number; // TODO
|
50
|
-
|
51
|
-
export let valueHash = (x: any): Hash => {
|
52
|
-
if (typeof x === "number") {
|
53
|
-
// console.log("hash for x:", x, "\t", result);
|
54
|
-
return x;
|
55
|
-
} else if (typeof x === "string") {
|
56
|
-
let h = 0;
|
57
|
-
// https://gist.github.com/hyamamoto/fd435505d29ebfa3d9716fd2be8d42f0#gistcomment-2775538
|
58
|
-
for (var i = 0; i < x.length; i++) {
|
59
|
-
h = Math.imul(31, h) + (x[i].charCodeAt(0) | 0);
|
60
|
-
}
|
61
|
-
// console.log("hash for x:", x, "\t", result);
|
62
|
-
return h;
|
63
|
-
}
|
64
|
-
throw new Error("Hash solution not provided for this type(other than number and string)");
|
65
|
-
};
|
66
|
-
|
67
|
-
/** default hash function only handles number and string, need customization */
|
68
|
-
export let hashGenerator: typeof valueHash = valueHash;
|
69
|
-
|
70
|
-
/** allow customizing hash function from outside */
|
71
|
-
export let overwriteHashGenerator = (f: typeof hashGenerator) => {
|
72
|
-
hashGenerator = f;
|
73
|
-
};
|
74
|
-
|
75
|
-
export let mergeValueHash = (base: Hash, x: number | string): Hash => {
|
76
|
-
if (typeof x === "number") {
|
77
|
-
return Math.imul(31, base) + x;
|
78
|
-
} else if (typeof x === "string") {
|
79
|
-
let h = base;
|
80
|
-
// https://gist.github.com/hyamamoto/fd435505d29ebfa3d9716fd2be8d42f0#gistcomment-2775538
|
81
|
-
for (var i = 0; i < x.length; i++) {
|
82
|
-
h = Math.imul(31, h) + (x[i].charCodeAt(0) | 0);
|
83
|
-
}
|
84
|
-
return h;
|
85
|
-
}
|
86
|
-
throw new Error("Hash solution not provided for this type(other than number and string)");
|
87
|
-
};
|