Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
M
Molstar
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Michal Malý
Molstar
Commits
fbd7c35f
Commit
fbd7c35f
authored
Oct 24, 2017
by
David Sehnal
Browse files
Options
Downloads
Patches
Plain Diff
collections refactoring
parent
2f78edea
No related branches found
No related tags found
No related merge requests found
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/structure/collections/multi-set.ts
+164
-139
164 additions, 139 deletions
src/structure/collections/multi-set.ts
src/structure/collections/ordered-set.ts
+8
-10
8 additions, 10 deletions
src/structure/collections/ordered-set.ts
with
172 additions
and
149 deletions
src/structure/collections/multi-set.ts
+
164
−
139
View file @
fbd7c35f
...
@@ -11,46 +11,76 @@ import { sortArray } from './sort'
...
@@ -11,46 +11,76 @@ import { sortArray } from './sort'
import
{
hash1
}
from
'
./hash-functions
'
import
{
hash1
}
from
'
./hash-functions
'
/** A map-like representation of integer set */
/** A map-like representation of integer set */
interface
MultiSet
{
/*
'@type': 'int-multi-set'
*/
}
interface
MultiSet
{
'
@type
'
:
'
int-multi-set
'
}
namespace
MultiSet
{
namespace
MultiSet
{
export
const
Empty
:
MultiSet
=
{
offsets
:
[
0
],
hashCode
:
0
,
keys
:
OrderedSet
.
Empty
}
as
MultiSetElements
as
any
;
export
const
Empty
:
MultiSet
=
{
offsets
:
[
0
],
hashCode
:
0
,
keys
:
OrderedSet
.
Empty
}
as
MultiSetElements
as
any
;
export
function
create
(
data
:
IntTuple
|
ArrayLike
<
IntTuple
>
|
IntTuple
|
{
[
id
:
number
]:
OrderedSet
}):
MultiSet
{
export
function
create
(
data
:
IntTuple
|
ArrayLike
<
IntTuple
>
|
IntTuple
|
{
[
id
:
number
]:
OrderedSet
}):
MultiSet
{
if
(
typeof
data
===
'
number
'
)
return
data
;
if
(
typeof
data
===
'
number
'
)
return
data
;
if
(
IntTuple
.
is
(
data
))
return
IntTuple
.
pack1
(
data
)
as
number
;
if
(
IntTuple
.
is
(
data
))
return
IntTuple
.
pack1
(
data
)
as
any
;
if
(
isArrayLike
(
data
))
return
ofTuples
(
data
);
if
(
isArrayLike
(
data
))
return
ofTuples
(
data
)
as
any
;
return
ofObject
(
data
as
{
[
id
:
number
]:
OrderedSet
});
return
ofObject
(
data
as
{
[
id
:
number
]:
OrderedSet
})
as
any
;
}
}
export
function
keys
(
set
:
MultiSet
):
OrderedSet
{
export
const
keys
:
(
set
:
MultiSet
)
=>
OrderedSet
=
keysI
as
any
;
export
const
keyCount
:
(
set
:
MultiSet
)
=>
number
=
keyCountI
as
any
;
export
const
hasKey
:
(
set
:
MultiSet
,
key
:
number
)
=>
boolean
=
hasKeyI
as
any
;
export
const
geyKey
:
(
set
:
MultiSet
,
i
:
number
)
=>
number
=
getKeyI
as
any
;
export
const
getByKey
:
(
set
:
MultiSet
,
key
:
number
)
=>
OrderedSet
=
getByKeyI
as
any
;
export
const
getByIndex
:
(
set
:
MultiSet
,
i
:
number
)
=>
OrderedSet
=
getByIndexI
as
any
;
export
const
has
:
(
set
:
MultiSet
,
x
:
IntTuple
)
=>
boolean
=
hasI
as
any
;
export
const
indexOf
:
(
set
:
MultiSet
,
x
:
IntTuple
)
=>
number
=
indexOfI
as
any
;
export
const
getAt
:
(
set
:
MultiSet
,
i
:
number
)
=>
IntTuple
=
getAtI
as
any
;
export
const
values
:
(
set
:
MultiSet
)
=>
Iterator
<
IntTuple
.
Unpacked
>
=
valuesI
as
any
;
export
const
size
:
(
set
:
MultiSet
)
=>
number
=
sizeI
as
any
;
export
const
hashCode
:
(
set
:
MultiSet
)
=>
number
=
hashCodeI
as
any
;
export
const
areEqual
:
(
a
:
MultiSet
,
b
:
MultiSet
)
=>
boolean
=
areEqualI
as
any
;
export
const
areIntersecting
:
(
a
:
MultiSet
,
b
:
MultiSet
)
=>
boolean
=
areIntersectingI
as
any
;
export
const
union
:
(
a
:
MultiSet
,
b
:
MultiSet
)
=>
MultiSet
=
unionI
as
any
;
export
const
unionMany
:
(
sets
:
MultiSet
[])
=>
MultiSet
=
unionManyI
as
any
;
export
const
intersect
:
(
a
:
MultiSet
,
b
:
MultiSet
)
=>
MultiSet
=
intersectI
as
any
;
export
const
subtract
:
(
a
:
MultiSet
,
b
:
MultiSet
)
=>
MultiSet
=
subtractI
as
any
;
}
export
default
MultiSet
/** Long and painful implementation starts here */
interface
MultiSetElements
{
[
id
:
number
]:
OrderedSet
,
offsets
:
number
[],
hashCode
:
number
,
keys
:
OrderedSet
}
type
MultiSetImpl
=
IntTuple
|
MultiSetElements
function
keysI
(
set
:
MultiSetImpl
):
OrderedSet
{
if
(
typeof
set
===
'
number
'
)
return
OrderedSet
.
ofSingleton
(
set
);
if
(
typeof
set
===
'
number
'
)
return
OrderedSet
.
ofSingleton
(
set
);
return
(
set
as
MultiSetElements
).
keys
;
return
(
set
as
MultiSetElements
).
keys
;
}
}
export
function
keyCount
(
set
:
MultiSet
):
number
{
function
keyCount
I
(
set
:
MultiSet
Impl
):
number
{
if
(
typeof
set
===
'
number
'
)
return
1
;
if
(
typeof
set
===
'
number
'
)
return
1
;
return
OrderedSet
.
size
((
set
as
MultiSetElements
).
keys
);
return
OrderedSet
.
size
((
set
as
MultiSetElements
).
keys
);
}
}
export
function
hasKey
(
set
:
MultiSet
,
key
:
number
):
boolean
{
function
hasKey
I
(
set
:
MultiSet
Impl
,
key
:
number
):
boolean
{
if
(
typeof
set
===
'
number
'
)
return
IntTuple
.
fst
(
set
)
===
key
;
if
(
typeof
set
===
'
number
'
)
return
IntTuple
.
fst
(
set
)
===
key
;
return
OrderedSet
.
has
((
set
as
MultiSetElements
).
keys
,
key
);
return
OrderedSet
.
has
((
set
as
MultiSetElements
).
keys
,
key
);
}
}
export
function
getKey
(
set
:
MultiSet
,
index
:
number
):
number
{
function
getKey
I
(
set
:
MultiSet
Impl
,
index
:
number
):
number
{
if
(
typeof
set
===
'
number
'
)
return
IntTuple
.
fst
(
set
);
if
(
typeof
set
===
'
number
'
)
return
IntTuple
.
fst
(
set
);
return
OrderedSet
.
getAt
((
set
as
MultiSetElements
).
keys
,
index
);
return
OrderedSet
.
getAt
((
set
as
MultiSetElements
).
keys
,
index
);
}
}
export
function
has
(
set
:
MultiSet
,
t
:
IntTuple
):
boolean
{
function
has
I
(
set
:
MultiSet
Impl
,
t
:
IntTuple
):
boolean
{
if
(
typeof
set
===
'
number
'
)
return
IntTuple
.
areEqual
(
t
,
set
);
if
(
typeof
set
===
'
number
'
)
return
IntTuple
.
areEqual
(
t
,
set
);
IntTuple
.
unpack
(
t
,
_hasP
);
IntTuple
.
unpack
(
t
,
_hasP
);
return
OrderedSet
.
has
((
set
as
MultiSetElements
).
keys
,
_hasP
.
fst
)
?
OrderedSet
.
has
((
set
as
MultiSetElements
)[
_hasP
.
fst
],
_hasP
.
snd
)
:
false
;
return
OrderedSet
.
has
((
set
as
MultiSetElements
).
keys
,
_hasP
.
fst
)
?
OrderedSet
.
has
((
set
as
MultiSetElements
)[
_hasP
.
fst
],
_hasP
.
snd
)
:
false
;
}
}
const
_hasP
=
IntTuple
.
zero
();
const
_hasP
=
IntTuple
.
zero
();
export
function
getByKey
(
set
:
MultiSet
,
key
:
number
):
OrderedSet
{
function
getByKey
I
(
set
:
MultiSet
Impl
,
key
:
number
):
OrderedSet
{
if
(
typeof
set
===
'
number
'
)
{
if
(
typeof
set
===
'
number
'
)
{
IntTuple
.
unpack
(
set
,
_gS
);
IntTuple
.
unpack
(
set
,
_gS
);
return
_gS
.
fst
===
key
?
OrderedSet
.
ofSingleton
(
_gS
.
snd
)
:
OrderedSet
.
Empty
;
return
_gS
.
fst
===
key
?
OrderedSet
.
ofSingleton
(
_gS
.
snd
)
:
OrderedSet
.
Empty
;
...
@@ -59,35 +89,35 @@ namespace MultiSet {
...
@@ -59,35 +89,35 @@ namespace MultiSet {
}
}
const
_gS
=
IntTuple
.
zero
();
const
_gS
=
IntTuple
.
zero
();
export
function
getByIndex
(
set
:
MultiSet
,
index
:
number
):
OrderedSet
{
function
getByIndex
I
(
set
:
MultiSet
Impl
,
index
:
number
):
OrderedSet
{
if
(
typeof
set
===
'
number
'
)
return
index
===
0
?
OrderedSet
.
ofSingleton
(
IntTuple
.
snd
(
set
))
:
OrderedSet
.
Empty
;
if
(
typeof
set
===
'
number
'
)
return
index
===
0
?
OrderedSet
.
ofSingleton
(
IntTuple
.
snd
(
set
))
:
OrderedSet
.
Empty
;
const
key
=
OrderedSet
.
getAt
((
set
as
MultiSetElements
).
keys
,
index
);
const
key
=
OrderedSet
.
getAt
((
set
as
MultiSetElements
).
keys
,
index
);
return
(
set
as
MultiSetElements
)[
key
]
||
OrderedSet
.
Empty
;
return
(
set
as
MultiSetElements
)[
key
]
||
OrderedSet
.
Empty
;
}
}
export
function
getAt
(
set
:
MultiSet
,
i
:
number
):
IntTuple
{
function
getAt
I
(
set
:
MultiSet
Impl
,
i
:
number
):
IntTuple
{
if
(
typeof
set
===
'
number
'
)
return
set
;
if
(
typeof
set
===
'
number
'
)
return
set
;
return
getAtE
(
set
as
MultiSetElements
,
i
);
return
getAtE
(
set
as
MultiSetElements
,
i
);
}
}
export
function
indexOf
(
set
:
MultiSet
,
t
:
IntTuple
)
{
function
indexOf
I
(
set
:
MultiSet
Impl
,
t
:
IntTuple
)
{
if
(
typeof
set
===
'
number
'
)
return
IntTuple
.
areEqual
(
set
,
t
)
?
0
:
-
1
;
if
(
typeof
set
===
'
number
'
)
return
IntTuple
.
areEqual
(
set
,
t
)
?
0
:
-
1
;
return
indexOfE
(
set
as
MultiSetElements
,
t
);
return
indexOfE
(
set
as
MultiSetElements
,
t
);
}
}
/** Number elements in the "child" sets */
/** Number elements in the "child" sets */
export
function
size
(
set
:
MultiSet
)
{
function
size
I
(
set
:
MultiSet
Impl
)
{
if
(
typeof
set
===
'
number
'
)
return
1
;
if
(
typeof
set
===
'
number
'
)
return
1
;
return
(
set
as
MultiSetElements
).
offsets
[(
set
as
MultiSetElements
).
offsets
.
length
-
1
];
return
(
set
as
MultiSetElements
).
offsets
[(
set
as
MultiSetElements
).
offsets
.
length
-
1
];
}
}
export
function
hashCode
(
set
:
MultiSet
)
{
function
hashCode
I
(
set
:
MultiSet
Impl
)
{
if
(
typeof
set
===
'
number
'
)
return
IntTuple
.
hashCode
(
set
);
if
(
typeof
set
===
'
number
'
)
return
IntTuple
.
hashCode
(
set
);
if
((
set
as
MultiSetElements
).
hashCode
!==
-
1
)
return
(
set
as
MultiSetElements
).
hashCode
;
if
((
set
as
MultiSetElements
).
hashCode
!==
-
1
)
return
(
set
as
MultiSetElements
).
hashCode
;
return
computeHash
((
set
as
MultiSetElements
));
return
computeHash
((
set
as
MultiSetElements
));
}
}
export
function
areEqual
(
a
:
MultiSet
,
b
:
MultiSet
):
boolean
{
function
areEqual
I
(
a
:
MultiSet
Impl
,
b
:
MultiSet
Impl
)
{
if
(
typeof
a
===
'
number
'
)
{
if
(
typeof
a
===
'
number
'
)
{
if
(
typeof
b
===
'
number
'
)
return
IntTuple
.
areEqual
(
a
,
b
);
if
(
typeof
b
===
'
number
'
)
return
IntTuple
.
areEqual
(
a
,
b
);
return
false
;
return
false
;
...
@@ -96,7 +126,7 @@ namespace MultiSet {
...
@@ -96,7 +126,7 @@ namespace MultiSet {
return
areEqualEE
(
a
as
MultiSetElements
,
b
as
MultiSetElements
);
return
areEqualEE
(
a
as
MultiSetElements
,
b
as
MultiSetElements
);
}
}
export
function
areIntersecting
(
a
:
MultiSet
,
b
:
MultiSet
):
boolean
{
function
areIntersecting
I
(
a
:
MultiSet
Impl
,
b
:
MultiSet
Impl
)
{
if
(
typeof
a
===
'
number
'
)
{
if
(
typeof
a
===
'
number
'
)
{
if
(
typeof
b
===
'
number
'
)
return
IntTuple
.
areEqual
(
a
,
b
);
if
(
typeof
b
===
'
number
'
)
return
IntTuple
.
areEqual
(
a
,
b
);
return
areIntersectingNE
(
a
,
b
as
MultiSetElements
);
return
areIntersectingNE
(
a
,
b
as
MultiSetElements
);
...
@@ -105,29 +135,29 @@ namespace MultiSet {
...
@@ -105,29 +135,29 @@ namespace MultiSet {
return
areIntersectingEE
(
a
as
MultiSetElements
,
b
as
MultiSetElements
);
return
areIntersectingEE
(
a
as
MultiSetElements
,
b
as
MultiSetElements
);
}
}
export
function
intersect
(
a
:
MultiSet
,
b
:
MultiSet
):
MultiSet
{
function
intersect
I
(
a
:
MultiSet
Impl
,
b
:
MultiSet
Impl
)
{
if
(
typeof
a
===
'
number
'
)
{
if
(
typeof
a
===
'
number
'
)
{
if
(
typeof
b
===
'
number
'
)
return
IntTuple
.
areEqual
(
a
,
b
)
?
a
:
Empty
;
if
(
typeof
b
===
'
number
'
)
return
IntTuple
.
areEqual
(
a
,
b
)
?
a
:
MultiSet
.
Empty
;
return
intersectNE
(
a
,
b
as
MultiSetElements
);
return
intersectNE
(
a
,
b
as
MultiSetElements
);
}
}
if
(
typeof
b
===
'
number
'
)
return
intersectNE
(
b
,
a
as
MultiSetElements
);
if
(
typeof
b
===
'
number
'
)
return
intersectNE
(
b
,
a
as
MultiSetElements
);
return
intersectEE
(
a
as
MultiSetElements
,
b
as
MultiSetElements
);
return
intersectEE
(
a
as
MultiSetElements
,
b
as
MultiSetElements
);
}
}
export
function
subtract
(
a
:
MultiSet
,
b
:
MultiSet
):
MultiSet
{
function
subtract
I
(
a
:
MultiSet
Impl
,
b
:
MultiSet
Impl
)
{
if
(
typeof
a
===
'
number
'
)
{
if
(
typeof
a
===
'
number
'
)
{
if
(
typeof
b
===
'
number
'
)
return
IntTuple
.
areEqual
(
a
,
b
)
?
Empty
:
a
;
if
(
typeof
b
===
'
number
'
)
return
IntTuple
.
areEqual
(
a
,
b
)
?
MultiSet
.
Empty
:
a
;
return
subtractNE
(
a
,
b
as
MultiSetElements
);
return
subtractNE
(
a
,
b
as
MultiSetElements
);
}
}
if
(
typeof
b
===
'
number
'
)
return
subtractEN
(
a
as
MultiSetElements
,
b
);
if
(
typeof
b
===
'
number
'
)
return
subtractEN
(
a
as
MultiSetElements
,
b
);
return
subtractEE
(
a
as
MultiSetElements
,
b
as
MultiSetElements
);
return
subtractEE
(
a
as
MultiSetElements
,
b
as
MultiSetElements
);
}
}
export
function
union
(
a
:
MultiSet
,
b
:
MultiSet
):
MultiSet
{
function
union
I
(
a
:
MultiSet
Impl
,
b
:
MultiSet
Impl
)
{
return
findUnion
([
a
,
b
]);
return
findUnion
([
a
,
b
]);
}
}
export
function
unionMany
(
sets
:
ArrayLike
<
MultiSet
>
):
MultiSet
{
function
unionMany
I
(
sets
:
ArrayLike
<
MultiSet
Impl
>
)
{
return
findUnion
(
sets
);
return
findUnion
(
sets
);
}
}
...
@@ -175,13 +205,10 @@ namespace MultiSet {
...
@@ -175,13 +205,10 @@ namespace MultiSet {
}
}
}
}
export
function
values
(
set
:
MultiSet
):
Iterator
<
IntTuple
.
Unpacked
>
{
function
values
I
(
set
:
MultiSet
Impl
):
Iterator
<
IntTuple
.
Unpacked
>
{
if
(
typeof
set
===
'
number
'
)
return
Iterator
.
Value
(
IntTuple
.
unpack1
(
set
));
if
(
typeof
set
===
'
number
'
)
return
Iterator
.
Value
(
IntTuple
.
unpack1
(
set
));
return
new
ElementsIterator
(
set
as
MultiSetElements
);
return
new
ElementsIterator
(
set
as
MultiSetElements
);
}
}
}
interface
MultiSetElements
{
[
id
:
number
]:
OrderedSet
,
offsets
:
number
[],
hashCode
:
number
,
keys
:
OrderedSet
}
function
isArrayLike
(
x
:
any
):
x
is
ArrayLike
<
number
>
{
function
isArrayLike
(
x
:
any
):
x
is
ArrayLike
<
number
>
{
return
x
&&
(
typeof
x
.
length
===
'
number
'
&&
(
x
instanceof
Array
||
!!
x
.
buffer
));
return
x
&&
(
typeof
x
.
length
===
'
number
'
&&
(
x
instanceof
Array
||
!!
x
.
buffer
));
...
@@ -259,7 +286,7 @@ function normalizeArray(xs: number[]) {
...
@@ -259,7 +286,7 @@ function normalizeArray(xs: number[]) {
return
xs
;
return
xs
;
}
}
function
ofTuples
(
xs
:
ArrayLike
<
IntTuple
>
)
:
MultiSet
{
function
ofTuples
(
xs
:
ArrayLike
<
IntTuple
>
)
{
if
(
xs
.
length
===
0
)
return
MultiSet
.
Empty
;
if
(
xs
.
length
===
0
)
return
MultiSet
.
Empty
;
const
sets
:
{
[
key
:
number
]:
number
[]
}
=
Object
.
create
(
null
);
const
sets
:
{
[
key
:
number
]:
number
[]
}
=
Object
.
create
(
null
);
const
p
=
IntTuple
.
zero
();
const
p
=
IntTuple
.
zero
();
...
@@ -322,7 +349,7 @@ function computeHash(set: MultiSetElements) {
...
@@ -322,7 +349,7 @@ function computeHash(set: MultiSetElements) {
hash
=
(
31
*
hash
+
k
)
|
0
;
hash
=
(
31
*
hash
+
k
)
|
0
;
hash
=
(
31
*
hash
+
OrderedSet
.
hashCode
(
set
[
k
]))
|
0
;
hash
=
(
31
*
hash
+
OrderedSet
.
hashCode
(
set
[
k
]))
|
0
;
}
}
hash
=
(
31
*
hash
+
MultiSet
.
size
(
set
))
|
0
;
hash
=
(
31
*
hash
+
size
I
(
set
))
|
0
;
hash
=
hash1
(
hash
);
hash
=
hash1
(
hash
);
set
.
hashCode
=
hash
;
set
.
hashCode
=
hash
;
return
hash
;
return
hash
;
...
@@ -330,7 +357,7 @@ function computeHash(set: MultiSetElements) {
...
@@ -330,7 +357,7 @@ function computeHash(set: MultiSetElements) {
function
areEqualEE
(
a
:
MultiSetElements
,
b
:
MultiSetElements
)
{
function
areEqualEE
(
a
:
MultiSetElements
,
b
:
MultiSetElements
)
{
if
(
a
===
b
)
return
true
;
if
(
a
===
b
)
return
true
;
if
(
MultiSet
.
size
(
a
)
!==
MultiSet
.
size
(
a
))
return
false
;
if
(
size
I
(
a
)
!==
size
I
(
a
))
return
false
;
const
keys
=
a
.
keys
;
const
keys
=
a
.
keys
;
if
(
!
OrderedSet
.
areEqual
(
keys
,
b
.
keys
))
return
false
;
if
(
!
OrderedSet
.
areEqual
(
keys
,
b
.
keys
))
return
false
;
...
@@ -393,7 +420,7 @@ function subtractNE(a: IntTuple, b: MultiSetElements) {
...
@@ -393,7 +420,7 @@ function subtractNE(a: IntTuple, b: MultiSetElements) {
}
}
const
_sEN
=
IntTuple
.
zero
();
const
_sEN
=
IntTuple
.
zero
();
function
subtractEN
(
a
:
MultiSetElements
,
b
:
IntTuple
):
MultiSet
{
function
subtractEN
(
a
:
MultiSetElements
,
b
:
IntTuple
):
MultiSet
Impl
{
const
aKeys
=
a
.
keys
;
const
aKeys
=
a
.
keys
;
IntTuple
.
unpack
(
b
,
_sEN
);
IntTuple
.
unpack
(
b
,
_sEN
);
if
(
!
OrderedSet
.
has
(
aKeys
,
_sEN
.
fst
)
||
!
OrderedSet
.
has
(
a
[
_sEN
.
fst
],
_sEN
.
snd
))
return
a
;
if
(
!
OrderedSet
.
has
(
aKeys
,
_sEN
.
fst
)
||
!
OrderedSet
.
has
(
a
[
_sEN
.
fst
],
_sEN
.
snd
))
return
a
;
...
@@ -439,10 +466,10 @@ function subtractEE(a: MultiSetElements, b: MultiSetElements) {
...
@@ -439,10 +466,10 @@ function subtractEE(a: MultiSetElements, b: MultiSetElements) {
return
ofObjectOrdered
(
OrderedSet
.
ofSortedArray
(
keys
),
ret
);
return
ofObjectOrdered
(
OrderedSet
.
ofSortedArray
(
keys
),
ret
);
}
}
function
findUnion
(
sets
:
ArrayLike
<
MultiSet
>
)
{
function
findUnion
(
sets
:
ArrayLike
<
MultiSet
Impl
>
)
{
if
(
!
sets
.
length
)
return
MultiSet
.
Empty
;
if
(
!
sets
.
length
)
return
MultiSet
.
Empty
;
if
(
sets
.
length
===
1
)
return
sets
[
0
];
if
(
sets
.
length
===
1
)
return
sets
[
0
];
if
(
sets
.
length
===
2
&&
MultiSet
.
areEqual
(
sets
[
0
],
sets
[
1
]))
return
sets
[
0
];
if
(
sets
.
length
===
2
&&
areEqual
I
(
sets
[
0
],
sets
[
1
]))
return
sets
[
0
];
const
eCount
=
{
count
:
0
};
const
eCount
=
{
count
:
0
};
const
ns
=
unionN
(
sets
,
eCount
);
const
ns
=
unionN
(
sets
,
eCount
);
...
@@ -452,14 +479,14 @@ function findUnion(sets: ArrayLike<MultiSet>) {
...
@@ -452,14 +479,14 @@ function findUnion(sets: ArrayLike<MultiSet>) {
const
s
=
sets
[
i
];
const
s
=
sets
[
i
];
if
(
typeof
s
!==
'
number
'
)
unionInto
(
ret
,
s
as
MultiSetElements
);
if
(
typeof
s
!==
'
number
'
)
unionInto
(
ret
,
s
as
MultiSetElements
);
}
}
if
(
MultiSet
.
size
(
ns
)
>
0
)
{
if
(
sizeI
(
ns
as
MultiSetImpl
)
>
0
)
{
if
(
typeof
ns
===
'
number
'
)
unionIntoN
(
ret
,
ns
);
if
(
typeof
ns
===
'
number
'
)
unionIntoN
(
ret
,
ns
);
else
unionInto
(
ret
,
ns
as
MultiSetElements
);
else
unionInto
(
ret
,
ns
as
MultiSetElements
);
}
}
return
ofObject
(
ret
);
return
ofObject
(
ret
);
}
}
function
unionN
(
sets
:
ArrayLike
<
MultiSet
>
,
eCount
:
{
count
:
number
})
{
function
unionN
(
sets
:
ArrayLike
<
MultiSet
Impl
>
,
eCount
:
{
count
:
number
})
{
let
countN
=
0
,
countE
=
0
;
let
countN
=
0
,
countE
=
0
;
for
(
let
i
=
0
,
_i
=
sets
.
length
;
i
<
_i
;
i
++
)
{
for
(
let
i
=
0
,
_i
=
sets
.
length
;
i
<
_i
;
i
++
)
{
if
(
typeof
sets
[
i
]
===
'
number
'
)
countN
++
;
if
(
typeof
sets
[
i
]
===
'
number
'
)
countN
++
;
...
@@ -497,5 +524,3 @@ function unionIntoN(data: { [key: number]: OrderedSet }, a: IntTuple) {
...
@@ -497,5 +524,3 @@ function unionIntoN(data: { [key: number]: OrderedSet }, a: IntTuple) {
data
[
_uIN
.
fst
]
=
OrderedSet
.
ofSingleton
(
_uIN
.
snd
);
data
[
_uIN
.
fst
]
=
OrderedSet
.
ofSingleton
(
_uIN
.
snd
);
}
}
}
}
\ No newline at end of file
export
default
MultiSet
\ No newline at end of file
This diff is collapsed.
Click to expand it.
src/structure/collections/ordered-set.ts
+
8
−
10
View file @
fbd7c35f
...
@@ -22,21 +22,22 @@ namespace OrderedSet {
...
@@ -22,21 +22,22 @@ namespace OrderedSet {
return
xs
as
any
;
return
xs
as
any
;
}
}
export
const
size
:
(
set
:
OrderedSet
)
=>
number
=
sizeI
as
any
;
export
const
has
:
(
set
:
OrderedSet
,
x
:
number
)
=>
boolean
=
hasI
as
any
;
export
const
has
:
(
set
:
OrderedSet
,
x
:
number
)
=>
boolean
=
hasI
as
any
;
export
const
indexOf
:
(
set
:
OrderedSet
,
x
:
number
)
=>
number
=
indexOfI
as
any
;
export
const
indexOf
:
(
set
:
OrderedSet
,
x
:
number
)
=>
number
=
indexOfI
as
any
;
export
const
getAt
:
(
set
:
OrderedSet
,
i
:
number
)
=>
number
=
getAtI
as
any
;
export
const
getAt
:
(
set
:
OrderedSet
,
i
:
number
)
=>
number
=
getAtI
as
any
;
export
const
min
:
(
set
:
OrderedSet
)
=>
number
=
minI
as
any
;
export
const
min
:
(
set
:
OrderedSet
)
=>
number
=
minI
as
any
;
export
const
max
:
(
set
:
OrderedSet
)
=>
number
=
maxI
as
any
;
export
const
max
:
(
set
:
OrderedSet
)
=>
number
=
maxI
as
any
;
export
const
size
:
(
set
:
OrderedSet
)
=>
number
=
sizeI
as
any
;
export
const
hashCode
:
(
set
:
OrderedSet
)
=>
number
=
hashCodeI
as
any
;
export
const
hashCode
:
(
set
:
OrderedSet
)
=>
number
=
hashCodeI
as
any
;
export
const
areEqual
:
BinaryTest
=
areEqualI
as
any
;
export
const
areEqual
:
(
a
:
OrderedSet
,
b
:
OrderedSet
)
=>
boolean
=
areEqualI
as
any
;
export
const
areIntersecting
:
BinaryTest
=
areIntersectingI
as
any
;
export
const
areIntersecting
:
(
a
:
OrderedSet
,
b
:
OrderedSet
)
=>
boolean
=
areIntersectingI
as
any
;
export
const
isSubset
:
BinaryTest
=
isSubsetI
as
any
;
export
const
isSubset
:
(
a
:
OrderedSet
,
b
:
OrderedSet
)
=>
boolean
=
isSubsetI
as
any
;
export
const
union
:
BinaryOp
=
unionI
as
any
;
export
const
union
:
(
a
:
OrderedSet
,
b
:
OrderedSet
)
=>
OrderedSet
=
unionI
as
any
;
export
const
intersect
:
BinaryOp
=
intersectI
as
any
;
export
const
intersect
:
(
a
:
OrderedSet
,
b
:
OrderedSet
)
=>
OrderedSet
=
intersectI
as
any
;
export
const
subtract
:
BinaryOp
=
subtractI
as
any
;
export
const
subtract
:
(
a
:
OrderedSet
,
b
:
OrderedSet
)
=>
OrderedSet
=
subtractI
as
any
;
export
const
getInsertionIndex
:
(
set
:
OrderedSet
,
x
:
number
)
=>
number
=
getInsertionIndexI
as
any
;
export
const
getInsertionIndex
:
(
set
:
OrderedSet
,
x
:
number
)
=>
number
=
getInsertionIndexI
as
any
;
export
const
getIntervalRange
:
(
set
:
OrderedSet
,
min
:
number
,
max
:
number
)
=>
{
start
:
number
,
end
:
number
}
=
getIntervalRangeI
as
any
;
export
const
getIntervalRange
:
(
set
:
OrderedSet
,
min
:
number
,
max
:
number
)
=>
{
start
:
number
,
end
:
number
}
=
getIntervalRangeI
as
any
;
...
@@ -46,9 +47,6 @@ export default OrderedSet
...
@@ -46,9 +47,6 @@ export default OrderedSet
/** Long and painful implementation starts here */
/** Long and painful implementation starts here */
type
BinaryTest
=
(
a
:
OrderedSet
,
b
:
OrderedSet
)
=>
boolean
type
BinaryOp
=
(
a
:
OrderedSet
,
b
:
OrderedSet
)
=>
OrderedSet
type
Range
=
IntTuple
type
Range
=
IntTuple
type
SortedArray
=
ArrayLike
<
number
>
type
SortedArray
=
ArrayLike
<
number
>
type
OrderedSetImpl
=
Range
|
SortedArray
type
OrderedSetImpl
=
Range
|
SortedArray
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment