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 { weight: N; __next: [number, number]; } export interface Edge { weight: E; node: [number, number]; __next: [number, number]; // next edge source(): number; target(): number; } export function createNode(weight: N, next: [number, number]): Node { return { weight, __next: next, } } export function createEdge(weight: E, next: [number, number], node: [number, number]): Edge { return { weight, node, __next: next, source(): number { return node[0] }, target(): number { return node[1] } } } export class Pair { constructor(public value: T | [T, T]) { if (Array.isArray(value)) { this.type = 'Both' } else { this.type = 'One'; } } readonly type: 'One' | 'Both'; static One(x: T) { return new Pair(x) } static Both(a: T, b: T) { return new Pair([a, b] as const) } } export function index_twice(slc: T[], a: number, b: number): Option> { 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); } }