functionalscript 0.0.282 → 0.0.286

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.282",
3
+ "version": "0.0.286",
4
4
  "description": "FunctionalScript is a functional subset of JavaScript",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -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
 
@@ -77,55 +77,82 @@ Posible actions:
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
79
 
80
- ## Deleting a Node
81
-
82
- |type |index| | | |
83
- |------------------|-----|---------------------|--------|-----------------------------|
84
- |`[v]` | 0| | |underflow `undefined` |
85
- |`[v0,v1]` | 0| | |replace `[v1]` |
86
- | | 1| | |replace `[v0]` |
87
- |`[n0,v1,n2]` | 1|`concat(n0,n2)` |overflow|replace `[n0_,v1_,n1_]` |
88
- | | | |replace |underflow `n_` |
89
- |`[n0,v1,n2,v3,n4]`| 1|`concat(n0,n2),v3,n4`|overflow|replace `[n0_,v1_,n1_,v3,n4]`|
90
- | | | |replace |replace `[n_,v3,n4]` |
91
- | | 3|`n0,v1,concat(n2,n4)`|overflow|replace `[n0,v1,n0_,v1_,n1_]`|
92
- | | | |replace |replace `[n0,v1,n_]` |
93
-
94
- ### Underflow
95
-
96
- |type |index| | |
97
- |------------------|-----|---------------------------------------|-----------------------------------------------|
98
- |`[n0,v1,n2]` | 0|`[[],v1,[v20]]` |underflow `[v1,v20]` |
99
- | | |`[[],v1,[v20,v21]]` |replace `[[v1],v20,[v21]]` |
100
- | | |`[[n_],v1,[n20,v21,n22]]` |underflow `[n_,v1,n20,v21,n22]` |
101
- | | |`[[n_],v1,[n20,v21,n22,v23,n24]]` |replace `[[n_,v1,n20],v21,[n22,v23,n24]]` |
102
- | | 2| | |
103
- |`[n0,v1,n2,v3,n4]`| 0|`[[],v1,[v20],v3,n4]` |replace `[[v1,v20],v3,n4]` |
104
- | | |`[[],v1,[v20,v21],v3,n4]` |replace `[[v1],v20,[v21],v3,n4]` |
105
- | | |`[[n_],v1,[n20,v21,n22],v3,n4]` |replace `[[n_,v1,n20,v21,n22],v3,n4]` |
106
- | | |`[[n_],v1,[n20,v21,n22,v23,n24],v3,n4]`|replace `[[n_,v1,n20],v21,[n22,v23,n24],v3,n4]`|
107
- | | 2| | |
108
- | | 4| | |
109
-
110
- ## Concat (n0,n1)
111
-
112
- `concat` returns either `overflow 3` or `replace`:
113
- - `overflow 3`: `[n0,v1,n2]`
114
- - `replace`: `n`
115
-
116
- |`n0` |`n1` | |
117
- |-----------------------|-----------------------|-------------------------------------------------|
118
- |`[v00]` |`[v10]` |R `[v00,v10]` |
119
- | |`[v10,v11]` |O `[[v00],v10,[v11]]` |
120
- |`[v00,v01]` |`n1` |O `[[v00],v01,n1]` |
121
- |`[n00,v01,n02]` |`[n10,v11,n12]` |`n00,v01,concat(n02,n10),v11,n12` |
122
- | |`[n10,v11,n12,v13,n14]`|`n00,v01,concat(n02,n10),v11,n12,v13,n14` |
123
- |`[n00,v01,n02,v03,n04]`|`[n10,v11,n12]` |`n00,v01,n02,v03,concat(n04,n10),v11,n12` |
124
- | |`[n10,v11,n12,v13,n14]`|`n00,v01,n02,v03,concat(n04,n10),v11,n12,v13,n14`|
125
-
126
- |source |replace `cn` |overflow `[cn0,cv1,cn2]` |
127
- |---------------------------------------|------------------------------------|---------------------------------------------|
128
- |`n0,v1,concat(n2,n3),v4,n5` |R `[n0,v1,cn,v2,n3]` |O `[[n0,v1,cn0],cv1,[cn2,v4,n5]]` |
129
- |`n0,v1,concat(n2,n3),v4,n5,v6,n7` |O `[[n0,v1,cn],v4,[n5,v6,n7]]` |O `[[n0,v1,cn0],cv1,[cn2,v4,n5,v6,n7]]` |
130
- |`n0,v1,n2,v3,concat(n4,n5),v6,n7` |O `[[n0,v1,n2],v3,[cn,v6,n7]]` |O `[[n0,v1,n2,v3,cn0],cv1,[cn2,v6,n7]]` |
131
- |`n0,v1,n2,v3,concat(n4,n5),v6,n7,v8,n9`|O `[[n0,v1,n2],v3,[cn,v6,n7,v8,n9]]`|O `[[n0,v1,n2,v3,cn0],cv1,[cn2,v6,n7,v8,n9]]`|
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,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>|_.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 {{
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
+ }
@@ -395,8 +395,13 @@ const up = n => {
395
395
  * @typedef {readonly[...Head2<T>, ...Head2<T>]} Head4
396
396
  */
397
397
 
398
- /** @type {<T>(n: Branch3<T> | Branch5<T>) => readonly[Head2<T>|Head4<T>, Node<T>]} */
399
- const bracnhSplit = n => {
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 => {
400
405
  if (n.length === 3) {
401
406
  const [n0, v1, n2] = n
402
407
  return [[n0, v1], n2]
@@ -421,9 +426,9 @@ const concat = a => b => {
421
426
  default: {
422
427
  switch (b.length) {
423
428
  case 3: case 5: {
424
- const [aHead, aLast] = bracnhSplit(a)
425
- const [bn0, ...b1] = b
426
- return up([...aHead, ...concat(aLast)(bn0), ...b1])
429
+ const [aHead, aLast] = headLast(a)
430
+ const [bFirst, ...bTail] = b
431
+ return up([...aHead, ...concat(aLast)(bFirst), ...bTail])
427
432
  }
428
433
  default: { throw 'invalid b node' }
429
434
  }
@@ -5,8 +5,12 @@ 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 => {
@@ -62,29 +66,40 @@ const set = node => value => {
62
66
  for (let i = 2; i <= 10; i++)
63
67
  _map = set(_map)((i * i).toString())
64
68
  if (_map.length !== 3) { throw _map }
65
- // console.log(_map)
69
+ let _s = jsonStr(_map)
70
+ if (_s !== '[[["1","100"],"16",["25","36"]],"4",[["49"],"64",["81","9"]]]') { throw _s }
71
+
66
72
  let [a,,b] = _map
67
73
  let _c = concat(a)(b)
68
- // console.log(_c)
69
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
+
70
78
  [a,,b] = _c
71
79
  _c = concat(a)(b)
72
- // console.log(_c)
73
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
+
74
84
  let [_r] = _c
75
85
  if (_r.length !== 5) { throw _r }
76
86
  [a,,b] = _r
77
87
  _c = concat(a)(b)
78
- // console.log(_c)
79
88
  if (_c.length !== 3) { throw _c }
89
+ _s = jsonStr(_c);
90
+ if (_s !== '[["1"],"100",["25","49"]]') { throw _s }
91
+
80
92
  [a,,b] = _c
81
93
  _c = concat(a)(b)
82
- // console.log(_c)
83
94
  if (_c.length !== 3) { throw _c }
95
+ _s = jsonStr(_c);
96
+ if (_s !== '[["1"],"25",["49"]]') { throw _s }
97
+
84
98
  [a,,b] = _c
85
99
  _c = concat(a)(b)
86
- // console.log(_c)
87
100
  if (_c.length !== 1) { throw _c }
101
+ _s = jsonStr(_c);
102
+ if (_s !== '[["1","49"]]') { throw _s }
88
103
  }
89
104
 
90
105
  const test = () => {
@@ -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()