From 8dcc77ffc0f8bf1b5a54c6d1ca86aafb72748686 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kimi=20L=C3=B6ffel?= Date: Sun, 12 Mar 2023 00:54:51 +0100 Subject: [PATCH] add sort --- sort.ts | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 sort.ts diff --git a/sort.ts b/sort.ts new file mode 100644 index 0000000..3a81d10 --- /dev/null +++ b/sort.ts @@ -0,0 +1,135 @@ +import type { Equal, Expect } from '@type-challenges/utils' + +type cases = [ + Expect, []>>, + Expect, [1]>>, + Expect, [1, 2]>>, + Expect, [0, 0, 0]>>, + Expect, [1, 2, 3]>>, + Expect, [1, 2, 3]>>, + Expect, [1, 2, 2, 3]>>, + Expect, [0, 0, 0, 0, 1, 2, 3]>>, + Expect, [2, 4, 5, 6, 6, 6, 7, 8, 9]>>, + Expect, [1, 1, 1, 1, 1, 1, 1, 1, 2]>>, + Expect, []>>, + Expect, [1]>>, + Expect, [2, 1]>>, + Expect, [0, 0, 0]>>, + Expect, [3, 2, 1]>>, + Expect, [3, 2, 1]>>, + Expect, [3, 2, 2, 1]>>, + Expect, [3, 2, 1, 0, 0, 0, 0]>>, + Expect, [9, 8, 7, 6, 6, 6, 5, 4, 2]>>, +] + +type ApproxEqualLength< + T extends unknown[], + U extends unknown[], + N extends number = T['length'], + M extends number = U['length'], +> = +N extends M + ? true + : [...T, 1]['length'] extends M + ? true + : [...U, 1]['length'] extends N + ? true + : false +; + +type SplitHalf< + T extends number[], + Left extends number[] = [], + Right extends number[] = T, +> = +ApproxEqualLength extends true + ? [Left, Right] + : Right extends [infer Head, ...infer Tail] + ? Head extends number + ? Tail extends number[] + ? SplitHalf + : never + : never + : never +; + +type Greater< + T extends number, + U extends number, + Acc extends 1[] = [] +> = +Acc['length'] extends T + ? Acc['length'] extends U + ? false + : false + : Acc['length'] extends U + ? true + : Greater +; + +type Less< + T extends number, + U extends number, + Acc extends 1[] = [] +> = +Acc['length'] extends T + ? Acc['length'] extends U + ? false + : true + : Acc['length'] extends U + ? false + : Less +; + + +type Merge< + T extends number[], + U extends number[], + Desc extends boolean = false, + Acc extends number[] = [], +> = +T extends [infer THead, ...infer TTail] + // T has elements + ? U extends [infer UHead, ...infer UTail] + // U has elements + ? THead extends number + ? UHead extends number + ? TTail extends number[] + ? UTail extends number[] + ? Desc extends false + ? Less extends true + ? Merge + : Merge + : Greater extends true + ? Merge + : Merge + : never + : never + : never + : never + // U has no elements + : [...Acc, THead, ...TTail] + // T has no elements + : [...Acc, ...U] +; + +type Sort< + T extends number[], + Desc extends boolean = false +> = +T['length'] extends 0 + ? [] + : T['length'] extends 1 + ? T + : SplitHalf extends [infer First, infer Second, ...infer Tail] + ? First extends number[] + ? Second extends number[] + ? Merge< + Sort, + Sort, + Desc + > + : never + : never + : never +; \ No newline at end of file