UNPKG

joshkaposh-graph

Version:

A collection of general purpose graph data structures and traversal algorithms

119 lines (93 loc) 2.42 kB
import type { Option } from "joshkaposh-option"; export type GraphIx = 8 | 16 | 32; export type DefaultIx = 32; export type EdgeType = { is_directed(): boolean; } export type Directed = typeof Directed; export const Directed = { is_directed() { return true as const; }, } export type Undirected = typeof Undirected; export const Undirected = { is_directed() { return false as const }, } export class Direction { private constructor(public value: 0 | 1) { } static Incoming() { return new Direction(1) } static Outgoing() { return new Direction(0); } opposite() { return new Direction(this.value === 0 ? 1 : 0); } index() { return this.value & 0x1; } } export const Incoming = Direction.Incoming(); export const Outgoing = Direction.Outgoing(); export const DIRECTIONS = [Outgoing, Incoming] as const export interface Node<N> { weight: N; __next: [number, number]; } export interface Edge<E> { weight: E; node: [number, number]; __next: [number, number]; // next edge source(): number; target(): number; } export function createNode<N>(weight: N, next: [number, number]): Node<N> { return { weight, __next: next, } } export function createEdge<E>(weight: E, next: [number, number], node: [number, number]): Edge<E> { return { weight, node, __next: next, source(): number { return node[0] }, target(): number { return node[1] } } } export class Pair<T> { constructor(public value: T | [T, T]) { if (Array.isArray(value)) { this.type = 'Both' } else { this.type = 'One'; } } readonly type: 'One' | 'Both'; static One<T>(x: T) { return new Pair(x) } static Both<T>(a: T, b: T) { return new Pair([a, b] as const) } } export function index_twice<T>(slc: T[], a: number, b: number): Option<Pair<T>> { if (Math.max(a, b) >= slc.length) { return null; } else if (a === b) { return Pair.One(slc[Math.max(a, b)]); } else { const ar = slc[a]; const br = slc[b]; return Pair.Both(ar, br); } }