@panyam/tsutils 0.0.58 → 0.0.63
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/cjs/list.d.ts +5 -3
- package/lib/cjs/list.js +55 -39
- package/lib/cjs/list.js.map +1 -1
- package/lib/cjs/numberutils.d.ts +12 -12
- package/lib/cjs/numberutils.js +27 -22
- package/lib/cjs/numberutils.js.map +1 -1
- package/lib/esm/list.d.ts +5 -3
- package/lib/esm/list.js +55 -39
- package/lib/esm/list.js.map +1 -1
- package/lib/esm/numberutils.d.ts +12 -12
- package/lib/esm/numberutils.js +27 -22
- package/lib/esm/numberutils.js.map +1 -1
- package/package.json +1 -1
package/lib/cjs/list.d.ts
CHANGED
|
@@ -23,11 +23,12 @@ export declare class ValueList<V extends ListNode<V>> {
|
|
|
23
23
|
get last(): Nullable<V>;
|
|
24
24
|
reversedValues(): Generator<V>;
|
|
25
25
|
values(): Generator<V>;
|
|
26
|
-
popBack(): V;
|
|
27
|
-
popFront(): V;
|
|
28
26
|
add(child: V, before?: Nullable<V>): this;
|
|
29
27
|
pushFront(value: V): this;
|
|
30
|
-
|
|
28
|
+
pushBack(value: V): this;
|
|
29
|
+
remove(child: V): this;
|
|
30
|
+
popBack(): V;
|
|
31
|
+
popFront(): V;
|
|
31
32
|
}
|
|
32
33
|
export declare class List<V> {
|
|
33
34
|
private container;
|
|
@@ -35,6 +36,7 @@ export declare class List<V> {
|
|
|
35
36
|
toJSON(): V[];
|
|
36
37
|
forEach(method: (val: V) => boolean | any): number;
|
|
37
38
|
equals(another: List<V>, eqlFunc: (val1: V, val2: V) => boolean): boolean;
|
|
39
|
+
find(target: V): Nullable<MutableListNode<V>>;
|
|
38
40
|
get isEmpty(): boolean;
|
|
39
41
|
get size(): number;
|
|
40
42
|
get first(): Nullable<MutableListNode<V>>;
|
package/lib/cjs/list.js
CHANGED
|
@@ -14,7 +14,7 @@ class ValueList {
|
|
|
14
14
|
this._lastChild = null;
|
|
15
15
|
this._size = 0;
|
|
16
16
|
for (const v of values)
|
|
17
|
-
this.
|
|
17
|
+
this.pushBack(v);
|
|
18
18
|
}
|
|
19
19
|
toJSON() {
|
|
20
20
|
return Array.from(this.values());
|
|
@@ -69,39 +69,11 @@ class ValueList {
|
|
|
69
69
|
tmp = tmp.nextSibling;
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
|
-
popBack() {
|
|
73
|
-
if (this._lastChild == null) {
|
|
74
|
-
throw new Error("No children");
|
|
75
|
-
}
|
|
76
|
-
const out = this._lastChild;
|
|
77
|
-
const prev = this._lastChild.prevSibling;
|
|
78
|
-
this._size--;
|
|
79
|
-
if (prev == null) {
|
|
80
|
-
this._firstChild = this._lastChild = null;
|
|
81
|
-
}
|
|
82
|
-
else {
|
|
83
|
-
prev.nextSibling = null;
|
|
84
|
-
this._lastChild = prev;
|
|
85
|
-
}
|
|
86
|
-
return out;
|
|
87
|
-
}
|
|
88
|
-
popFront() {
|
|
89
|
-
if (this._firstChild == null) {
|
|
90
|
-
throw new Error("No children");
|
|
91
|
-
}
|
|
92
|
-
const out = this._firstChild;
|
|
93
|
-
const next = this._firstChild.nextSibling;
|
|
94
|
-
this._size--;
|
|
95
|
-
if (next == null) {
|
|
96
|
-
this._firstChild = this._lastChild = null;
|
|
97
|
-
}
|
|
98
|
-
else {
|
|
99
|
-
next.prevSibling = null;
|
|
100
|
-
this._firstChild = next;
|
|
101
|
-
}
|
|
102
|
-
return out;
|
|
103
|
-
}
|
|
104
72
|
add(child, before = null) {
|
|
73
|
+
if (child.nextSibling != null || child.prevSibling != null) {
|
|
74
|
+
throw new Error("New node already added to a list. Remove it first");
|
|
75
|
+
}
|
|
76
|
+
child.nextSibling = child.prevSibling = null;
|
|
105
77
|
this._size++;
|
|
106
78
|
if (this._firstChild == null || this._lastChild == null) {
|
|
107
79
|
this._firstChild = this._lastChild = child;
|
|
@@ -119,13 +91,10 @@ class ValueList {
|
|
|
119
91
|
this._firstChild = child;
|
|
120
92
|
}
|
|
121
93
|
else {
|
|
122
|
-
const next = before.nextSibling;
|
|
123
94
|
const prev = before.prevSibling;
|
|
124
|
-
child.nextSibling =
|
|
95
|
+
child.nextSibling = before;
|
|
96
|
+
before.prevSibling = child;
|
|
125
97
|
child.prevSibling = prev;
|
|
126
|
-
if (next != null) {
|
|
127
|
-
next.prevSibling = child;
|
|
128
|
-
}
|
|
129
98
|
if (prev != null) {
|
|
130
99
|
prev.nextSibling = child;
|
|
131
100
|
}
|
|
@@ -135,9 +104,48 @@ class ValueList {
|
|
|
135
104
|
pushFront(value) {
|
|
136
105
|
return this.add(value, this._firstChild);
|
|
137
106
|
}
|
|
138
|
-
|
|
107
|
+
pushBack(value) {
|
|
139
108
|
return this.add(value);
|
|
140
109
|
}
|
|
110
|
+
remove(child) {
|
|
111
|
+
const next = child.nextSibling;
|
|
112
|
+
const prev = child.prevSibling;
|
|
113
|
+
if (next == null) {
|
|
114
|
+
this._lastChild = prev;
|
|
115
|
+
if (prev == null)
|
|
116
|
+
this._firstChild = null;
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
next.prevSibling = prev;
|
|
120
|
+
}
|
|
121
|
+
if (prev == null) {
|
|
122
|
+
this._firstChild = next;
|
|
123
|
+
if (next == null)
|
|
124
|
+
this._lastChild = null;
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
prev.nextSibling = next;
|
|
128
|
+
}
|
|
129
|
+
this._size--;
|
|
130
|
+
child.prevSibling = child.nextSibling = null;
|
|
131
|
+
return this;
|
|
132
|
+
}
|
|
133
|
+
popBack() {
|
|
134
|
+
if (this._lastChild == null) {
|
|
135
|
+
throw new Error("No children");
|
|
136
|
+
}
|
|
137
|
+
const out = this._lastChild;
|
|
138
|
+
this.remove(out);
|
|
139
|
+
return out;
|
|
140
|
+
}
|
|
141
|
+
popFront() {
|
|
142
|
+
if (this._firstChild == null) {
|
|
143
|
+
throw new Error("No children");
|
|
144
|
+
}
|
|
145
|
+
const out = this._firstChild;
|
|
146
|
+
this.remove(out);
|
|
147
|
+
return out;
|
|
148
|
+
}
|
|
141
149
|
}
|
|
142
150
|
exports.ValueList = ValueList;
|
|
143
151
|
class List {
|
|
@@ -155,6 +163,14 @@ class List {
|
|
|
155
163
|
equals(another, eqlFunc) {
|
|
156
164
|
return this.container.equals(another.container, (a, b) => eqlFunc(a.value, b.value));
|
|
157
165
|
}
|
|
166
|
+
find(target) {
|
|
167
|
+
for (const v of this.container.values()) {
|
|
168
|
+
if (target == v.value) {
|
|
169
|
+
return v;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
158
174
|
get isEmpty() {
|
|
159
175
|
return this.container.isEmpty;
|
|
160
176
|
}
|
package/lib/cjs/list.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/list.ts"],"names":[],"mappings":";;;AAOA,MAAM,eAAe;IAGnB,YAAmB,KAAQ;QAAR,UAAK,GAAL,KAAK,CAAG;QAF3B,gBAAW,GAAiC,IAAI,CAAC;QACjD,gBAAW,GAAiC,IAAI,CAAC;IACnB,CAAC;CAChC;AAMD,MAAa,SAAS;IAKpB,YAAY,GAAG,MAAW;QAJhB,gBAAW,GAAgB,IAAI,CAAC;QAChC,eAAU,GAAgB,IAAI,CAAC;QAC/B,UAAK,GAAG,CAAC,CAAC;QAGlB,KAAK,MAAM,CAAC,IAAI,MAAM;YAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACvC,CAAC;IAED,MAAM;QACJ,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IACnC,CAAC;IAED,OAAO,CAAC,MAAiC;QACvC,IAAI,GAAG,GAAa,IAAI,CAAC,WAAW,CAAC;QACrC,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,OAAO,GAAG,IAAI,IAAI,EAAE;YAClB,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,KAAK,EAAE;gBACxB,MAAM;aACP;YACD,KAAK,EAAE,CAAC;YACR,GAAG,GAAG,GAAG,CAAC,WAAW,CAAC;SACvB;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,CAAC,OAAqB,EAAE,OAAsC;QAClE,IAAI,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI;YAAE,OAAO,KAAK,CAAC;QAC5C,IAAI,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC;QACrB,IAAI,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC;QACzB,OAAO,GAAG,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,EAAE,GAAG,GAAG,GAAG,CAAC,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE;YAClF,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE;gBACvB,OAAO,KAAK,CAAC;aACd;SACF;QACD,OAAO,GAAG,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,CAAC;IACrC,CAAC;IAED,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;IACzB,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAKD,CAAC,cAAc;QACb,IAAI,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC;QAC1B,OAAO,GAAG,IAAI,IAAI,EAAE;YAClB,MAAM,GAAG,CAAC;YACV,GAAG,GAAG,GAAG,CAAC,WAAW,CAAC;SACvB;IACH,CAAC;IAKD,CAAC,MAAM;QACL,IAAI,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC;QAC3B,OAAO,GAAG,IAAI,IAAI,EAAE;YAClB,MAAM,GAAG,CAAC;YACV,GAAG,GAAG,GAAG,CAAC,WAAW,CAAC;SACvB;IACH,CAAC;IAED,OAAO;QACL,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,EAAE;YAC3B,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC;SAChC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;QACzC,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,IAAI,IAAI,IAAI,IAAI,EAAE;YAChB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;SAC3C;aAAM;YACL,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;YACxB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;SACxB;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,QAAQ;QACN,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,EAAE;YAC5B,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC;SAChC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC;QAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC;QAC1C,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,IAAI,IAAI,IAAI,IAAI,EAAE;YAChB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;SAC3C;aAAM;YACL,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;YACxB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;SACzB;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,GAAG,CAAC,KAAQ,EAAE,SAAsB,IAAI;QACtC,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,EAAE;YACvD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;SAC5C;aAAM,IAAI,MAAM,IAAI,IAAI,EAAE;YACzB,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC;YACpC,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC;YACzB,IAAI,CAAC,UAAU,CAAC,WAAW,GAAG,KAAK,CAAC;YACpC,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;SACzB;aAAM,IAAI,MAAM,IAAI,IAAI,CAAC,WAAW,EAAE;YACrC,KAAK,CAAC,WAAW,GAAG,MAAM,CAAC;YAC3B,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC;YACzB,IAAI,CAAC,WAAW,CAAC,WAAW,GAAG,KAAK,CAAC;YACrC,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;SAC1B;aAAM;YACL,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC;YAChC,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC;YAChC,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC;YACzB,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC;YACzB,IAAI,IAAI,IAAI,IAAI,EAAE;gBAChB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;aAC1B;YACD,IAAI,IAAI,IAAI,IAAI,EAAE;gBAChB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;aAC1B;SACF;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,SAAS,CAAC,KAAQ;QAChB,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IAC3C,CAAC;IAED,IAAI,CAAC,KAAQ;QACX,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;CACF;AAhJD,8BAgJC;AAMD,MAAa,IAAI;IAGf,YAAY,GAAG,MAAW;QACxB,IAAI,CAAC,SAAS,GAAG,IAAI,SAAS,EAAsB,CAAC;QACrD,KAAK,MAAM,CAAC,IAAI,MAAM;YAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACvC,CAAC;IAED,MAAM;QACJ,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IACnC,CAAC;IAED,OAAO,CAAC,MAAiC;QACvC,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IACxD,CAAC;IAED,MAAM,CAAC,OAAgB,EAAE,OAAsC;QAC7D,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IACvF,CAAC;IAED,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;IAChC,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;IAC7B,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;IAC9B,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;IAC7B,CAAC;IAKD,CAAC,cAAc;QACb,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE;YAAE,MAAM,CAAC,CAAC,KAAK,CAAC;IACjE,CAAC;IAKD,CAAC,MAAM;QACL,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE;YAAE,MAAM,CAAC,CAAC,KAAK,CAAC;IACzD,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC;IACxC,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC;IACzC,CAAC;IAED,SAAS,CAAC,KAAQ;QAChB,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC/C,CAAC;IAED,IAAI,CAAC,KAAQ;QACX,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;IAED,GAAG,CAAC,KAAQ,EAAE,SAAuC,IAAI;QACvD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,CAAC;QACvD,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAtED,oBAsEC","sourcesContent":["import { Nullable } from \"./types\";\n\nexport interface ListNode<V> {\n nextSibling: Nullable<V>;\n prevSibling: Nullable<V>;\n}\n\nclass MutableListNode<V> implements ListNode<MutableListNode<V>> {\n nextSibling: Nullable<MutableListNode<V>> = null;\n prevSibling: Nullable<MutableListNode<V>> = null;\n constructor(public value: V) {}\n}\n\n/**\n * A list implementation where the value itself contains next and prev pointers\n * so we do not need to create wrapper classes.\n */\nexport class ValueList<V extends ListNode<V>> {\n protected _firstChild: Nullable<V> = null;\n protected _lastChild: Nullable<V> = null;\n protected _size = 0;\n\n constructor(...values: V[]) {\n for (const v of values) this.push(v);\n }\n\n toJSON(): V[] {\n return Array.from(this.values());\n }\n\n forEach(method: (val: V) => boolean | any): number {\n let tmp: V | null = this._firstChild;\n let count = 0;\n while (tmp != null) {\n if (method(tmp) == false) {\n break;\n }\n count++;\n tmp = tmp.nextSibling;\n }\n return count;\n }\n\n equals(another: ValueList<V>, eqlFunc: (val1: V, val2: V) => boolean): boolean {\n if (this.size != another.size) return false;\n let tmp = this.first;\n let tmp2 = another.first;\n for (; tmp != null && tmp2 != null; tmp = tmp.nextSibling, tmp2 = tmp2.nextSibling) {\n if (!eqlFunc(tmp, tmp2)) {\n return false;\n }\n }\n return tmp == null && tmp2 == null;\n }\n\n get isEmpty(): boolean {\n return this._size == 0;\n }\n\n get size(): number {\n return this._size;\n }\n\n get first(): Nullable<V> {\n return this._firstChild;\n }\n\n get last(): Nullable<V> {\n return this._lastChild;\n }\n\n /**\n * Generator of values in reverse order.\n */\n *reversedValues(): Generator<V> {\n let tmp = this._lastChild;\n while (tmp != null) {\n yield tmp;\n tmp = tmp.prevSibling;\n }\n }\n\n /**\n * Generator of values in forward order.\n */\n *values(): Generator<V> {\n let tmp = this._firstChild;\n while (tmp != null) {\n yield tmp;\n tmp = tmp.nextSibling;\n }\n }\n\n popBack(): V {\n if (this._lastChild == null) {\n throw new Error(\"No children\");\n }\n const out = this._lastChild;\n const prev = this._lastChild.prevSibling;\n this._size--;\n if (prev == null) {\n this._firstChild = this._lastChild = null;\n } else {\n prev.nextSibling = null;\n this._lastChild = prev;\n }\n return out;\n }\n\n popFront(): V {\n if (this._firstChild == null) {\n throw new Error(\"No children\");\n }\n const out = this._firstChild;\n const next = this._firstChild.nextSibling;\n this._size--;\n if (next == null) {\n this._firstChild = this._lastChild = null;\n } else {\n next.prevSibling = null;\n this._firstChild = next;\n }\n return out;\n }\n\n add(child: V, before: Nullable<V> = null): this {\n this._size++;\n if (this._firstChild == null || this._lastChild == null) {\n this._firstChild = this._lastChild = child;\n } else if (before == null) {\n child.prevSibling = this._lastChild;\n child.nextSibling = null;\n this._lastChild.nextSibling = child;\n this._lastChild = child;\n } else if (before == this._firstChild) {\n child.nextSibling = before;\n child.prevSibling = null;\n this._firstChild.prevSibling = child;\n this._firstChild = child;\n } else {\n const next = before.nextSibling;\n const prev = before.prevSibling;\n child.nextSibling = next;\n child.prevSibling = prev;\n if (next != null) {\n next.prevSibling = child;\n }\n if (prev != null) {\n prev.nextSibling = child;\n }\n }\n return this;\n }\n\n pushFront(value: V): this {\n return this.add(value, this._firstChild);\n }\n\n push(value: V): this {\n return this.add(value);\n }\n}\n\n/**\n * A list implementation where the values themselves need to be wrapper in a list node.\n * If values already have sibling node properties they can be direclty used via ValueLists.\n */\nexport class List<V> {\n private container: ValueList<MutableListNode<V>>;\n\n constructor(...values: V[]) {\n this.container = new ValueList<MutableListNode<V>>();\n for (const v of values) this.push(v);\n }\n\n toJSON(): V[] {\n return Array.from(this.values());\n }\n\n forEach(method: (val: V) => boolean | any): number {\n return this.container.forEach((v) => method(v.value));\n }\n\n equals(another: List<V>, eqlFunc: (val1: V, val2: V) => boolean): boolean {\n return this.container.equals(another.container, (a, b) => eqlFunc(a.value, b.value));\n }\n\n get isEmpty(): boolean {\n return this.container.isEmpty;\n }\n\n get size(): number {\n return this.container.size;\n }\n\n get first(): Nullable<MutableListNode<V>> {\n return this.container.first;\n }\n\n get last(): Nullable<MutableListNode<V>> {\n return this.container.last;\n }\n\n /**\n * Generator of values in reverse order.\n */\n *reversedValues(): Generator<V> {\n for (const v of this.container.reversedValues()) yield v.value;\n }\n\n /**\n * Generator of values in forward order.\n */\n *values(): Generator<V> {\n for (const v of this.container.values()) yield v.value;\n }\n\n popBack(): V {\n return this.container.popBack().value;\n }\n\n popFront(): V {\n return this.container.popFront().value;\n }\n\n pushFront(value: V): this {\n return this.add(value, this.container.first);\n }\n\n push(value: V): this {\n return this.add(value);\n }\n\n add(child: V, before: Nullable<MutableListNode<V>> = null): this {\n this.container.add(new MutableListNode(child), before);\n return this;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/list.ts"],"names":[],"mappings":"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","sourcesContent":["import { Nullable } from \"./types\";\n\nexport interface ListNode<V> {\n nextSibling: Nullable<V>;\n prevSibling: Nullable<V>;\n}\n\nclass MutableListNode<V> implements ListNode<MutableListNode<V>> {\n nextSibling: Nullable<MutableListNode<V>> = null;\n prevSibling: Nullable<MutableListNode<V>> = null;\n constructor(public value: V) {}\n}\n\n/**\n * A list implementation where the value itself contains next and prev pointers\n * so we do not need to create wrapper classes.\n */\nexport class ValueList<V extends ListNode<V>> {\n protected _firstChild: Nullable<V> = null;\n protected _lastChild: Nullable<V> = null;\n protected _size = 0;\n\n constructor(...values: V[]) {\n for (const v of values) this.pushBack(v);\n }\n\n toJSON(): V[] {\n return Array.from(this.values());\n }\n\n forEach(method: (val: V) => boolean | any): number {\n let tmp: V | null = this._firstChild;\n let count = 0;\n while (tmp != null) {\n if (method(tmp) == false) {\n break;\n }\n count++;\n tmp = tmp.nextSibling;\n }\n return count;\n }\n\n equals(another: ValueList<V>, eqlFunc: (val1: V, val2: V) => boolean): boolean {\n if (this.size != another.size) return false;\n let tmp = this.first;\n let tmp2 = another.first;\n for (; tmp != null && tmp2 != null; tmp = tmp.nextSibling, tmp2 = tmp2.nextSibling) {\n if (!eqlFunc(tmp, tmp2)) {\n return false;\n }\n }\n return tmp == null && tmp2 == null;\n }\n\n get isEmpty(): boolean {\n return this._size == 0;\n }\n\n get size(): number {\n return this._size;\n }\n\n get first(): Nullable<V> {\n return this._firstChild;\n }\n\n get last(): Nullable<V> {\n return this._lastChild;\n }\n\n /**\n * Generator of values in reverse order.\n */\n *reversedValues(): Generator<V> {\n let tmp = this._lastChild;\n while (tmp != null) {\n yield tmp;\n tmp = tmp.prevSibling;\n }\n }\n\n /**\n * Generator of values in forward order.\n */\n *values(): Generator<V> {\n let tmp = this._firstChild;\n while (tmp != null) {\n yield tmp;\n tmp = tmp.nextSibling;\n }\n }\n\n add(child: V, before: Nullable<V> = null): this {\n // Ensure that this node is not added anywhere else\n if (child.nextSibling != null || child.prevSibling != null) {\n throw new Error(\"New node already added to a list. Remove it first\");\n }\n child.nextSibling = child.prevSibling = null;\n this._size++;\n if (this._firstChild == null || this._lastChild == null) {\n this._firstChild = this._lastChild = child;\n } else if (before == null) {\n child.prevSibling = this._lastChild;\n child.nextSibling = null;\n this._lastChild.nextSibling = child;\n this._lastChild = child;\n } else if (before == this._firstChild) {\n child.nextSibling = before;\n child.prevSibling = null;\n this._firstChild.prevSibling = child;\n this._firstChild = child;\n } else {\n const prev = before.prevSibling;\n child.nextSibling = before;\n before.prevSibling = child;\n child.prevSibling = prev;\n if (prev != null) {\n prev.nextSibling = child;\n }\n }\n return this;\n }\n\n pushFront(value: V): this {\n return this.add(value, this._firstChild);\n }\n\n pushBack(value: V): this {\n return this.add(value);\n }\n\n /**\n * Removes a child node from this list.\n * It is upto the caller to ensure that this node indeed belongs\n * to this list otherwise deletion of a non belonging node could result\n * in undefined behaviour.\n */\n remove(child: V): this {\n const next = child.nextSibling;\n const prev = child.prevSibling;\n\n if (next == null) {\n this._lastChild = prev;\n if (prev == null) this._firstChild = null;\n } else {\n next.prevSibling = prev;\n }\n\n if (prev == null) {\n this._firstChild = next;\n if (next == null) this._lastChild = null;\n } else {\n prev.nextSibling = next;\n }\n\n this._size--;\n\n child.prevSibling = child.nextSibling = null;\n return this;\n }\n\n popBack(): V {\n if (this._lastChild == null) {\n throw new Error(\"No children\");\n }\n const out = this._lastChild;\n this.remove(out);\n return out;\n }\n\n popFront(): V {\n if (this._firstChild == null) {\n throw new Error(\"No children\");\n }\n const out = this._firstChild;\n this.remove(out);\n return out;\n }\n}\n\n/**\n * A list implementation where the values themselves need to be wrapper in a list node.\n * If values already have sibling node properties they can be direclty used\n * via ValueLists.\n */\nexport class List<V> {\n private container: ValueList<MutableListNode<V>>;\n\n constructor(...values: V[]) {\n this.container = new ValueList<MutableListNode<V>>();\n for (const v of values) this.push(v);\n }\n\n toJSON(): V[] {\n return Array.from(this.values());\n }\n\n forEach(method: (val: V) => boolean | any): number {\n return this.container.forEach((v) => method(v.value));\n }\n\n equals(another: List<V>, eqlFunc: (val1: V, val2: V) => boolean): boolean {\n return this.container.equals(another.container, (a, b) => eqlFunc(a.value, b.value));\n }\n\n find(target: V): Nullable<MutableListNode<V>> {\n for (const v of this.container.values()) {\n if (target == v.value) {\n return v;\n }\n }\n return null;\n }\n\n get isEmpty(): boolean {\n return this.container.isEmpty;\n }\n\n get size(): number {\n return this.container.size;\n }\n\n get first(): Nullable<MutableListNode<V>> {\n return this.container.first;\n }\n\n get last(): Nullable<MutableListNode<V>> {\n return this.container.last;\n }\n\n /**\n * Generator of values in reverse order.\n */\n *reversedValues(): Generator<V> {\n for (const v of this.container.reversedValues()) yield v.value;\n }\n\n /**\n * Generator of values in forward order.\n */\n *values(): Generator<V> {\n for (const v of this.container.values()) yield v.value;\n }\n\n popBack(): V {\n return this.container.popBack().value;\n }\n\n popFront(): V {\n return this.container.popFront().value;\n }\n\n pushFront(value: V): this {\n return this.add(value, this.container.first);\n }\n\n push(value: V): this {\n return this.add(value);\n }\n\n add(child: V, before: Nullable<MutableListNode<V>> = null): this {\n this.container.add(new MutableListNode(child), before);\n return this;\n }\n}\n"]}
|
package/lib/cjs/numberutils.d.ts
CHANGED
|
@@ -7,23 +7,23 @@ export declare class Fraction {
|
|
|
7
7
|
static readonly ZERO: Fraction;
|
|
8
8
|
static readonly ONE: Fraction;
|
|
9
9
|
static readonly INFINITY: Fraction;
|
|
10
|
-
constructor(num?: number, den?: number);
|
|
11
|
-
static parse(val: string): Fraction;
|
|
10
|
+
constructor(num?: number, den?: number, factorized?: boolean);
|
|
11
|
+
static parse(val: string, factorized?: boolean): Fraction;
|
|
12
12
|
get isWhole(): boolean;
|
|
13
13
|
get isZero(): boolean;
|
|
14
14
|
get isInfinity(): boolean;
|
|
15
15
|
get isOne(): boolean;
|
|
16
16
|
get ceil(): number;
|
|
17
17
|
get floor(): number;
|
|
18
|
-
plus(another: Fraction): Fraction;
|
|
19
|
-
plusNum(another: number): Fraction;
|
|
20
|
-
minus(another: Fraction): Fraction;
|
|
21
|
-
minusNum(another: number): Fraction;
|
|
22
|
-
times(another: Fraction): Fraction;
|
|
23
|
-
timesNum(another: number): Fraction;
|
|
24
|
-
divby(another: Fraction): Fraction;
|
|
25
|
-
divbyNum(another: number): Fraction;
|
|
26
|
-
numDivby(another: number): Fraction;
|
|
18
|
+
plus(another: Fraction, factorized?: boolean): Fraction;
|
|
19
|
+
plusNum(another: number, factorized?: boolean): Fraction;
|
|
20
|
+
minus(another: Fraction, factorized?: boolean): Fraction;
|
|
21
|
+
minusNum(another: number, factorized?: boolean): Fraction;
|
|
22
|
+
times(another: Fraction, factorized?: boolean): Fraction;
|
|
23
|
+
timesNum(another: number, factorized?: boolean): Fraction;
|
|
24
|
+
divby(another: Fraction, factorized?: boolean): Fraction;
|
|
25
|
+
divbyNum(another: number, factorized?: boolean): Fraction;
|
|
26
|
+
numDivby(another: number, factorized?: boolean): Fraction;
|
|
27
27
|
mod(another: Fraction): Fraction;
|
|
28
28
|
modNum(another: number): Fraction;
|
|
29
29
|
get inverse(): Fraction;
|
|
@@ -44,4 +44,4 @@ export declare class Fraction {
|
|
|
44
44
|
static max(f1: Fraction, f2: Fraction): Fraction;
|
|
45
45
|
static min(f1: Fraction, f2: Fraction): Fraction;
|
|
46
46
|
}
|
|
47
|
-
export declare const Frac: (a?: number, b?: number) => Fraction;
|
|
47
|
+
export declare const Frac: (a?: number, b?: number, factorized?: boolean) => Fraction;
|
package/lib/cjs/numberutils.js
CHANGED
|
@@ -44,14 +44,19 @@ function gcdof(x, y) {
|
|
|
44
44
|
}
|
|
45
45
|
exports.gcdof = gcdof;
|
|
46
46
|
class Fraction {
|
|
47
|
-
constructor(num = 0, den = 1) {
|
|
47
|
+
constructor(num = 0, den = 1, factorized = false) {
|
|
48
48
|
if (isNaN(num) || isNaN(den)) {
|
|
49
49
|
throw new Error(`Invalid numerator(${num}) or denminator(${den})`);
|
|
50
50
|
}
|
|
51
|
+
if (factorized) {
|
|
52
|
+
const gcd = gcdof(num, den);
|
|
53
|
+
num /= gcd;
|
|
54
|
+
den /= gcd;
|
|
55
|
+
}
|
|
51
56
|
this.num = num;
|
|
52
57
|
this.den = den;
|
|
53
58
|
}
|
|
54
|
-
static parse(val) {
|
|
59
|
+
static parse(val, factorized = false) {
|
|
55
60
|
const parts = val
|
|
56
61
|
.trim()
|
|
57
62
|
.split("/")
|
|
@@ -74,7 +79,7 @@ class Fraction {
|
|
|
74
79
|
if (isNaN(num) || isNaN(den)) {
|
|
75
80
|
throw new Error("Invalid fraction string: " + val);
|
|
76
81
|
}
|
|
77
|
-
return new Fraction(num, den);
|
|
82
|
+
return new Fraction(num, den, factorized);
|
|
78
83
|
}
|
|
79
84
|
get isWhole() {
|
|
80
85
|
return this.num % this.den == 0;
|
|
@@ -104,32 +109,32 @@ class Fraction {
|
|
|
104
109
|
return Math.floor(this.num / this.den);
|
|
105
110
|
}
|
|
106
111
|
}
|
|
107
|
-
plus(another) {
|
|
108
|
-
return new Fraction(this.num * another.den + this.den * another.num, this.den * another.den);
|
|
112
|
+
plus(another, factorized = false) {
|
|
113
|
+
return new Fraction(this.num * another.den + this.den * another.num, this.den * another.den, factorized);
|
|
109
114
|
}
|
|
110
|
-
plusNum(another) {
|
|
111
|
-
return new Fraction(this.num + this.den * another, this.den);
|
|
115
|
+
plusNum(another, factorized = false) {
|
|
116
|
+
return new Fraction(this.num + this.den * another, this.den, factorized);
|
|
112
117
|
}
|
|
113
|
-
minus(another) {
|
|
114
|
-
return new Fraction(this.num * another.den - this.den * another.num, this.den * another.den);
|
|
118
|
+
minus(another, factorized = false) {
|
|
119
|
+
return new Fraction(this.num * another.den - this.den * another.num, this.den * another.den, factorized);
|
|
115
120
|
}
|
|
116
|
-
minusNum(another) {
|
|
117
|
-
return new Fraction(this.num - this.den * another, this.den);
|
|
121
|
+
minusNum(another, factorized = false) {
|
|
122
|
+
return new Fraction(this.num - this.den * another, this.den, factorized);
|
|
118
123
|
}
|
|
119
|
-
times(another) {
|
|
120
|
-
return new Fraction(this.num * another.num, this.den * another.den);
|
|
124
|
+
times(another, factorized = false) {
|
|
125
|
+
return new Fraction(this.num * another.num, this.den * another.den, factorized);
|
|
121
126
|
}
|
|
122
|
-
timesNum(another) {
|
|
123
|
-
return new Fraction(this.num * another, this.den);
|
|
127
|
+
timesNum(another, factorized = false) {
|
|
128
|
+
return new Fraction(this.num * another, this.den, factorized);
|
|
124
129
|
}
|
|
125
|
-
divby(another) {
|
|
126
|
-
return new Fraction(this.num * another.den, this.den * another.num);
|
|
130
|
+
divby(another, factorized = false) {
|
|
131
|
+
return new Fraction(this.num * another.den, this.den * another.num, factorized);
|
|
127
132
|
}
|
|
128
|
-
divbyNum(another) {
|
|
129
|
-
return new Fraction(this.num, this.den * another);
|
|
133
|
+
divbyNum(another, factorized = false) {
|
|
134
|
+
return new Fraction(this.num, this.den * another, factorized);
|
|
130
135
|
}
|
|
131
|
-
numDivby(another) {
|
|
132
|
-
return new Fraction(this.den * another, this.num);
|
|
136
|
+
numDivby(another, factorized = false) {
|
|
137
|
+
return new Fraction(this.den * another, this.num, factorized);
|
|
133
138
|
}
|
|
134
139
|
mod(another) {
|
|
135
140
|
const d = this.divby(another);
|
|
@@ -198,6 +203,6 @@ exports.Fraction = Fraction;
|
|
|
198
203
|
Fraction.ZERO = new Fraction();
|
|
199
204
|
Fraction.ONE = new Fraction(1, 1);
|
|
200
205
|
Fraction.INFINITY = new Fraction(1, 0);
|
|
201
|
-
const Frac = (a = 0, b = 1) => new Fraction(a, b);
|
|
206
|
+
const Frac = (a = 0, b = 1, factorized = false) => new Fraction(a, b, factorized);
|
|
202
207
|
exports.Frac = Frac;
|
|
203
208
|
//# sourceMappingURL=numberutils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"numberutils.js","sourceRoot":"","sources":["../../src/numberutils.ts"],"names":[],"mappings":"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","sourcesContent":["import { Nullable } from \"./types\";\n\nexport function range(start: number, end: Nullable<number> = null, incr: Nullable<number> = 1): number[] {\n if (end == null) {\n const absStart = Math.abs(start);\n const arr = Array.from({ length: absStart });\n if (start >= 0) {\n return arr.map((x, i) => i);\n } else {\n return arr.map((x, i) => i - (absStart - 1));\n }\n }\n const out: number[] = [];\n if (incr == null) {\n incr = 1;\n }\n incr = Math.abs(incr);\n if (start !== end) {\n if (start < end) {\n for (let i = start; i <= end; i += incr) {\n out.push(i);\n }\n } else {\n for (let i = start; i >= end; i -= incr) {\n out.push(i);\n }\n }\n }\n return out;\n}\n\n/*\nexport function applyMixins(derivedCtor: any, baseCtors: any[]) {\n baseCtors.forEach(baseCtor => {\n Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {\n Object.defineProperty(derivedCtor.prototype, name,\n Object.getOwnPropertyDescriptor(baseCtor.prototype, name));\n });\n });\n}\n*/\n\nexport function gcdof(x: number, y: number): number {\n x = Math.abs(x);\n y = Math.abs(y);\n while (y > 0) {\n const t = y;\n y = x % y;\n x = t;\n }\n return x;\n}\n\nexport class Fraction {\n readonly num: number;\n readonly den: number;\n\n static readonly ZERO = new Fraction();\n static readonly ONE = new Fraction(1, 1);\n static readonly INFINITY = new Fraction(1, 0);\n\n constructor(num = 0, den = 1) {\n if (isNaN(num) || isNaN(den)) {\n throw new Error(`Invalid numerator(${num}) or denminator(${den})`);\n }\n this.num = num;\n this.den = den;\n }\n\n static parse(val: string): Fraction {\n const parts = val\n .trim()\n .split(\"/\")\n .map((x) => x.trim());\n let num = 1;\n let den = 1;\n if (parts.length == 1) num = parseInt(parts[0]);\n else if (parts.length != 2) {\n throw new Error(\"Invalid fraction string: \" + val);\n } else {\n if (parts[0].length > 0) {\n num = parseInt(parts[0]);\n }\n if (parts[1].length > 0) {\n den = parseInt(parts[1]);\n }\n }\n if (isNaN(num) || isNaN(den)) {\n throw new Error(\"Invalid fraction string: \" + val);\n }\n return new Fraction(num, den);\n }\n\n get isWhole(): boolean {\n return this.num % this.den == 0;\n }\n\n get isZero(): boolean {\n return this.num == 0;\n }\n\n get isInfinity(): boolean {\n return this.den == 0;\n }\n\n get isOne(): boolean {\n return this.num == this.den;\n }\n\n get ceil(): number {\n if (this.num % this.den == 0) {\n return this.num / this.den;\n } else {\n return 1 + Math.floor(this.num / this.den);\n }\n }\n\n get floor(): number {\n if (this.num % this.den == 0) {\n return this.num / this.den;\n } else {\n return Math.floor(this.num / this.den);\n }\n }\n\n plus(another: Fraction): Fraction {\n return new Fraction(this.num * another.den + this.den * another.num, this.den * another.den);\n }\n\n plusNum(another: number): Fraction {\n return new Fraction(this.num + this.den * another, this.den);\n }\n\n minus(another: Fraction): Fraction {\n return new Fraction(this.num * another.den - this.den * another.num, this.den * another.den);\n }\n\n minusNum(another: number): Fraction {\n return new Fraction(this.num - this.den * another, this.den);\n }\n\n times(another: Fraction): Fraction {\n return new Fraction(this.num * another.num, this.den * another.den);\n }\n\n timesNum(another: number): Fraction {\n return new Fraction(this.num * another, this.den);\n }\n\n divby(another: Fraction): Fraction {\n return new Fraction(this.num * another.den, this.den * another.num);\n }\n\n divbyNum(another: number): Fraction {\n return new Fraction(this.num, this.den * another);\n }\n\n /**\n * Returns another / this.\n */\n numDivby(another: number): Fraction {\n return new Fraction(this.den * another, this.num);\n }\n\n /**\n * Returns this % another\n */\n mod(another: Fraction): Fraction {\n // a (mod b) = a − b ⌊a / b⌋\n const d = this.divby(another);\n const floorOfD = Math.floor(d.num / d.den);\n return this.minus(another.timesNum(floorOfD));\n }\n\n /*\n * Returns this % another\n */\n modNum(another: number): Fraction {\n // a (mod b) = a − b ⌊a / b⌋\n const d = this.divbyNum(another);\n const floorOfD = Math.floor(d.num / d.den);\n return this.minusNum(another * floorOfD);\n }\n\n get inverse(): Fraction {\n return new Fraction(this.den, this.num);\n }\n\n get factorized(): Fraction {\n const gcd = gcdof(this.num, this.den);\n return new Fraction(this.num / gcd, this.den / gcd);\n }\n\n equals(another: Fraction): boolean {\n return this.num * another.den == this.den * another.num;\n }\n\n equalsNum(another: number): boolean {\n return this.num == this.den * another;\n }\n\n cmp(another: Fraction): number {\n return this.num * another.den - this.den * another.num;\n }\n\n cmpNum(another: number): number {\n return this.num - this.den * another;\n }\n\n isLT(another: Fraction): boolean {\n return this.cmp(another) < 0;\n }\n\n isLTE(another: Fraction): boolean {\n return this.cmp(another) <= 0;\n }\n\n isLTNum(another: number): boolean {\n return this.cmpNum(another) < 0;\n }\n\n isLTENum(another: number): boolean {\n return this.cmpNum(another) <= 0;\n }\n\n isGT(another: Fraction): boolean {\n return this.cmp(another) > 0;\n }\n\n isGTE(another: Fraction): boolean {\n return this.cmp(another) >= 0;\n }\n\n isGTNum(another: number): boolean {\n return this.cmpNum(another) > 0;\n }\n\n isGTENum(another: number): boolean {\n return this.cmpNum(another) >= 0;\n }\n\n toString(): string {\n return this.num + \"/\" + this.den;\n }\n\n static max(f1: Fraction, f2: Fraction): Fraction {\n return f1.cmp(f2) > 0 ? f1 : f2;\n }\n\n static min(f1: Fraction, f2: Fraction): Fraction {\n return f1.cmp(f2) < 0 ? f1 : f2;\n }\n}\n\n// Shortcut helper\nexport const Frac = (a = 0, b = 1): Fraction => new Fraction(a, b);\n"]}
|
|
1
|
+
{"version":3,"file":"numberutils.js","sourceRoot":"","sources":["../../src/numberutils.ts"],"names":[],"mappings":"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","sourcesContent":["import { Nullable } from \"./types\";\n\nexport function range(start: number, end: Nullable<number> = null, incr: Nullable<number> = 1): number[] {\n if (end == null) {\n const absStart = Math.abs(start);\n const arr = Array.from({ length: absStart });\n if (start >= 0) {\n return arr.map((x, i) => i);\n } else {\n return arr.map((x, i) => i - (absStart - 1));\n }\n }\n const out: number[] = [];\n if (incr == null) {\n incr = 1;\n }\n incr = Math.abs(incr);\n if (start !== end) {\n if (start < end) {\n for (let i = start; i <= end; i += incr) {\n out.push(i);\n }\n } else {\n for (let i = start; i >= end; i -= incr) {\n out.push(i);\n }\n }\n }\n return out;\n}\n\n/*\nexport function applyMixins(derivedCtor: any, baseCtors: any[]) {\n baseCtors.forEach(baseCtor => {\n Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {\n Object.defineProperty(derivedCtor.prototype, name,\n Object.getOwnPropertyDescriptor(baseCtor.prototype, name));\n });\n });\n}\n*/\n\nexport function gcdof(x: number, y: number): number {\n x = Math.abs(x);\n y = Math.abs(y);\n while (y > 0) {\n const t = y;\n y = x % y;\n x = t;\n }\n return x;\n}\n\nexport class Fraction {\n readonly num: number;\n readonly den: number;\n\n static readonly ZERO = new Fraction();\n static readonly ONE = new Fraction(1, 1);\n static readonly INFINITY = new Fraction(1, 0);\n\n constructor(num = 0, den = 1, factorized = false) {\n if (isNaN(num) || isNaN(den)) {\n throw new Error(`Invalid numerator(${num}) or denminator(${den})`);\n }\n if (factorized) {\n const gcd = gcdof(num, den);\n num /= gcd;\n den /= gcd;\n }\n this.num = num;\n this.den = den;\n }\n\n static parse(val: string, factorized = false): Fraction {\n const parts = val\n .trim()\n .split(\"/\")\n .map((x) => x.trim());\n let num = 1;\n let den = 1;\n if (parts.length == 1) num = parseInt(parts[0]);\n else if (parts.length != 2) {\n throw new Error(\"Invalid fraction string: \" + val);\n } else {\n if (parts[0].length > 0) {\n num = parseInt(parts[0]);\n }\n if (parts[1].length > 0) {\n den = parseInt(parts[1]);\n }\n }\n if (isNaN(num) || isNaN(den)) {\n throw new Error(\"Invalid fraction string: \" + val);\n }\n return new Fraction(num, den, factorized);\n }\n\n get isWhole(): boolean {\n return this.num % this.den == 0;\n }\n\n get isZero(): boolean {\n return this.num == 0;\n }\n\n get isInfinity(): boolean {\n return this.den == 0;\n }\n\n get isOne(): boolean {\n return this.num == this.den;\n }\n\n get ceil(): number {\n if (this.num % this.den == 0) {\n return this.num / this.den;\n } else {\n return 1 + Math.floor(this.num / this.den);\n }\n }\n\n get floor(): number {\n if (this.num % this.den == 0) {\n return this.num / this.den;\n } else {\n return Math.floor(this.num / this.den);\n }\n }\n\n plus(another: Fraction, factorized = false): Fraction {\n return new Fraction(this.num * another.den + this.den * another.num, this.den * another.den, factorized);\n }\n\n plusNum(another: number, factorized = false): Fraction {\n return new Fraction(this.num + this.den * another, this.den, factorized);\n }\n\n minus(another: Fraction, factorized = false): Fraction {\n return new Fraction(this.num * another.den - this.den * another.num, this.den * another.den, factorized);\n }\n\n minusNum(another: number, factorized = false): Fraction {\n return new Fraction(this.num - this.den * another, this.den, factorized);\n }\n\n times(another: Fraction, factorized = false): Fraction {\n return new Fraction(this.num * another.num, this.den * another.den, factorized);\n }\n\n timesNum(another: number, factorized = false): Fraction {\n return new Fraction(this.num * another, this.den, factorized);\n }\n\n divby(another: Fraction, factorized = false): Fraction {\n return new Fraction(this.num * another.den, this.den * another.num, factorized);\n }\n\n divbyNum(another: number, factorized = false): Fraction {\n return new Fraction(this.num, this.den * another, factorized);\n }\n\n /**\n * Returns another / this.\n */\n numDivby(another: number, factorized = false): Fraction {\n return new Fraction(this.den * another, this.num, factorized);\n }\n\n /**\n * Returns this % another\n */\n mod(another: Fraction): Fraction {\n // a (mod b) = a − b ⌊a / b⌋\n const d = this.divby(another);\n const floorOfD = Math.floor(d.num / d.den);\n return this.minus(another.timesNum(floorOfD));\n }\n\n /*\n * Returns this % another\n */\n modNum(another: number): Fraction {\n // a (mod b) = a − b ⌊a / b⌋\n const d = this.divbyNum(another);\n const floorOfD = Math.floor(d.num / d.den);\n return this.minusNum(another * floorOfD);\n }\n\n get inverse(): Fraction {\n return new Fraction(this.den, this.num);\n }\n\n get factorized(): Fraction {\n const gcd = gcdof(this.num, this.den);\n return new Fraction(this.num / gcd, this.den / gcd);\n }\n\n equals(another: Fraction): boolean {\n return this.num * another.den == this.den * another.num;\n }\n\n equalsNum(another: number): boolean {\n return this.num == this.den * another;\n }\n\n cmp(another: Fraction): number {\n return this.num * another.den - this.den * another.num;\n }\n\n cmpNum(another: number): number {\n return this.num - this.den * another;\n }\n\n isLT(another: Fraction): boolean {\n return this.cmp(another) < 0;\n }\n\n isLTE(another: Fraction): boolean {\n return this.cmp(another) <= 0;\n }\n\n isLTNum(another: number): boolean {\n return this.cmpNum(another) < 0;\n }\n\n isLTENum(another: number): boolean {\n return this.cmpNum(another) <= 0;\n }\n\n isGT(another: Fraction): boolean {\n return this.cmp(another) > 0;\n }\n\n isGTE(another: Fraction): boolean {\n return this.cmp(another) >= 0;\n }\n\n isGTNum(another: number): boolean {\n return this.cmpNum(another) > 0;\n }\n\n isGTENum(another: number): boolean {\n return this.cmpNum(another) >= 0;\n }\n\n toString(): string {\n return this.num + \"/\" + this.den;\n }\n\n static max(f1: Fraction, f2: Fraction): Fraction {\n return f1.cmp(f2) > 0 ? f1 : f2;\n }\n\n static min(f1: Fraction, f2: Fraction): Fraction {\n return f1.cmp(f2) < 0 ? f1 : f2;\n }\n}\n\n// Shortcut helper\nexport const Frac = (a = 0, b = 1, factorized = false): Fraction => new Fraction(a, b, factorized);\n"]}
|
package/lib/esm/list.d.ts
CHANGED
|
@@ -23,11 +23,12 @@ export declare class ValueList<V extends ListNode<V>> {
|
|
|
23
23
|
get last(): Nullable<V>;
|
|
24
24
|
reversedValues(): Generator<V>;
|
|
25
25
|
values(): Generator<V>;
|
|
26
|
-
popBack(): V;
|
|
27
|
-
popFront(): V;
|
|
28
26
|
add(child: V, before?: Nullable<V>): this;
|
|
29
27
|
pushFront(value: V): this;
|
|
30
|
-
|
|
28
|
+
pushBack(value: V): this;
|
|
29
|
+
remove(child: V): this;
|
|
30
|
+
popBack(): V;
|
|
31
|
+
popFront(): V;
|
|
31
32
|
}
|
|
32
33
|
export declare class List<V> {
|
|
33
34
|
private container;
|
|
@@ -35,6 +36,7 @@ export declare class List<V> {
|
|
|
35
36
|
toJSON(): V[];
|
|
36
37
|
forEach(method: (val: V) => boolean | any): number;
|
|
37
38
|
equals(another: List<V>, eqlFunc: (val1: V, val2: V) => boolean): boolean;
|
|
39
|
+
find(target: V): Nullable<MutableListNode<V>>;
|
|
38
40
|
get isEmpty(): boolean;
|
|
39
41
|
get size(): number;
|
|
40
42
|
get first(): Nullable<MutableListNode<V>>;
|
package/lib/esm/list.js
CHANGED
|
@@ -11,7 +11,7 @@ export class ValueList {
|
|
|
11
11
|
this._lastChild = null;
|
|
12
12
|
this._size = 0;
|
|
13
13
|
for (const v of values)
|
|
14
|
-
this.
|
|
14
|
+
this.pushBack(v);
|
|
15
15
|
}
|
|
16
16
|
toJSON() {
|
|
17
17
|
return Array.from(this.values());
|
|
@@ -66,39 +66,11 @@ export class ValueList {
|
|
|
66
66
|
tmp = tmp.nextSibling;
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
|
-
popBack() {
|
|
70
|
-
if (this._lastChild == null) {
|
|
71
|
-
throw new Error("No children");
|
|
72
|
-
}
|
|
73
|
-
const out = this._lastChild;
|
|
74
|
-
const prev = this._lastChild.prevSibling;
|
|
75
|
-
this._size--;
|
|
76
|
-
if (prev == null) {
|
|
77
|
-
this._firstChild = this._lastChild = null;
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
prev.nextSibling = null;
|
|
81
|
-
this._lastChild = prev;
|
|
82
|
-
}
|
|
83
|
-
return out;
|
|
84
|
-
}
|
|
85
|
-
popFront() {
|
|
86
|
-
if (this._firstChild == null) {
|
|
87
|
-
throw new Error("No children");
|
|
88
|
-
}
|
|
89
|
-
const out = this._firstChild;
|
|
90
|
-
const next = this._firstChild.nextSibling;
|
|
91
|
-
this._size--;
|
|
92
|
-
if (next == null) {
|
|
93
|
-
this._firstChild = this._lastChild = null;
|
|
94
|
-
}
|
|
95
|
-
else {
|
|
96
|
-
next.prevSibling = null;
|
|
97
|
-
this._firstChild = next;
|
|
98
|
-
}
|
|
99
|
-
return out;
|
|
100
|
-
}
|
|
101
69
|
add(child, before = null) {
|
|
70
|
+
if (child.nextSibling != null || child.prevSibling != null) {
|
|
71
|
+
throw new Error("New node already added to a list. Remove it first");
|
|
72
|
+
}
|
|
73
|
+
child.nextSibling = child.prevSibling = null;
|
|
102
74
|
this._size++;
|
|
103
75
|
if (this._firstChild == null || this._lastChild == null) {
|
|
104
76
|
this._firstChild = this._lastChild = child;
|
|
@@ -116,13 +88,10 @@ export class ValueList {
|
|
|
116
88
|
this._firstChild = child;
|
|
117
89
|
}
|
|
118
90
|
else {
|
|
119
|
-
const next = before.nextSibling;
|
|
120
91
|
const prev = before.prevSibling;
|
|
121
|
-
child.nextSibling =
|
|
92
|
+
child.nextSibling = before;
|
|
93
|
+
before.prevSibling = child;
|
|
122
94
|
child.prevSibling = prev;
|
|
123
|
-
if (next != null) {
|
|
124
|
-
next.prevSibling = child;
|
|
125
|
-
}
|
|
126
95
|
if (prev != null) {
|
|
127
96
|
prev.nextSibling = child;
|
|
128
97
|
}
|
|
@@ -132,9 +101,48 @@ export class ValueList {
|
|
|
132
101
|
pushFront(value) {
|
|
133
102
|
return this.add(value, this._firstChild);
|
|
134
103
|
}
|
|
135
|
-
|
|
104
|
+
pushBack(value) {
|
|
136
105
|
return this.add(value);
|
|
137
106
|
}
|
|
107
|
+
remove(child) {
|
|
108
|
+
const next = child.nextSibling;
|
|
109
|
+
const prev = child.prevSibling;
|
|
110
|
+
if (next == null) {
|
|
111
|
+
this._lastChild = prev;
|
|
112
|
+
if (prev == null)
|
|
113
|
+
this._firstChild = null;
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
next.prevSibling = prev;
|
|
117
|
+
}
|
|
118
|
+
if (prev == null) {
|
|
119
|
+
this._firstChild = next;
|
|
120
|
+
if (next == null)
|
|
121
|
+
this._lastChild = null;
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
prev.nextSibling = next;
|
|
125
|
+
}
|
|
126
|
+
this._size--;
|
|
127
|
+
child.prevSibling = child.nextSibling = null;
|
|
128
|
+
return this;
|
|
129
|
+
}
|
|
130
|
+
popBack() {
|
|
131
|
+
if (this._lastChild == null) {
|
|
132
|
+
throw new Error("No children");
|
|
133
|
+
}
|
|
134
|
+
const out = this._lastChild;
|
|
135
|
+
this.remove(out);
|
|
136
|
+
return out;
|
|
137
|
+
}
|
|
138
|
+
popFront() {
|
|
139
|
+
if (this._firstChild == null) {
|
|
140
|
+
throw new Error("No children");
|
|
141
|
+
}
|
|
142
|
+
const out = this._firstChild;
|
|
143
|
+
this.remove(out);
|
|
144
|
+
return out;
|
|
145
|
+
}
|
|
138
146
|
}
|
|
139
147
|
export class List {
|
|
140
148
|
constructor(...values) {
|
|
@@ -151,6 +159,14 @@ export class List {
|
|
|
151
159
|
equals(another, eqlFunc) {
|
|
152
160
|
return this.container.equals(another.container, (a, b) => eqlFunc(a.value, b.value));
|
|
153
161
|
}
|
|
162
|
+
find(target) {
|
|
163
|
+
for (const v of this.container.values()) {
|
|
164
|
+
if (target == v.value) {
|
|
165
|
+
return v;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
154
170
|
get isEmpty() {
|
|
155
171
|
return this.container.isEmpty;
|
|
156
172
|
}
|
package/lib/esm/list.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/list.ts"],"names":[],"mappings":"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","sourcesContent":["import { Nullable } from \"./types\";\n\nexport interface ListNode<V> {\n nextSibling: Nullable<V>;\n prevSibling: Nullable<V>;\n}\n\nclass MutableListNode<V> implements ListNode<MutableListNode<V>> {\n nextSibling: Nullable<MutableListNode<V>> = null;\n prevSibling: Nullable<MutableListNode<V>> = null;\n constructor(public value: V) {}\n}\n\n/**\n * A list implementation where the value itself contains next and prev pointers\n * so we do not need to create wrapper classes.\n */\nexport class ValueList<V extends ListNode<V>> {\n protected _firstChild: Nullable<V> = null;\n protected _lastChild: Nullable<V> = null;\n protected _size = 0;\n\n constructor(...values: V[]) {\n for (const v of values) this.push(v);\n }\n\n toJSON(): V[] {\n return Array.from(this.values());\n }\n\n forEach(method: (val: V) => boolean | any): number {\n let tmp: V | null = this._firstChild;\n let count = 0;\n while (tmp != null) {\n if (method(tmp) == false) {\n break;\n }\n count++;\n tmp = tmp.nextSibling;\n }\n return count;\n }\n\n equals(another: ValueList<V>, eqlFunc: (val1: V, val2: V) => boolean): boolean {\n if (this.size != another.size) return false;\n let tmp = this.first;\n let tmp2 = another.first;\n for (; tmp != null && tmp2 != null; tmp = tmp.nextSibling, tmp2 = tmp2.nextSibling) {\n if (!eqlFunc(tmp, tmp2)) {\n return false;\n }\n }\n return tmp == null && tmp2 == null;\n }\n\n get isEmpty(): boolean {\n return this._size == 0;\n }\n\n get size(): number {\n return this._size;\n }\n\n get first(): Nullable<V> {\n return this._firstChild;\n }\n\n get last(): Nullable<V> {\n return this._lastChild;\n }\n\n /**\n * Generator of values in reverse order.\n */\n *reversedValues(): Generator<V> {\n let tmp = this._lastChild;\n while (tmp != null) {\n yield tmp;\n tmp = tmp.prevSibling;\n }\n }\n\n /**\n * Generator of values in forward order.\n */\n *values(): Generator<V> {\n let tmp = this._firstChild;\n while (tmp != null) {\n yield tmp;\n tmp = tmp.nextSibling;\n }\n }\n\n popBack(): V {\n if (this._lastChild == null) {\n throw new Error(\"No children\");\n }\n const out = this._lastChild;\n const prev = this._lastChild.prevSibling;\n this._size--;\n if (prev == null) {\n this._firstChild = this._lastChild = null;\n } else {\n prev.nextSibling = null;\n this._lastChild = prev;\n }\n return out;\n }\n\n popFront(): V {\n if (this._firstChild == null) {\n throw new Error(\"No children\");\n }\n const out = this._firstChild;\n const next = this._firstChild.nextSibling;\n this._size--;\n if (next == null) {\n this._firstChild = this._lastChild = null;\n } else {\n next.prevSibling = null;\n this._firstChild = next;\n }\n return out;\n }\n\n add(child: V, before: Nullable<V> = null): this {\n this._size++;\n if (this._firstChild == null || this._lastChild == null) {\n this._firstChild = this._lastChild = child;\n } else if (before == null) {\n child.prevSibling = this._lastChild;\n child.nextSibling = null;\n this._lastChild.nextSibling = child;\n this._lastChild = child;\n } else if (before == this._firstChild) {\n child.nextSibling = before;\n child.prevSibling = null;\n this._firstChild.prevSibling = child;\n this._firstChild = child;\n } else {\n const next = before.nextSibling;\n const prev = before.prevSibling;\n child.nextSibling = next;\n child.prevSibling = prev;\n if (next != null) {\n next.prevSibling = child;\n }\n if (prev != null) {\n prev.nextSibling = child;\n }\n }\n return this;\n }\n\n pushFront(value: V): this {\n return this.add(value, this._firstChild);\n }\n\n push(value: V): this {\n return this.add(value);\n }\n}\n\n/**\n * A list implementation where the values themselves need to be wrapper in a list node.\n * If values already have sibling node properties they can be direclty used via ValueLists.\n */\nexport class List<V> {\n private container: ValueList<MutableListNode<V>>;\n\n constructor(...values: V[]) {\n this.container = new ValueList<MutableListNode<V>>();\n for (const v of values) this.push(v);\n }\n\n toJSON(): V[] {\n return Array.from(this.values());\n }\n\n forEach(method: (val: V) => boolean | any): number {\n return this.container.forEach((v) => method(v.value));\n }\n\n equals(another: List<V>, eqlFunc: (val1: V, val2: V) => boolean): boolean {\n return this.container.equals(another.container, (a, b) => eqlFunc(a.value, b.value));\n }\n\n get isEmpty(): boolean {\n return this.container.isEmpty;\n }\n\n get size(): number {\n return this.container.size;\n }\n\n get first(): Nullable<MutableListNode<V>> {\n return this.container.first;\n }\n\n get last(): Nullable<MutableListNode<V>> {\n return this.container.last;\n }\n\n /**\n * Generator of values in reverse order.\n */\n *reversedValues(): Generator<V> {\n for (const v of this.container.reversedValues()) yield v.value;\n }\n\n /**\n * Generator of values in forward order.\n */\n *values(): Generator<V> {\n for (const v of this.container.values()) yield v.value;\n }\n\n popBack(): V {\n return this.container.popBack().value;\n }\n\n popFront(): V {\n return this.container.popFront().value;\n }\n\n pushFront(value: V): this {\n return this.add(value, this.container.first);\n }\n\n push(value: V): this {\n return this.add(value);\n }\n\n add(child: V, before: Nullable<MutableListNode<V>> = null): this {\n this.container.add(new MutableListNode(child), before);\n return this;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/list.ts"],"names":[],"mappings":"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","sourcesContent":["import { Nullable } from \"./types\";\n\nexport interface ListNode<V> {\n nextSibling: Nullable<V>;\n prevSibling: Nullable<V>;\n}\n\nclass MutableListNode<V> implements ListNode<MutableListNode<V>> {\n nextSibling: Nullable<MutableListNode<V>> = null;\n prevSibling: Nullable<MutableListNode<V>> = null;\n constructor(public value: V) {}\n}\n\n/**\n * A list implementation where the value itself contains next and prev pointers\n * so we do not need to create wrapper classes.\n */\nexport class ValueList<V extends ListNode<V>> {\n protected _firstChild: Nullable<V> = null;\n protected _lastChild: Nullable<V> = null;\n protected _size = 0;\n\n constructor(...values: V[]) {\n for (const v of values) this.pushBack(v);\n }\n\n toJSON(): V[] {\n return Array.from(this.values());\n }\n\n forEach(method: (val: V) => boolean | any): number {\n let tmp: V | null = this._firstChild;\n let count = 0;\n while (tmp != null) {\n if (method(tmp) == false) {\n break;\n }\n count++;\n tmp = tmp.nextSibling;\n }\n return count;\n }\n\n equals(another: ValueList<V>, eqlFunc: (val1: V, val2: V) => boolean): boolean {\n if (this.size != another.size) return false;\n let tmp = this.first;\n let tmp2 = another.first;\n for (; tmp != null && tmp2 != null; tmp = tmp.nextSibling, tmp2 = tmp2.nextSibling) {\n if (!eqlFunc(tmp, tmp2)) {\n return false;\n }\n }\n return tmp == null && tmp2 == null;\n }\n\n get isEmpty(): boolean {\n return this._size == 0;\n }\n\n get size(): number {\n return this._size;\n }\n\n get first(): Nullable<V> {\n return this._firstChild;\n }\n\n get last(): Nullable<V> {\n return this._lastChild;\n }\n\n /**\n * Generator of values in reverse order.\n */\n *reversedValues(): Generator<V> {\n let tmp = this._lastChild;\n while (tmp != null) {\n yield tmp;\n tmp = tmp.prevSibling;\n }\n }\n\n /**\n * Generator of values in forward order.\n */\n *values(): Generator<V> {\n let tmp = this._firstChild;\n while (tmp != null) {\n yield tmp;\n tmp = tmp.nextSibling;\n }\n }\n\n add(child: V, before: Nullable<V> = null): this {\n // Ensure that this node is not added anywhere else\n if (child.nextSibling != null || child.prevSibling != null) {\n throw new Error(\"New node already added to a list. Remove it first\");\n }\n child.nextSibling = child.prevSibling = null;\n this._size++;\n if (this._firstChild == null || this._lastChild == null) {\n this._firstChild = this._lastChild = child;\n } else if (before == null) {\n child.prevSibling = this._lastChild;\n child.nextSibling = null;\n this._lastChild.nextSibling = child;\n this._lastChild = child;\n } else if (before == this._firstChild) {\n child.nextSibling = before;\n child.prevSibling = null;\n this._firstChild.prevSibling = child;\n this._firstChild = child;\n } else {\n const prev = before.prevSibling;\n child.nextSibling = before;\n before.prevSibling = child;\n child.prevSibling = prev;\n if (prev != null) {\n prev.nextSibling = child;\n }\n }\n return this;\n }\n\n pushFront(value: V): this {\n return this.add(value, this._firstChild);\n }\n\n pushBack(value: V): this {\n return this.add(value);\n }\n\n /**\n * Removes a child node from this list.\n * It is upto the caller to ensure that this node indeed belongs\n * to this list otherwise deletion of a non belonging node could result\n * in undefined behaviour.\n */\n remove(child: V): this {\n const next = child.nextSibling;\n const prev = child.prevSibling;\n\n if (next == null) {\n this._lastChild = prev;\n if (prev == null) this._firstChild = null;\n } else {\n next.prevSibling = prev;\n }\n\n if (prev == null) {\n this._firstChild = next;\n if (next == null) this._lastChild = null;\n } else {\n prev.nextSibling = next;\n }\n\n this._size--;\n\n child.prevSibling = child.nextSibling = null;\n return this;\n }\n\n popBack(): V {\n if (this._lastChild == null) {\n throw new Error(\"No children\");\n }\n const out = this._lastChild;\n this.remove(out);\n return out;\n }\n\n popFront(): V {\n if (this._firstChild == null) {\n throw new Error(\"No children\");\n }\n const out = this._firstChild;\n this.remove(out);\n return out;\n }\n}\n\n/**\n * A list implementation where the values themselves need to be wrapper in a list node.\n * If values already have sibling node properties they can be direclty used\n * via ValueLists.\n */\nexport class List<V> {\n private container: ValueList<MutableListNode<V>>;\n\n constructor(...values: V[]) {\n this.container = new ValueList<MutableListNode<V>>();\n for (const v of values) this.push(v);\n }\n\n toJSON(): V[] {\n return Array.from(this.values());\n }\n\n forEach(method: (val: V) => boolean | any): number {\n return this.container.forEach((v) => method(v.value));\n }\n\n equals(another: List<V>, eqlFunc: (val1: V, val2: V) => boolean): boolean {\n return this.container.equals(another.container, (a, b) => eqlFunc(a.value, b.value));\n }\n\n find(target: V): Nullable<MutableListNode<V>> {\n for (const v of this.container.values()) {\n if (target == v.value) {\n return v;\n }\n }\n return null;\n }\n\n get isEmpty(): boolean {\n return this.container.isEmpty;\n }\n\n get size(): number {\n return this.container.size;\n }\n\n get first(): Nullable<MutableListNode<V>> {\n return this.container.first;\n }\n\n get last(): Nullable<MutableListNode<V>> {\n return this.container.last;\n }\n\n /**\n * Generator of values in reverse order.\n */\n *reversedValues(): Generator<V> {\n for (const v of this.container.reversedValues()) yield v.value;\n }\n\n /**\n * Generator of values in forward order.\n */\n *values(): Generator<V> {\n for (const v of this.container.values()) yield v.value;\n }\n\n popBack(): V {\n return this.container.popBack().value;\n }\n\n popFront(): V {\n return this.container.popFront().value;\n }\n\n pushFront(value: V): this {\n return this.add(value, this.container.first);\n }\n\n push(value: V): this {\n return this.add(value);\n }\n\n add(child: V, before: Nullable<MutableListNode<V>> = null): this {\n this.container.add(new MutableListNode(child), before);\n return this;\n }\n}\n"]}
|
package/lib/esm/numberutils.d.ts
CHANGED
|
@@ -7,23 +7,23 @@ export declare class Fraction {
|
|
|
7
7
|
static readonly ZERO: Fraction;
|
|
8
8
|
static readonly ONE: Fraction;
|
|
9
9
|
static readonly INFINITY: Fraction;
|
|
10
|
-
constructor(num?: number, den?: number);
|
|
11
|
-
static parse(val: string): Fraction;
|
|
10
|
+
constructor(num?: number, den?: number, factorized?: boolean);
|
|
11
|
+
static parse(val: string, factorized?: boolean): Fraction;
|
|
12
12
|
get isWhole(): boolean;
|
|
13
13
|
get isZero(): boolean;
|
|
14
14
|
get isInfinity(): boolean;
|
|
15
15
|
get isOne(): boolean;
|
|
16
16
|
get ceil(): number;
|
|
17
17
|
get floor(): number;
|
|
18
|
-
plus(another: Fraction): Fraction;
|
|
19
|
-
plusNum(another: number): Fraction;
|
|
20
|
-
minus(another: Fraction): Fraction;
|
|
21
|
-
minusNum(another: number): Fraction;
|
|
22
|
-
times(another: Fraction): Fraction;
|
|
23
|
-
timesNum(another: number): Fraction;
|
|
24
|
-
divby(another: Fraction): Fraction;
|
|
25
|
-
divbyNum(another: number): Fraction;
|
|
26
|
-
numDivby(another: number): Fraction;
|
|
18
|
+
plus(another: Fraction, factorized?: boolean): Fraction;
|
|
19
|
+
plusNum(another: number, factorized?: boolean): Fraction;
|
|
20
|
+
minus(another: Fraction, factorized?: boolean): Fraction;
|
|
21
|
+
minusNum(another: number, factorized?: boolean): Fraction;
|
|
22
|
+
times(another: Fraction, factorized?: boolean): Fraction;
|
|
23
|
+
timesNum(another: number, factorized?: boolean): Fraction;
|
|
24
|
+
divby(another: Fraction, factorized?: boolean): Fraction;
|
|
25
|
+
divbyNum(another: number, factorized?: boolean): Fraction;
|
|
26
|
+
numDivby(another: number, factorized?: boolean): Fraction;
|
|
27
27
|
mod(another: Fraction): Fraction;
|
|
28
28
|
modNum(another: number): Fraction;
|
|
29
29
|
get inverse(): Fraction;
|
|
@@ -44,4 +44,4 @@ export declare class Fraction {
|
|
|
44
44
|
static max(f1: Fraction, f2: Fraction): Fraction;
|
|
45
45
|
static min(f1: Fraction, f2: Fraction): Fraction;
|
|
46
46
|
}
|
|
47
|
-
export declare const Frac: (a?: number, b?: number) => Fraction;
|
|
47
|
+
export declare const Frac: (a?: number, b?: number, factorized?: boolean) => Fraction;
|
package/lib/esm/numberutils.js
CHANGED
|
@@ -39,14 +39,19 @@ export function gcdof(x, y) {
|
|
|
39
39
|
return x;
|
|
40
40
|
}
|
|
41
41
|
export class Fraction {
|
|
42
|
-
constructor(num = 0, den = 1) {
|
|
42
|
+
constructor(num = 0, den = 1, factorized = false) {
|
|
43
43
|
if (isNaN(num) || isNaN(den)) {
|
|
44
44
|
throw new Error(`Invalid numerator(${num}) or denminator(${den})`);
|
|
45
45
|
}
|
|
46
|
+
if (factorized) {
|
|
47
|
+
const gcd = gcdof(num, den);
|
|
48
|
+
num /= gcd;
|
|
49
|
+
den /= gcd;
|
|
50
|
+
}
|
|
46
51
|
this.num = num;
|
|
47
52
|
this.den = den;
|
|
48
53
|
}
|
|
49
|
-
static parse(val) {
|
|
54
|
+
static parse(val, factorized = false) {
|
|
50
55
|
const parts = val
|
|
51
56
|
.trim()
|
|
52
57
|
.split("/")
|
|
@@ -69,7 +74,7 @@ export class Fraction {
|
|
|
69
74
|
if (isNaN(num) || isNaN(den)) {
|
|
70
75
|
throw new Error("Invalid fraction string: " + val);
|
|
71
76
|
}
|
|
72
|
-
return new Fraction(num, den);
|
|
77
|
+
return new Fraction(num, den, factorized);
|
|
73
78
|
}
|
|
74
79
|
get isWhole() {
|
|
75
80
|
return this.num % this.den == 0;
|
|
@@ -99,32 +104,32 @@ export class Fraction {
|
|
|
99
104
|
return Math.floor(this.num / this.den);
|
|
100
105
|
}
|
|
101
106
|
}
|
|
102
|
-
plus(another) {
|
|
103
|
-
return new Fraction(this.num * another.den + this.den * another.num, this.den * another.den);
|
|
107
|
+
plus(another, factorized = false) {
|
|
108
|
+
return new Fraction(this.num * another.den + this.den * another.num, this.den * another.den, factorized);
|
|
104
109
|
}
|
|
105
|
-
plusNum(another) {
|
|
106
|
-
return new Fraction(this.num + this.den * another, this.den);
|
|
110
|
+
plusNum(another, factorized = false) {
|
|
111
|
+
return new Fraction(this.num + this.den * another, this.den, factorized);
|
|
107
112
|
}
|
|
108
|
-
minus(another) {
|
|
109
|
-
return new Fraction(this.num * another.den - this.den * another.num, this.den * another.den);
|
|
113
|
+
minus(another, factorized = false) {
|
|
114
|
+
return new Fraction(this.num * another.den - this.den * another.num, this.den * another.den, factorized);
|
|
110
115
|
}
|
|
111
|
-
minusNum(another) {
|
|
112
|
-
return new Fraction(this.num - this.den * another, this.den);
|
|
116
|
+
minusNum(another, factorized = false) {
|
|
117
|
+
return new Fraction(this.num - this.den * another, this.den, factorized);
|
|
113
118
|
}
|
|
114
|
-
times(another) {
|
|
115
|
-
return new Fraction(this.num * another.num, this.den * another.den);
|
|
119
|
+
times(another, factorized = false) {
|
|
120
|
+
return new Fraction(this.num * another.num, this.den * another.den, factorized);
|
|
116
121
|
}
|
|
117
|
-
timesNum(another) {
|
|
118
|
-
return new Fraction(this.num * another, this.den);
|
|
122
|
+
timesNum(another, factorized = false) {
|
|
123
|
+
return new Fraction(this.num * another, this.den, factorized);
|
|
119
124
|
}
|
|
120
|
-
divby(another) {
|
|
121
|
-
return new Fraction(this.num * another.den, this.den * another.num);
|
|
125
|
+
divby(another, factorized = false) {
|
|
126
|
+
return new Fraction(this.num * another.den, this.den * another.num, factorized);
|
|
122
127
|
}
|
|
123
|
-
divbyNum(another) {
|
|
124
|
-
return new Fraction(this.num, this.den * another);
|
|
128
|
+
divbyNum(another, factorized = false) {
|
|
129
|
+
return new Fraction(this.num, this.den * another, factorized);
|
|
125
130
|
}
|
|
126
|
-
numDivby(another) {
|
|
127
|
-
return new Fraction(this.den * another, this.num);
|
|
131
|
+
numDivby(another, factorized = false) {
|
|
132
|
+
return new Fraction(this.den * another, this.num, factorized);
|
|
128
133
|
}
|
|
129
134
|
mod(another) {
|
|
130
135
|
const d = this.divby(another);
|
|
@@ -192,5 +197,5 @@ export class Fraction {
|
|
|
192
197
|
Fraction.ZERO = new Fraction();
|
|
193
198
|
Fraction.ONE = new Fraction(1, 1);
|
|
194
199
|
Fraction.INFINITY = new Fraction(1, 0);
|
|
195
|
-
export const Frac = (a = 0, b = 1) => new Fraction(a, b);
|
|
200
|
+
export const Frac = (a = 0, b = 1, factorized = false) => new Fraction(a, b, factorized);
|
|
196
201
|
//# sourceMappingURL=numberutils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"numberutils.js","sourceRoot":"","sources":["../../src/numberutils.ts"],"names":[],"mappings":"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","sourcesContent":["import { Nullable } from \"./types\";\n\nexport function range(start: number, end: Nullable<number> = null, incr: Nullable<number> = 1): number[] {\n if (end == null) {\n const absStart = Math.abs(start);\n const arr = Array.from({ length: absStart });\n if (start >= 0) {\n return arr.map((x, i) => i);\n } else {\n return arr.map((x, i) => i - (absStart - 1));\n }\n }\n const out: number[] = [];\n if (incr == null) {\n incr = 1;\n }\n incr = Math.abs(incr);\n if (start !== end) {\n if (start < end) {\n for (let i = start; i <= end; i += incr) {\n out.push(i);\n }\n } else {\n for (let i = start; i >= end; i -= incr) {\n out.push(i);\n }\n }\n }\n return out;\n}\n\n/*\nexport function applyMixins(derivedCtor: any, baseCtors: any[]) {\n baseCtors.forEach(baseCtor => {\n Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {\n Object.defineProperty(derivedCtor.prototype, name,\n Object.getOwnPropertyDescriptor(baseCtor.prototype, name));\n });\n });\n}\n*/\n\nexport function gcdof(x: number, y: number): number {\n x = Math.abs(x);\n y = Math.abs(y);\n while (y > 0) {\n const t = y;\n y = x % y;\n x = t;\n }\n return x;\n}\n\nexport class Fraction {\n readonly num: number;\n readonly den: number;\n\n static readonly ZERO = new Fraction();\n static readonly ONE = new Fraction(1, 1);\n static readonly INFINITY = new Fraction(1, 0);\n\n constructor(num = 0, den = 1) {\n if (isNaN(num) || isNaN(den)) {\n throw new Error(`Invalid numerator(${num}) or denminator(${den})`);\n }\n this.num = num;\n this.den = den;\n }\n\n static parse(val: string): Fraction {\n const parts = val\n .trim()\n .split(\"/\")\n .map((x) => x.trim());\n let num = 1;\n let den = 1;\n if (parts.length == 1) num = parseInt(parts[0]);\n else if (parts.length != 2) {\n throw new Error(\"Invalid fraction string: \" + val);\n } else {\n if (parts[0].length > 0) {\n num = parseInt(parts[0]);\n }\n if (parts[1].length > 0) {\n den = parseInt(parts[1]);\n }\n }\n if (isNaN(num) || isNaN(den)) {\n throw new Error(\"Invalid fraction string: \" + val);\n }\n return new Fraction(num, den);\n }\n\n get isWhole(): boolean {\n return this.num % this.den == 0;\n }\n\n get isZero(): boolean {\n return this.num == 0;\n }\n\n get isInfinity(): boolean {\n return this.den == 0;\n }\n\n get isOne(): boolean {\n return this.num == this.den;\n }\n\n get ceil(): number {\n if (this.num % this.den == 0) {\n return this.num / this.den;\n } else {\n return 1 + Math.floor(this.num / this.den);\n }\n }\n\n get floor(): number {\n if (this.num % this.den == 0) {\n return this.num / this.den;\n } else {\n return Math.floor(this.num / this.den);\n }\n }\n\n plus(another: Fraction): Fraction {\n return new Fraction(this.num * another.den + this.den * another.num, this.den * another.den);\n }\n\n plusNum(another: number): Fraction {\n return new Fraction(this.num + this.den * another, this.den);\n }\n\n minus(another: Fraction): Fraction {\n return new Fraction(this.num * another.den - this.den * another.num, this.den * another.den);\n }\n\n minusNum(another: number): Fraction {\n return new Fraction(this.num - this.den * another, this.den);\n }\n\n times(another: Fraction): Fraction {\n return new Fraction(this.num * another.num, this.den * another.den);\n }\n\n timesNum(another: number): Fraction {\n return new Fraction(this.num * another, this.den);\n }\n\n divby(another: Fraction): Fraction {\n return new Fraction(this.num * another.den, this.den * another.num);\n }\n\n divbyNum(another: number): Fraction {\n return new Fraction(this.num, this.den * another);\n }\n\n /**\n * Returns another / this.\n */\n numDivby(another: number): Fraction {\n return new Fraction(this.den * another, this.num);\n }\n\n /**\n * Returns this % another\n */\n mod(another: Fraction): Fraction {\n // a (mod b) = a − b ⌊a / b⌋\n const d = this.divby(another);\n const floorOfD = Math.floor(d.num / d.den);\n return this.minus(another.timesNum(floorOfD));\n }\n\n /*\n * Returns this % another\n */\n modNum(another: number): Fraction {\n // a (mod b) = a − b ⌊a / b⌋\n const d = this.divbyNum(another);\n const floorOfD = Math.floor(d.num / d.den);\n return this.minusNum(another * floorOfD);\n }\n\n get inverse(): Fraction {\n return new Fraction(this.den, this.num);\n }\n\n get factorized(): Fraction {\n const gcd = gcdof(this.num, this.den);\n return new Fraction(this.num / gcd, this.den / gcd);\n }\n\n equals(another: Fraction): boolean {\n return this.num * another.den == this.den * another.num;\n }\n\n equalsNum(another: number): boolean {\n return this.num == this.den * another;\n }\n\n cmp(another: Fraction): number {\n return this.num * another.den - this.den * another.num;\n }\n\n cmpNum(another: number): number {\n return this.num - this.den * another;\n }\n\n isLT(another: Fraction): boolean {\n return this.cmp(another) < 0;\n }\n\n isLTE(another: Fraction): boolean {\n return this.cmp(another) <= 0;\n }\n\n isLTNum(another: number): boolean {\n return this.cmpNum(another) < 0;\n }\n\n isLTENum(another: number): boolean {\n return this.cmpNum(another) <= 0;\n }\n\n isGT(another: Fraction): boolean {\n return this.cmp(another) > 0;\n }\n\n isGTE(another: Fraction): boolean {\n return this.cmp(another) >= 0;\n }\n\n isGTNum(another: number): boolean {\n return this.cmpNum(another) > 0;\n }\n\n isGTENum(another: number): boolean {\n return this.cmpNum(another) >= 0;\n }\n\n toString(): string {\n return this.num + \"/\" + this.den;\n }\n\n static max(f1: Fraction, f2: Fraction): Fraction {\n return f1.cmp(f2) > 0 ? f1 : f2;\n }\n\n static min(f1: Fraction, f2: Fraction): Fraction {\n return f1.cmp(f2) < 0 ? f1 : f2;\n }\n}\n\n// Shortcut helper\nexport const Frac = (a = 0, b = 1): Fraction => new Fraction(a, b);\n"]}
|
|
1
|
+
{"version":3,"file":"numberutils.js","sourceRoot":"","sources":["../../src/numberutils.ts"],"names":[],"mappings":"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","sourcesContent":["import { Nullable } from \"./types\";\n\nexport function range(start: number, end: Nullable<number> = null, incr: Nullable<number> = 1): number[] {\n if (end == null) {\n const absStart = Math.abs(start);\n const arr = Array.from({ length: absStart });\n if (start >= 0) {\n return arr.map((x, i) => i);\n } else {\n return arr.map((x, i) => i - (absStart - 1));\n }\n }\n const out: number[] = [];\n if (incr == null) {\n incr = 1;\n }\n incr = Math.abs(incr);\n if (start !== end) {\n if (start < end) {\n for (let i = start; i <= end; i += incr) {\n out.push(i);\n }\n } else {\n for (let i = start; i >= end; i -= incr) {\n out.push(i);\n }\n }\n }\n return out;\n}\n\n/*\nexport function applyMixins(derivedCtor: any, baseCtors: any[]) {\n baseCtors.forEach(baseCtor => {\n Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {\n Object.defineProperty(derivedCtor.prototype, name,\n Object.getOwnPropertyDescriptor(baseCtor.prototype, name));\n });\n });\n}\n*/\n\nexport function gcdof(x: number, y: number): number {\n x = Math.abs(x);\n y = Math.abs(y);\n while (y > 0) {\n const t = y;\n y = x % y;\n x = t;\n }\n return x;\n}\n\nexport class Fraction {\n readonly num: number;\n readonly den: number;\n\n static readonly ZERO = new Fraction();\n static readonly ONE = new Fraction(1, 1);\n static readonly INFINITY = new Fraction(1, 0);\n\n constructor(num = 0, den = 1, factorized = false) {\n if (isNaN(num) || isNaN(den)) {\n throw new Error(`Invalid numerator(${num}) or denminator(${den})`);\n }\n if (factorized) {\n const gcd = gcdof(num, den);\n num /= gcd;\n den /= gcd;\n }\n this.num = num;\n this.den = den;\n }\n\n static parse(val: string, factorized = false): Fraction {\n const parts = val\n .trim()\n .split(\"/\")\n .map((x) => x.trim());\n let num = 1;\n let den = 1;\n if (parts.length == 1) num = parseInt(parts[0]);\n else if (parts.length != 2) {\n throw new Error(\"Invalid fraction string: \" + val);\n } else {\n if (parts[0].length > 0) {\n num = parseInt(parts[0]);\n }\n if (parts[1].length > 0) {\n den = parseInt(parts[1]);\n }\n }\n if (isNaN(num) || isNaN(den)) {\n throw new Error(\"Invalid fraction string: \" + val);\n }\n return new Fraction(num, den, factorized);\n }\n\n get isWhole(): boolean {\n return this.num % this.den == 0;\n }\n\n get isZero(): boolean {\n return this.num == 0;\n }\n\n get isInfinity(): boolean {\n return this.den == 0;\n }\n\n get isOne(): boolean {\n return this.num == this.den;\n }\n\n get ceil(): number {\n if (this.num % this.den == 0) {\n return this.num / this.den;\n } else {\n return 1 + Math.floor(this.num / this.den);\n }\n }\n\n get floor(): number {\n if (this.num % this.den == 0) {\n return this.num / this.den;\n } else {\n return Math.floor(this.num / this.den);\n }\n }\n\n plus(another: Fraction, factorized = false): Fraction {\n return new Fraction(this.num * another.den + this.den * another.num, this.den * another.den, factorized);\n }\n\n plusNum(another: number, factorized = false): Fraction {\n return new Fraction(this.num + this.den * another, this.den, factorized);\n }\n\n minus(another: Fraction, factorized = false): Fraction {\n return new Fraction(this.num * another.den - this.den * another.num, this.den * another.den, factorized);\n }\n\n minusNum(another: number, factorized = false): Fraction {\n return new Fraction(this.num - this.den * another, this.den, factorized);\n }\n\n times(another: Fraction, factorized = false): Fraction {\n return new Fraction(this.num * another.num, this.den * another.den, factorized);\n }\n\n timesNum(another: number, factorized = false): Fraction {\n return new Fraction(this.num * another, this.den, factorized);\n }\n\n divby(another: Fraction, factorized = false): Fraction {\n return new Fraction(this.num * another.den, this.den * another.num, factorized);\n }\n\n divbyNum(another: number, factorized = false): Fraction {\n return new Fraction(this.num, this.den * another, factorized);\n }\n\n /**\n * Returns another / this.\n */\n numDivby(another: number, factorized = false): Fraction {\n return new Fraction(this.den * another, this.num, factorized);\n }\n\n /**\n * Returns this % another\n */\n mod(another: Fraction): Fraction {\n // a (mod b) = a − b ⌊a / b⌋\n const d = this.divby(another);\n const floorOfD = Math.floor(d.num / d.den);\n return this.minus(another.timesNum(floorOfD));\n }\n\n /*\n * Returns this % another\n */\n modNum(another: number): Fraction {\n // a (mod b) = a − b ⌊a / b⌋\n const d = this.divbyNum(another);\n const floorOfD = Math.floor(d.num / d.den);\n return this.minusNum(another * floorOfD);\n }\n\n get inverse(): Fraction {\n return new Fraction(this.den, this.num);\n }\n\n get factorized(): Fraction {\n const gcd = gcdof(this.num, this.den);\n return new Fraction(this.num / gcd, this.den / gcd);\n }\n\n equals(another: Fraction): boolean {\n return this.num * another.den == this.den * another.num;\n }\n\n equalsNum(another: number): boolean {\n return this.num == this.den * another;\n }\n\n cmp(another: Fraction): number {\n return this.num * another.den - this.den * another.num;\n }\n\n cmpNum(another: number): number {\n return this.num - this.den * another;\n }\n\n isLT(another: Fraction): boolean {\n return this.cmp(another) < 0;\n }\n\n isLTE(another: Fraction): boolean {\n return this.cmp(another) <= 0;\n }\n\n isLTNum(another: number): boolean {\n return this.cmpNum(another) < 0;\n }\n\n isLTENum(another: number): boolean {\n return this.cmpNum(another) <= 0;\n }\n\n isGT(another: Fraction): boolean {\n return this.cmp(another) > 0;\n }\n\n isGTE(another: Fraction): boolean {\n return this.cmp(another) >= 0;\n }\n\n isGTNum(another: number): boolean {\n return this.cmpNum(another) > 0;\n }\n\n isGTENum(another: number): boolean {\n return this.cmpNum(another) >= 0;\n }\n\n toString(): string {\n return this.num + \"/\" + this.den;\n }\n\n static max(f1: Fraction, f2: Fraction): Fraction {\n return f1.cmp(f2) > 0 ? f1 : f2;\n }\n\n static min(f1: Fraction, f2: Fraction): Fraction {\n return f1.cmp(f2) < 0 ? f1 : f2;\n }\n}\n\n// Shortcut helper\nexport const Frac = (a = 0, b = 1, factorized = false): Fraction => new Fraction(a, b, factorized);\n"]}
|