Skip to content
Snippets Groups Projects
Commit 2f78edea authored by David Sehnal's avatar David Sehnal
Browse files

collections

parent 4e2fe6b2
No related branches found
No related tags found
No related merge requests found
import * as B from 'benchmark'
import IntPair from '../structure/collections/int-pair'
import IntTuple from '../structure/collections/int-tuple'
import OrdSet from '../structure/collections/ordered-set'
import MSet from '../structure/collections/multi-set'
......@@ -33,7 +33,7 @@ namespace Iteration {
export function elementAt() {
let s = 0;
for (let i = 0, _i = MSet.size(ms); i < _i; i++) s += IntPair.snd(MSet.get(ms, i));
for (let i = 0, _i = MSet.size(ms); i < _i; i++) s += IntTuple.snd(MSet.getAt(ms, i));
return s;
}
......@@ -41,9 +41,9 @@ namespace Iteration {
let s = 0;
const keys = MSet.keys(ms);
for (let i = 0, _i = OrdSet.size(keys); i < _i; i++) {
const set = MSet.getSetByKey(ms, OrdSet.get(keys, i));
const set = MSet.getByKey(ms, OrdSet.getAt(keys, i));
for (let j = 0, _j = OrdSet.size(set); j < _j; j++) {
s += OrdSet.get(set, j);
s += OrdSet.getAt(set, j);
}
}
return s;
......@@ -51,10 +51,10 @@ namespace Iteration {
export function manual1() {
let s = 0;
for (let i = 0, _i = MSet.getSetCount(ms); i < _i; i++) {
const set = MSet.getSetByIndex(ms, i);
for (let i = 0, _i = MSet.keyCount(ms); i < _i; i++) {
const set = MSet.getByIndex(ms, i);
for (let j = 0, _j = OrdSet.size(set); j < _j; j++) {
s += OrdSet.get(set, j);
s += OrdSet.getAt(set, j);
}
}
return s;
......@@ -75,4 +75,4 @@ suite
.add('manual1', () => Iteration.manual1())
.add('el at', () => Iteration.elementAt())
.on('cycle', (e: any) => console.log(String(e.target)))
.run();
.run();
\ No newline at end of file
......@@ -43,4 +43,12 @@ export function hash4(i: number, j: number, k: number, l: number) {
a = (a ^ 0xdeadbeef) + (a << 5);
a = a ^ (a >> 11);
return a;
}
/**
* A unique number for each pair of integers
* Biggest representable pair is (67108863, 67108863) (limit imposed by Number.MAX_SAFE_INTEGER)
*/
export function cantorPairing(a: number, b: number) {
return (a + b) * (a + b + 1) / 2 + b;
}
\ No newline at end of file
......@@ -6,10 +6,14 @@
import { hash2 } from './hash-functions'
interface IntPair { fst: number, snd: number }
/**
* Represents a pair of two integers as a double,
* Caution: === does not work, because of NaN, use IntTuple.areEqual for equality
*/
interface IntTuple extends Number { }
namespace IntPair {
export interface Packed extends Number { }
namespace IntTuple {
export interface Unpacked { fst: number, snd: number }
const { _int32, _float64, _int32_1, _float64_1 } = (function() {
const data = new ArrayBuffer(8);
......@@ -22,72 +26,73 @@ namespace IntPair {
};
}());
export function is(x: any): x is IntPair {
export function is(x: any): x is Unpacked {
return !!x && typeof x.fst === 'number' && typeof x.snd === 'number';
}
export function create(fst: number, snd: number) { return { fst, snd }; }
export function zero(): IntPair { return { fst: 0, snd: 0 }; }
export function zero(): Unpacked { return { fst: 0, snd: 0 }; }
export function pack1(fst: number, snd: number): number {
export function pack(fst: number, snd: number): IntTuple {
_int32[0] = fst;
_int32[1] = snd;
return _float64[0];
}
export function pack(p: IntPair): number {
_int32[0] = p.fst;
_int32[1] = p.snd;
export function pack1(t: Unpacked): IntTuple {
_int32[0] = t.fst;
_int32[1] = t.snd;
return _float64[0];
}
export function unpack(packed: Packed, target: IntPair): IntPair {
_float64[0] = packed as number;
export function unpack(t: IntTuple, target: Unpacked): Unpacked {
_float64[0] = t as number;
target.fst = _int32[0];
target.snd = _int32[1];
return target;
}
export function unpack1(packed: Packed): IntPair {
export function unpack1(packed: IntTuple): Unpacked {
return unpack(packed, zero());
}
export function fst(packed: Packed): number {
_float64[0] = packed as number;
export function fst(t: IntTuple): number {
_float64[0] = t as number;
return _int32[0];
}
export function snd(packed: Packed): number {
_float64[0] = packed as number;
export function snd(t: IntTuple): number {
_float64[0] = t as number;
return _int32[1];
}
export function areEqual(a: Packed, b: Packed) {
/** Normal equality does not work, because NaN === NaN ~> false */
export function areEqual(a: IntTuple, b: IntTuple) {
_float64[0] = a as number;
_float64_1[0] = b as number;
return _int32[0] === _int32_1[0] && _int32[1] === _int32_1[1];
}
export function compare(a: number, b: number) {
_float64[0] = a;
_float64_1[0] = b;
export function compare(a: IntTuple, b: IntTuple) {
_float64[0] = a as number;
_float64_1[0] = b as number;
const x = _int32[0] - _int32_1[0];
if (x !== 0) return x;
return _int32[1] - _int32_1[1];
}
export function compareInArray(xs: ArrayLike<number>, i: number, j: number) {
_float64[0] = xs[i];
_float64_1[0] = xs[j];
export function compareInArray(xs: ArrayLike<IntTuple>, i: number, j: number) {
_float64[0] = xs[i] as number;
_float64_1[0] = xs[j] as number;
const x = _int32[0] - _int32_1[0];
if (x !== 0) return x;
return _int32[1] - _int32_1[1];
}
export function packedHashCode(packed: Packed) {
_float64[0] = packed as number;
export function hashCode(t: IntTuple) {
_float64[0] = t as number;
return hash2(_int32[0], _int32[1]);
}
}
export default IntPair
\ No newline at end of file
export default IntTuple
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
......@@ -5,7 +5,7 @@
*/
import Iterator from '../collections/iterator'
import IntPair from '../collections/int-pair'
import IntTuple from '../collections/int-tuple'
import * as Sort from '../collections/sort'
import OrderedSet from '../collections/ordered-set'
import LinkedIndex from '../collections/linked-index'
......@@ -33,11 +33,11 @@ describe('basic iterators', () => {
describe('int pair', () => {
it('works', () => {
const p = IntPair.zero();
const p = IntTuple.zero();
for (let i = 0; i < 10; i++) {
for (let j = -10; j < 5; j++) {
const t = IntPair.pack1(i, j);
IntPair.unpack(t, p);
const t = IntTuple.pack(i, j);
IntTuple.unpack(t, p);
expect(p.fst).toBe(i);
expect(p.snd).toBe(j);
}
......@@ -131,7 +131,7 @@ describe('qsort-dual array', () => {
describe('ordered set', () => {
function ordSetToArray(set: OrderedSet) {
const ret = [];
for (let i = 0, _i = OrderedSet.size(set); i < _i; i++) ret.push(OrderedSet.get(set, i));
for (let i = 0, _i = OrderedSet.size(set); i < _i; i++) ret.push(OrderedSet.getAt(set, i));
return ret;
}
......@@ -317,13 +317,13 @@ describe('linked-index', () => {
});
describe('multiset', () => {
const p = (i: number, j: number) => IntPair.create(i, j);
const r = (i: number, j: number) => IntPair.pack1(i, j);
const p = (i: number, j: number) => IntTuple.create(i, j);
const r = (i: number, j: number) => IntTuple.pack(i, j);
function setToPairs(set: MultiSet): IntPair[] {
function setToPairs(set: MultiSet): ArrayLike<IntTuple.Unpacked> {
const ret = [];
const it = MultiSet.values(set);
for (let v = it.move(); !it.done; v = it.move()) ret[ret.length] = IntPair.create(v.fst, v.snd);
for (let v = it.move(); !it.done; v = it.move()) ret[ret.length] = IntTuple.create(v.fst, v.snd);
return ret;
}
......@@ -332,7 +332,8 @@ describe('multiset', () => {
expect(setToPairs(set)).toEqual([p(10, 11)]);
expect(MultiSet.has(set, r(10, 11))).toBe(true);
expect(MultiSet.has(set, r(11, 11))).toBe(false);
expect(MultiSet.get(set, 0)).toBe(r(10, 11));
expect(MultiSet.getAt(set, 0)).toBe(r(10, 11));
expect(MultiSet.size(set)).toBe(1);
});
it('singleton number', () => {
......@@ -352,12 +353,12 @@ describe('multiset', () => {
expect(MultiSet.has(set, r(3, 0))).toBe(true);
expect(MultiSet.has(set, r(1, 7))).toBe(true);
for (let i = 0; i < MultiSet.size(set); i++) {
expect(MultiSet.get(set, i)).toBe(IntPair.pack(ret[i]));
expect(MultiSet.getAt(set, i)).toBe(IntTuple.pack1(ret[i]));
}
});
it('element at', () => {
const control = [];
it('element at / index of', () => {
const control: IntTuple[] = [];
const sets = Object.create(null);
for (let i = 1; i < 10; i++) {
const set = [];
......@@ -369,7 +370,11 @@ describe('multiset', () => {
}
const ms = MultiSet.create(sets);
for (let i = 0; i < control.length; i++) {
expect(IntPair.areEqual(MultiSet.get(ms, i), control[i])).toBe(true);
expect(IntTuple.areEqual(MultiSet.getAt(ms, i), control[i])).toBe(true);
}
for (let i = 0; i < control.length; i++) {
expect(MultiSet.indexOf(ms, control[i])).toBe(i);
}
});
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment