Skip to content

Instantly share code, notes, and snippets.

@blrobin2
Created December 7, 2018 13:44
Show Gist options
  • Save blrobin2/70bb9d345be98dfde5dede7f5d78dca3 to your computer and use it in GitHub Desktop.
Save blrobin2/70bb9d345be98dfde5dede7f5d78dca3 to your computer and use it in GitHub Desktop.
Ord-based Bubble sort with TYPES
interface Setoid<T> {
equals(that: T): Boolean;
}
interface Ord<T> extends Setoid<T> {
lte(that: T): Boolean;
}
class Coord implements Ord<Coord> {
constructor(private x: Number, private y: Number, private z: Number) {}
static from({ x, y, z }: { x: Number, y: Number, z: Number}): Coord {
return new Coord(x, y, z);
}
toObject(): Record<'x'|'y'|'z', Number> {
return { x: this.x, y: this.y, z: this.z };
}
equals(that: Coord): Boolean {
return this.x === that.x
&& this.y === that.y
&& this.z === that.z;
}
lte(that: Coord): Boolean {
return (this.x < that.x)
|| (this.x == that.x && this.y < that.y)
|| (this.x == that.x && this.y == that.y && this.z < that.z)
|| (this.equals(that));
}
}
function coord(x: Number, y: Number, z:Number): Coord {
return new Coord(x, y, z);
}
class Line implements Ord<Line> {
constructor(private from: Coord, private to: Coord) {}
static from({
from,
to
}: {
from: Record<"x" | "y" | "z", Number>;
to: Record<"x" | "y" | "z", Number>;
}): Line {
return new Line(Coord.from(from), Coord.from(to));
}
toObject(): {
from: Record<"x" | "y" | "z", Number>;
to: Record<"x" | "y" | "z", Number>;
} {
return {
from: this.from.toObject(),
to: this.to.toObject()
};
}
equals(that: Line): Boolean {
return this.from.equals(that.from) && this.to.equals(that.to);
}
lte(that: Line): Boolean {
return (
lt(this.from, that.from) ||
(this.from.equals(that.from) && lt(this.to, that.to)) ||
this.equals(that)
);
}
}
function line(from: Coord, to: Coord): Line {
return new Line(from, to);
}
function lte<T extends Ord<T>>(x: T, y: T): Boolean {
return x.lte(y);
}
// gt :: Ord a => a -> a -> Boolean
function gt<T extends Ord<T>>(x: T, y: T): Boolean {
return !lte(x, y);
}
// gte :: Ord a => a -> a -> Boolean
function gte<T extends Ord<T>>(x: T, y: T): Boolean {
return gt(x, y) || x.equals(y);
}
// lt :: Ord a => a -> a -> Boolean
function lt<T extends Ord<T>>(x: T, y: T): Boolean {
return !gte(x, y);
}
function bubbleSort<T extends Ord<T>>(xs_: T[]): T[] {
const xs = [...xs_];
let n = xs.length - 1;
let swapped = true;
while (swapped) {
swapped = false;
for (let i = 1; i <= n; i++) {
const curr = xs[i];
const prev = xs[i - 1];
if (gt(prev, curr)) {
xs[i - 1] = curr;
xs[i] = prev;
swapped = true;
}
}
}
return xs;
}
const coord_list: Coord[] = [coord(1, 2, 3), coord(1, 2, 1), coord(1, 1, 2)];
const org = coord(0, 0, 0);
const line_list = [
line(
org,
coord(1, 2, 3)
),
line(
coord(1, 2, 1),
coord(1, 2, 2),
),
line(
org,
coord(1, 1, 2)
)
];
console.log(
//bubbleSort(coord_list)
bubbleSort(line_list).map(l => l.toObject())
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment