Skip to content

Instantly share code, notes, and snippets.

@MasterTuto
Created February 9, 2023 18:44
Show Gist options
  • Save MasterTuto/3a265d5b003180814881a345d985a420 to your computer and use it in GitHub Desktop.
Save MasterTuto/3a265d5b003180814881a345d985a420 to your computer and use it in GitHub Desktop.
MergeSort using TypeScript TypeSystem.
type Compare<A extends number, B extends number, X extends any[]=[], Y extends any[]=[]> = X['length'] extends A
? Y['length'] extends B ? 0 : -1
: Y['length'] extends B ? 1 : Compare<A, B, [any, ...X], [any, ...Y]>
type IsLower<A extends number, B extends number> = Compare<A, B> extends -1 ? true : false;
type IsHigher<A extends number, B extends number> = Compare<A, B> extends 1 ? true : false;
type Merge<A extends any[], B extends any[]> = A['length'] extends 0 ? B : (
B['length'] extends 0 ? A : (
IsLower<A[0], B[0]> extends true
? [A[0], ...Merge<TakeSince<A, 1>, B>]
: [B[0], ...Merge<A, TakeSince<B, 1>>]
)
)
type IntegerDivisionByTwo<N extends number, V extends any[] = [], P extends any[]=[]> = IsHigher<[...V, ...V]['length'], N> extends true
? P['length'] : IntegerDivisionByTwo<N, [any, ...V], V>;
type TakeUntil<L extends any[], N extends number, V extends any[]=[]> = V['length'] extends N ? V : (
L extends [x: infer A, ...y: infer B] ? TakeUntil<B, N, [...V, A]> : []
);
type TakeSince<L extends any[], N extends number, V extends any[]=[]> = L extends [x: infer A, ...y: infer B] ? (
V['length'] extends N ? [A, ...B] : TakeSince<B, N, [A, ...V]>
) : [];
type MergeSort<L extends any[]> = IsLower<L['length'], 2> extends true ? L : (
IntegerDivisionByTwo<L['length']> extends infer N extends number ? (
Merge<MergeSort<TakeUntil<L, N>>, MergeSort<TakeSince<L, N>>>
) : never
)
type Sort<L extends any[]> = MergeSort<L>;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment