functionalscript 0.0.281 → 0.0.285

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "functionalscript",
3
- "version": "0.0.281",
3
+ "version": "0.0.285",
4
4
  "description": "FunctionalScript is a functional subset of JavaScript",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -2,7 +2,7 @@
2
2
 
3
3
  https://en.wikipedia.org/wiki/B-tree
4
4
 
5
- ## BTree 2-3 nodes
5
+ ## BTree 2-3 nodes
6
6
 
7
7
  `Node<T>`:
8
8
 
@@ -66,7 +66,7 @@ Posible actions:
66
66
  |left | 0|`[(L VM R) v1 n2]` |
67
67
  |right | 2|`[n0 v1 (L VM R)]` |
68
68
 
69
- ## Branch5 Overflow
69
+ ## Branch5 Overflow
70
70
 
71
71
  - current `[n0, v1, n2, v3, n4]`
72
72
  - overflow `[L, VM, R]`
@@ -76,3 +76,83 @@ Posible actions:
76
76
  |left | 0|`[...o v1 n2 v3 n4]`|`[(L VM R) v1 n2 v3 n4]`|`[[ L VM R ] v1 [n2 v3 n4]]`|
77
77
  |middle| 2|`[n0 v1 ...o v3 n4]`|`[n0 v1 (L VM R) v3 n4]`|`[[n0 v1 L ] VM [ R v3 n4]]`|
78
78
  |right | 4|`[n0 v1 n2 v3 ...o]`|`[n0 v1 n2 v3 (L VM R)]`|`[[n0 v1 n2] v3 [ L VM R ]]`|
79
+
80
+ ## Concat
81
+
82
+ `concat` returns either `Branch1` or `Branch3`
83
+
84
+ |`a` |`b` | |size |
85
+ |------------------|-------------------|-------------------------------------------------|-----|
86
+ |`[av]` |`[bv]` |`[[av,bv]]` | |
87
+ | |`[bv0,bv1]` |`[a,bv0,[bv1]]` | |
88
+ |`[av0,av1]` | |`[[av0],av1,b]` | |
89
+ |`[...aHead,aLast]`|`[bFirst,...bLast]`|`up([...aHead,...concat(aLast,bFirst),...bTail])`|5..11|
90
+
91
+ ## Up
92
+
93
+ `up` returns `Branch1` or `Branch3`
94
+
95
+ |`n.lenght`| |
96
+ |----------|--------------------------|
97
+ |5 |`[n]` |
98
+ |7 |`[n[0...2],n[3],n[4...6]]`|
99
+ |9 |`[n[0...2],n[3],n[4...8]]`|
100
+ |11 |`[n[0...4],n[5],n[6...A]]`|
101
+
102
+ ## Delete
103
+
104
+ `delete` returns `['leaf', [] | Leaf1]` | `['branch', Branch1 | Branch3 | Branch5]`
105
+
106
+ |type |index|r |
107
+ |------------------|-----|---------------------------------|
108
+ |`[v]` | 0|leaf `[]` |
109
+ |`[v0,v1]` | 0|leaf `[v1]` |
110
+ | | 1|leaf `[v2]` |
111
+ |`[n0,v1,n2]` | 1|branch `concat(n0,n2)` |
112
+ |`[n0,v1,n2,v3,n4]`| 1|branch `[...concat(n0,n2),v3,n4]`|
113
+ | | 3|branch `[n0,v1,...concat(n2,n4)]`|
114
+
115
+ |type |index|nR | |
116
+ |------------------|-----|-------|----------------------------------------|
117
+ |`[n0,v1,n2]` | 0|`[]` |`[[v1, v20]]` |
118
+ | | | |`[[v1],v20,[v21]]` |
119
+ | | |`[nR0]`|`[[nR0, v1, n20, v21, n22]]` |
120
+ | | | |`[[nR0, v1, n20], v21, [n22, v23, n23]]`|
121
+ | | |`nR` |`[r,v1,n2]` |
122
+ | | 2|`[]` |`[[v00, v1]]` |
123
+ | | | |`[[v00],v01,[v1]]` |
124
+ | | |`[nR0]`|`[[n00, v01, n02, v1, nR0]]` |
125
+ | | | |`[[n00, v01, n02], v02, [n03, v1, nR0]]`|
126
+ | | |`nR` |`[n0,v1,r]` |
127
+ |`[n0,v1,n2,v3,n4]`| 0|`[]` |`[[v1,v20],v3,n4]` |
128
+ | | | |`[[v1],v20,[v21],v3,n4]` |
129
+ | | |`[nR0]`|`[[nR0,v1,n20,v21,n22],v3,n4]` |
130
+ | | | |`[[nR0,v1,n20],v21,[n22,v23,n24],v3,n4]`|
131
+ | | |`nR` |`[nR,v1,n2,v3,n4]` |
132
+ | | 2|`[]` |`[[v00,v1],v3,n4]` |
133
+ | | | |`[[v00],v01,[v1],v3,n4]` |
134
+ | | |`[nR0]`|`[[n00,v01,n02,v1,nR0],v3,n4]` |
135
+ | | | |`[[n00,v01,n02],v03,[n04,v1,nR0],v3,n4]`|
136
+ | | |`nR` |`[n0,v1,nR,v2,n4]` |
137
+ | | 4|`[]` |`[n0,v1,[v20,v3]]` |
138
+ | | | |`[n0,v1,[v20],v21,[v3]]` |
139
+ | | |`[nR0]`|`[n0,v1,[n20,v21,n22,v3,nR0]]` |
140
+ | | | |`[n0,v1,[n20,v21,n22],v23,[n24,v3,nR0]]`|
141
+ | | |`nR` |`[n0,v1,n2,v3,nR]` |
142
+
143
+ ## Insert
144
+
145
+ `insert` returns `Branch1` or `Branch3`
146
+
147
+ |type | |size|
148
+ |------------------|---------------------------------|----|
149
+ |`[v]` |`[[vI,v]]` | |
150
+ | |`[[v,vI]]` | |
151
+ |`[v0,v1]` |`[[vI],v0,[v1]]` | |
152
+ | |`[[v0],vI,[v1]]` | |
153
+ | |`[[v0],v1,[vI]]` | |
154
+ |`[n0,v1,n2]` |`up([...insert(n0),v1,n2])` |3..5|
155
+ | |`up([n0,v1,...insert(n2)])` |3..5|
156
+ |`[n0,v1,n2,v3,n4]`|`up([...insert(n0),v1,n2,v3,n4])`|5..7|
157
+ | |`up([n0,v1,...insert(n2),v3,n4])`|5..7|
158
+ | |`up([n0,v1,n2,v3,...insert(n4)])`|5..7|
@@ -0,0 +1,96 @@
1
+ const _ = require('..')
2
+ const { todo } = require('../../../dev')
3
+ const list = require('../../list')
4
+ const cmp = require('../../function/compare')
5
+
6
+ /**
7
+ * @template T
8
+ * @typedef {readonly[cmp.Index3, _.Leaf1<T>|_.Branch3<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 {readonly[First<T>, Path<T>]} Result<T>
60
+ */
61
+
62
+ /** @type {<T>(c: cmp.Compare<T>) => (node: _.Node<T>) => Result<T>} */
63
+ const find = c => {
64
+ const i3 = cmp.index3(c)
65
+ const i5 = cmp.index5(c)
66
+ /** @typedef {typeof c extends cmp.Compare<infer T> ? T : never} T */
67
+ /** @type {(prior: Path<T>) => (node: _.Node<T>) => Result<T>} */
68
+ const f = tail => node => {
69
+ /** @type {(first: PathItem<T>) => Result<T>} */
70
+ const append = first => f({ first, tail })(child(first))
71
+ switch (node.length) {
72
+ case 1: { return [[i3(node[0]), node], tail] }
73
+ case 2: { return [[i5(node), node], tail] }
74
+ case 3: {
75
+ const i = i3(node[1])
76
+ switch (i) {
77
+ case 0: case 2: { return append([i, node]) }
78
+ case 1: { return [[i, node], tail] }
79
+ }
80
+ }
81
+ case 5: {
82
+ const i = i5([node[1], node[3]])
83
+ switch (i) {
84
+ case 0: case 2: case 4: { return append([i, node]) }
85
+ case 1: case 3: { return [[i, node], tail]}
86
+ }
87
+ }
88
+ }
89
+ }
90
+ return f(undefined)
91
+ }
92
+
93
+ module.exports = {
94
+ /** @readonly */
95
+ find,
96
+ }
@@ -0,0 +1,122 @@
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 {(sequence: list.List<json.Unknown>) => string} */
11
+ // const arrayStr = sequence => jsonStr(list.toArray(sequence))
12
+
13
+ /** @type {(node: btree.Node<string>) => (value: string) => btree.Node<string>} */
14
+ const set = node => value => {
15
+ const result = btree.setVisitor(stringCmp(value))(node)(() => value)
16
+ switch (result[0]) {
17
+ case 'replace': case 'overflow': { return result[1] }
18
+ default: { return node }
19
+ }
20
+ }
21
+
22
+ /** @type {(r: _.Result<json.Unknown>) => string} */
23
+ const str = ([r, path]) => jsonStr([r[0], list.toArray(list.map(x => x[0])(path))])
24
+
25
+ /** @type {(i: string) => (m: btree.Node<string>) => string} */
26
+ const find = i => m => str(_.find(stringCmp(i))(m))
27
+
28
+ {
29
+ /** @type {btree.Node<string>} */
30
+ let _map = ['1']
31
+ for (let i = 2; i <= 10; i++)
32
+ _map = set(_map)((i * i).toString())
33
+ {
34
+ const s = jsonStr(_map)
35
+ if (s !== '[[["1","100"],"16",["25","36"]],"4",[["49"],"64",["81","9"]]]') { throw s }
36
+ }
37
+ //
38
+ {
39
+ const r = find("0")(_map)
40
+ if (r !== '[0,[0,0]]') { throw r }
41
+ }
42
+ {
43
+ const r = find("1")(_map)
44
+ if (r !== '[1,[0,0]]') { throw r }
45
+ }
46
+ {
47
+ const r = find("10")(_map)
48
+ if (r !== '[2,[0,0]]') { throw r }
49
+ }
50
+ {
51
+ const r = find("100")(_map)
52
+ if (r !== '[3,[0,0]]') { throw r }
53
+ }
54
+ {
55
+ const r = find("12")(_map)
56
+ if (r !== '[4,[0,0]]') { throw r }
57
+ }
58
+ {
59
+ const r = find("16")(_map)
60
+ if (r !== '[1,[0]]') { throw r }
61
+ }
62
+ {
63
+ const r = find("17")(_map)
64
+ if (r !== '[0,[2,0]]') { throw r }
65
+ }
66
+ {
67
+ const r = find("25")(_map)
68
+ if (r !== '[1,[2,0]]') { throw r }
69
+ }
70
+ {
71
+ const r = find("26")(_map)
72
+ if (r !== '[2,[2,0]]') { throw r }
73
+ }
74
+ {
75
+ const r = find("36")(_map)
76
+ if (r !== '[3,[2,0]]') { throw r }
77
+ }
78
+ {
79
+ const r = find("37")(_map)
80
+ if (r !== '[4,[2,0]]') { throw r }
81
+ }
82
+ {
83
+ const r = find("4")(_map)
84
+ if (r !== '[1,[]]') { throw r }
85
+ }
86
+ {
87
+ const r = find("41")(_map)
88
+ if (r !== '[0,[0,2]]') { throw r }
89
+ }
90
+ {
91
+ const r = find("49")(_map)
92
+ if (r !== '[1,[0,2]]') { throw r }
93
+ }
94
+ {
95
+ const r = find("5")(_map)
96
+ if (r !== '[2,[0,2]]') { throw r }
97
+ }
98
+ {
99
+ const r = find("64")(_map)
100
+ if (r !== '[1,[2]]') { throw r }
101
+ }
102
+ {
103
+ const r = find("65")(_map)
104
+ if (r !== '[0,[2,2]]') { throw r }
105
+ }
106
+ {
107
+ const r = find("81")(_map)
108
+ if (r !== '[1,[2,2]]') { throw r }
109
+ }
110
+ {
111
+ const r = find("85")(_map)
112
+ if (r !== '[2,[2,2]]') { throw r }
113
+ }
114
+ {
115
+ const r = find("9")(_map)
116
+ if (r !== '[3,[2,2]]') { throw r }
117
+ }
118
+ {
119
+ const r = find("91")(_map)
120
+ if (r !== '[4,[2,2]]') { throw r }
121
+ }
122
+ }
@@ -138,7 +138,7 @@ const seq = require('../list')
138
138
 
139
139
  /**
140
140
  * @template T
141
- * @typedef { readonly [Node<T>, T, Node<T>, T, Node<T>, T, Node<T>] } Branch7
141
+ * @typedef { readonly[...Branch5<T>, T, Node<T>] } Branch7
142
142
  */
143
143
 
144
144
  /** @type {<T>(n: Branch7<T>) => Branch3<T>} */
@@ -346,6 +346,96 @@ const values = node => () => {
346
346
  }
347
347
  }
348
348
 
349
+ /**
350
+ * @template T
351
+ * @typedef {readonly[Node<T>]} Branch1
352
+ */
353
+
354
+ /**
355
+ * @template T
356
+ * @typedef { Branch1<T> | Branch3<T> } ConcatResult
357
+ */
358
+
359
+ /**
360
+ * @template T
361
+ * @typedef {readonly[...Branch7<T>,T,Node<T>]} Branch9
362
+ */
363
+
364
+ /**
365
+ * @template T
366
+ * @typedef {readonly[...Branch9<T>,T,Node<T>]} Branch11
367
+ */
368
+
369
+ /** @type {<T>(n: Branch5<T> | Branch7<T> | Branch9<T> | Branch11<T>) => Branch1<T> | Branch3<T>} */
370
+ const up = n => {
371
+ switch (n.length) {
372
+ case 5: { return [n] }
373
+ case 7: {
374
+ const [n0, v1, n2, v3, n4, v5, n6] = n
375
+ return [[n0, v1, n2], v3, [n4, v5, n6]]
376
+ }
377
+ case 9: {
378
+ const [n0, v1, n2, v3, n4, v5, n6, v7, n8] = n
379
+ return [[n0, v1, n2], v3, [n4, v5, n6, v7, n8]]
380
+ }
381
+ case 11: {
382
+ const [n0, v1, n2, v3, n4, v5, n6, v7, n8, v9, n10] = n
383
+ return [[n0, v1, n2, v3, n4], v5, [n6, v7, n8, v9, n10]]
384
+ }
385
+ }
386
+ }
387
+
388
+ /**
389
+ * @template T
390
+ * @typedef {readonly[Node<T>,T]} Head2
391
+ */
392
+
393
+ /**
394
+ * @template T
395
+ * @typedef {readonly[...Head2<T>, ...Head2<T>]} Head4
396
+ */
397
+
398
+ /**
399
+ * @template T
400
+ * @typedef {Head2<T>|Head4<T>} Head
401
+ */
402
+
403
+ /** @type {<T>(n: Branch3<T> | Branch5<T>) => readonly[Head<T>, Node<T>]} */
404
+ const headLast = n => {
405
+ if (n.length === 3) {
406
+ const [n0, v1, n2] = n
407
+ return [[n0, v1], n2]
408
+ } else {
409
+ const [n0, v1, n2, v3, n4] = n
410
+ return [[n0, v1, n2, v3], n4]
411
+ }
412
+ }
413
+
414
+ /** @type {<T>(a: Node<T>) => (b: Node<T>) => ConcatResult<T>} */
415
+ const concat = a => b => {
416
+ /** @typedef {typeof a extends Node<infer T> ? T : never} T */
417
+ switch (a.length) {
418
+ case 1: {
419
+ switch (b.length) {
420
+ case 1: { return [[a[0], b[0]]] }
421
+ case 2: { return [a, b[0], [b[1]]] }
422
+ default: { throw 'invalid b node' }
423
+ }
424
+ }
425
+ case 2: { return [[a[0]], a[1], b] }
426
+ default: {
427
+ switch (b.length) {
428
+ case 3: case 5: {
429
+ const [aHead, aLast] = headLast(a)
430
+ const [bFirst, ...bTail] = b
431
+ return up([...aHead, ...concat(aLast)(bFirst), ...bTail])
432
+ }
433
+ default: { throw 'invalid b node' }
434
+ }
435
+ }
436
+ }
437
+ }
438
+
349
439
  module.exports = {
350
440
  /** @readonly */
351
441
  values,
@@ -363,5 +453,7 @@ module.exports = {
363
453
  /** @readonly */
364
454
  getOrInsertVisitor: visit(getOrInsertVisitor),
365
455
  /** @readonly */
366
- replaceVisitor: visit(replaceVisitor)
456
+ replaceVisitor: visit(replaceVisitor),
457
+ /** @readonly */
458
+ concat,
367
459
  }
@@ -1,12 +1,16 @@
1
1
  const btree = require('.')
2
- const { getVisitor, setVisitor, values } = btree
2
+ const { getVisitor, setVisitor, values, concat } = btree
3
3
  const json = require('../../json')
4
4
  const { sort } = require('../object')
5
5
  const { stringCmp } = require('../function/compare')
6
6
  const list = require('../list')
7
7
 
8
+ require('./find/test')
9
+
10
+ const jsonStr = json.stringify(sort)
11
+
8
12
  /** @type {(sequence: list.List<json.Unknown>) => string} */
9
- const stringify = sequence => json.stringify(sort)(list.toArray(sequence))
13
+ const stringify = sequence => jsonStr(list.toArray(sequence))
10
14
 
11
15
  /** @type {(node: btree.Node<string>) => (value: string) => btree.Node<string>} */
12
16
  const set = node => value => {
@@ -56,6 +60,48 @@ const set = node => value => {
56
60
  if (result !== undefined) { throw result }
57
61
  }
58
62
 
63
+ {
64
+ /** @type {btree.Node<string>} */
65
+ let _map = ['1']
66
+ for (let i = 2; i <= 10; i++)
67
+ _map = set(_map)((i * i).toString())
68
+ if (_map.length !== 3) { throw _map }
69
+ let _s = jsonStr(_map)
70
+ if (_s !== '[[["1","100"],"16",["25","36"]],"4",[["49"],"64",["81","9"]]]') { throw _s }
71
+
72
+ let [a,,b] = _map
73
+ let _c = concat(a)(b)
74
+ if (_c.length !== 3) { throw _c }
75
+ _s =jsonStr(_c);
76
+ if (_s !== '[[["1","100"],"16",["25"]],"36",[["49"],"64",["81","9"]]]') { throw _s }
77
+
78
+ [a,,b] = _c
79
+ _c = concat(a)(b)
80
+ if (_c.length !== 1) { throw _c }
81
+ _s = jsonStr(_c);
82
+ if (_s !== '[[["1","100"],"16",["25","49"],"64",["81","9"]]]') { throw _s }
83
+
84
+ let [_r] = _c
85
+ if (_r.length !== 5) { throw _r }
86
+ [a,,b] = _r
87
+ _c = concat(a)(b)
88
+ if (_c.length !== 3) { throw _c }
89
+ _s = jsonStr(_c);
90
+ if (_s !== '[["1"],"100",["25","49"]]') { throw _s }
91
+
92
+ [a,,b] = _c
93
+ _c = concat(a)(b)
94
+ if (_c.length !== 3) { throw _c }
95
+ _s = jsonStr(_c);
96
+ if (_s !== '[["1"],"25",["49"]]') { throw _s }
97
+
98
+ [a,,b] = _c
99
+ _c = concat(a)(b)
100
+ if (_c.length !== 1) { throw _c }
101
+ _s = jsonStr(_c);
102
+ if (_s !== '[["1","49"]]') { throw _s }
103
+ }
104
+
59
105
  const test = () => {
60
106
  /** @type {btree.Node<string>} */
61
107
  let _map = ['a']
@@ -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()