functionalscript 0.0.283 → 0.0.287
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/package.json +1 -1
- package/types/array/index.js +12 -0
- package/types/btree/find/index.js +104 -0
- package/types/btree/find/test.js +119 -0
- package/types/btree/set/index.js +39 -0
- package/types/btree/test.js +2 -0
- package/types/list/test.js +9 -0
package/package.json
CHANGED
package/types/array/index.js
CHANGED
|
@@ -54,6 +54,18 @@ const seq = require('../list')
|
|
|
54
54
|
|
|
55
55
|
/** @typedef {0|1|2|3|4} Index5 */
|
|
56
56
|
|
|
57
|
+
/**
|
|
58
|
+
* @template T
|
|
59
|
+
* @typedef {T extends Array1<infer _> ? Index1 :
|
|
60
|
+
* T extends Array2<infer _> ? Index2 :
|
|
61
|
+
* T extends Array3<infer _> ? Index3 :
|
|
62
|
+
* T extends Array4<infer _> ? Index4 :
|
|
63
|
+
* T extends Array5<infer _> ? Index5 :
|
|
64
|
+
* T extends readonly (infer _)[] ? number :
|
|
65
|
+
* never
|
|
66
|
+
* } KeyOf
|
|
67
|
+
*/
|
|
68
|
+
|
|
57
69
|
/** @type {<T>(_: readonly T[]) => readonly T[]} */
|
|
58
70
|
const uncheckTail = a => a.slice(1)
|
|
59
71
|
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
const _ = require('..')
|
|
2
|
+
const list = require('../../list')
|
|
3
|
+
const cmp = require('../../function/compare')
|
|
4
|
+
const array = require('../../array')
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @template T
|
|
8
|
+
* @typedef {readonly[cmp.Index3, _.Leaf1<T>]} FirstLeaf1
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @template T
|
|
13
|
+
* @typedef {readonly[1, _.Branch3<T>]} FirstBranch3
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @template T
|
|
18
|
+
* @typedef {readonly[cmp.Index5, _.Leaf2<T>]} FirstLeaf2
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @template T
|
|
23
|
+
* @typedef {readonly[1|3, _.Branch5<T>]} FirstBranch5
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @template T
|
|
28
|
+
* @typedef {FirstLeaf1<T> | FirstBranch3<T> | FirstLeaf2<T> | FirstBranch5<T>} First
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @template T
|
|
33
|
+
* @typedef {readonly[0|2, _.Branch3<T>]} PathItem3
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @template T
|
|
38
|
+
* @typedef {readonly[0|2|4, _.Branch5<T>]} PathItem5
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @template T
|
|
43
|
+
* @typedef {PathItem3<T> | PathItem5<T>} PathItem
|
|
44
|
+
*/
|
|
45
|
+
|
|
46
|
+
/** @type {<T>(item: PathItem<T>) => _.Node<T>} */
|
|
47
|
+
const child = item => {
|
|
48
|
+
/** @typedef {typeof item extends PathItem<infer T> ? T : never} T */
|
|
49
|
+
return /** @type {_.Node<T>} */(item[1][item[0]])
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @template T
|
|
54
|
+
* @typedef {list.List<PathItem<T>>} Path
|
|
55
|
+
*/
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @template T
|
|
59
|
+
* @typedef {{
|
|
60
|
+
* readonly first: First<T>,
|
|
61
|
+
* readonly tail: Path<T>
|
|
62
|
+
* }} Result<T>
|
|
63
|
+
*/
|
|
64
|
+
|
|
65
|
+
/** @type {<T>(c: cmp.Compare<T>) => (node: _.Node<T>) => Result<T>} */
|
|
66
|
+
const find = c => {
|
|
67
|
+
const i3 = cmp.index3(c)
|
|
68
|
+
const i5 = cmp.index5(c)
|
|
69
|
+
/** @typedef {typeof c extends cmp.Compare<infer T> ? T : never} T */
|
|
70
|
+
/** @type {(prior: Path<T>) => (node: _.Node<T>) => Result<T>} */
|
|
71
|
+
const f = tail => node => {
|
|
72
|
+
/** @type {(index: array.KeyOf<typeof node>) => Result<T>} */
|
|
73
|
+
const append = index => {
|
|
74
|
+
const first = /** @type {PathItem<T>} */([index, node])
|
|
75
|
+
return f({ first, tail })(child(first))
|
|
76
|
+
}
|
|
77
|
+
/** @type {(index: array.KeyOf<typeof node>) => Result<T>} */
|
|
78
|
+
const done = index => ({ first: /** @type {First<T>} */([index, node]), tail })
|
|
79
|
+
switch (node.length) {
|
|
80
|
+
case 1: { return done(i3(node[0])) }
|
|
81
|
+
case 2: { return done(i5(node)) }
|
|
82
|
+
case 3: {
|
|
83
|
+
const i = i3(node[1])
|
|
84
|
+
switch (i) {
|
|
85
|
+
case 0: case 2: { return append(i) }
|
|
86
|
+
case 1: { return done(i) }
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
case 5: {
|
|
90
|
+
const i = i5([node[1], node[3]])
|
|
91
|
+
switch (i) {
|
|
92
|
+
case 0: case 2: case 4: { return append(i) }
|
|
93
|
+
case 1: case 3: { return done(i) }
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return f(undefined)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
module.exports = {
|
|
102
|
+
/** @readonly */
|
|
103
|
+
find,
|
|
104
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
const _ = require('.')
|
|
2
|
+
const list = require('../../list')
|
|
3
|
+
const json = require('../../../json')
|
|
4
|
+
const { sort } = require('../../object')
|
|
5
|
+
const btree = require('..')
|
|
6
|
+
const { stringCmp } = require('../../function/compare')
|
|
7
|
+
|
|
8
|
+
const jsonStr = json.stringify(sort)
|
|
9
|
+
|
|
10
|
+
/** @type {(node: btree.Node<string>) => (value: string) => btree.Node<string>} */
|
|
11
|
+
const set = node => value => {
|
|
12
|
+
const result = btree.setVisitor(stringCmp(value))(node)(() => value)
|
|
13
|
+
switch (result[0]) {
|
|
14
|
+
case 'replace': case 'overflow': { return result[1] }
|
|
15
|
+
default: { return node }
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** @type {(r: _.Result<json.Unknown>) => string} */
|
|
20
|
+
const str = r => jsonStr(list.toArray(list.map(x => x[0])(r)))
|
|
21
|
+
|
|
22
|
+
/** @type {(i: string) => (m: btree.Node<string>) => string} */
|
|
23
|
+
const find = i => m => str(_.find(stringCmp(i))(m))
|
|
24
|
+
|
|
25
|
+
{
|
|
26
|
+
/** @type {btree.Node<string>} */
|
|
27
|
+
let _map = ['1']
|
|
28
|
+
for (let i = 2; i <= 10; i++)
|
|
29
|
+
_map = set(_map)((i * i).toString())
|
|
30
|
+
{
|
|
31
|
+
const s = jsonStr(_map)
|
|
32
|
+
if (s !== '[[["1","100"],"16",["25","36"]],"4",[["49"],"64",["81","9"]]]') { throw s }
|
|
33
|
+
}
|
|
34
|
+
//
|
|
35
|
+
{
|
|
36
|
+
const r = find("0")(_map)
|
|
37
|
+
if (r !== '[0,0,0]') { throw r }
|
|
38
|
+
}
|
|
39
|
+
{
|
|
40
|
+
const r = find("1")(_map)
|
|
41
|
+
if (r !== '[1,0,0]') { throw r }
|
|
42
|
+
}
|
|
43
|
+
{
|
|
44
|
+
const r = find("10")(_map)
|
|
45
|
+
if (r !== '[2,0,0]') { throw r }
|
|
46
|
+
}
|
|
47
|
+
{
|
|
48
|
+
const r = find("100")(_map)
|
|
49
|
+
if (r !== '[3,0,0]') { throw r }
|
|
50
|
+
}
|
|
51
|
+
{
|
|
52
|
+
const r = find("12")(_map)
|
|
53
|
+
if (r !== '[4,0,0]') { throw r }
|
|
54
|
+
}
|
|
55
|
+
{
|
|
56
|
+
const r = find("16")(_map)
|
|
57
|
+
if (r !== '[1,0]') { throw r }
|
|
58
|
+
}
|
|
59
|
+
{
|
|
60
|
+
const r = find("17")(_map)
|
|
61
|
+
if (r !== '[0,2,0]') { throw r }
|
|
62
|
+
}
|
|
63
|
+
{
|
|
64
|
+
const r = find("25")(_map)
|
|
65
|
+
if (r !== '[1,2,0]') { throw r }
|
|
66
|
+
}
|
|
67
|
+
{
|
|
68
|
+
const r = find("26")(_map)
|
|
69
|
+
if (r !== '[2,2,0]') { throw r }
|
|
70
|
+
}
|
|
71
|
+
{
|
|
72
|
+
const r = find("36")(_map)
|
|
73
|
+
if (r !== '[3,2,0]') { throw r }
|
|
74
|
+
}
|
|
75
|
+
{
|
|
76
|
+
const r = find("37")(_map)
|
|
77
|
+
if (r !== '[4,2,0]') { throw r }
|
|
78
|
+
}
|
|
79
|
+
{
|
|
80
|
+
const r = find("4")(_map)
|
|
81
|
+
if (r !== '[1]') { throw r }
|
|
82
|
+
}
|
|
83
|
+
{
|
|
84
|
+
const r = find("41")(_map)
|
|
85
|
+
if (r !== '[0,0,2]') { throw r }
|
|
86
|
+
}
|
|
87
|
+
{
|
|
88
|
+
const r = find("49")(_map)
|
|
89
|
+
if (r !== '[1,0,2]') { throw r }
|
|
90
|
+
}
|
|
91
|
+
{
|
|
92
|
+
const r = find("5")(_map)
|
|
93
|
+
if (r !== '[2,0,2]') { throw r }
|
|
94
|
+
}
|
|
95
|
+
{
|
|
96
|
+
const r = find("64")(_map)
|
|
97
|
+
if (r !== '[1,2]') { throw r }
|
|
98
|
+
}
|
|
99
|
+
{
|
|
100
|
+
const r = find("65")(_map)
|
|
101
|
+
if (r !== '[0,2,2]') { throw r }
|
|
102
|
+
}
|
|
103
|
+
{
|
|
104
|
+
const r = find("81")(_map)
|
|
105
|
+
if (r !== '[1,2,2]') { throw r }
|
|
106
|
+
}
|
|
107
|
+
{
|
|
108
|
+
const r = find("85")(_map)
|
|
109
|
+
if (r !== '[2,2,2]') { throw r }
|
|
110
|
+
}
|
|
111
|
+
{
|
|
112
|
+
const r = find("9")(_map)
|
|
113
|
+
if (r !== '[3,2,2]') { throw r }
|
|
114
|
+
}
|
|
115
|
+
{
|
|
116
|
+
const r = find("91")(_map)
|
|
117
|
+
if (r !== '[4,2,2]') { throw r }
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const _ = require('..')
|
|
2
|
+
const { find } = require('../find')
|
|
3
|
+
const cmp = require('../../function/compare')
|
|
4
|
+
const { todo } = require('../../../dev')
|
|
5
|
+
|
|
6
|
+
/** @type {<T>(c: cmp.Compare<T>) => (value: T) => (node: _.Node<T>) => _.Node<T>} */
|
|
7
|
+
const set = c => value => node => {
|
|
8
|
+
const { first, tail } = find(c)(node)
|
|
9
|
+
switch (first[0]) {
|
|
10
|
+
case 0: {
|
|
11
|
+
// x2
|
|
12
|
+
const x = first[1]
|
|
13
|
+
return todo()
|
|
14
|
+
}
|
|
15
|
+
case 1: {
|
|
16
|
+
// x4
|
|
17
|
+
const x = first[1];
|
|
18
|
+
return todo()
|
|
19
|
+
}
|
|
20
|
+
case 2: {
|
|
21
|
+
// x2
|
|
22
|
+
const x = first[1];
|
|
23
|
+
return todo()
|
|
24
|
+
}
|
|
25
|
+
case 3: {
|
|
26
|
+
// x2
|
|
27
|
+
const x = first[1];
|
|
28
|
+
return todo()
|
|
29
|
+
}
|
|
30
|
+
case 4: {
|
|
31
|
+
// x1
|
|
32
|
+
const x = first[1];
|
|
33
|
+
return todo()
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return todo()
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
module.exports = {}
|
package/types/btree/test.js
CHANGED
package/types/list/test.js
CHANGED
|
@@ -337,6 +337,15 @@ const stress = () => {
|
|
|
337
337
|
const len = _.length(_.dropWhile(() => true)(result))
|
|
338
338
|
if (len !== 0) { throw len }
|
|
339
339
|
}
|
|
340
|
+
|
|
341
|
+
console.log('reverse')
|
|
342
|
+
|
|
343
|
+
{
|
|
344
|
+
// 10_000_000 is too much
|
|
345
|
+
const n = 5_000_000
|
|
346
|
+
const result = _.toArray(_.reverse(_.countdown(n)))
|
|
347
|
+
if (result.length !== n) { throw result.length }
|
|
348
|
+
}
|
|
340
349
|
}
|
|
341
350
|
|
|
342
351
|
// stress()
|