main
Kimi Löffel 3 years ago
parent 57f08ab89c
commit 8dcc77ffc0

@ -0,0 +1,135 @@
import type { Equal, Expect } from '@type-challenges/utils'
type cases = [
Expect<Equal<Sort<[]>, []>>,
Expect<Equal<Sort<[1]>, [1]>>,
Expect<Equal<Sort<[2, 1]>, [1, 2]>>,
Expect<Equal<Sort<[0, 0, 0]>, [0, 0, 0]>>,
Expect<Equal<Sort<[1, 2, 3]>, [1, 2, 3]>>,
Expect<Equal<Sort<[3, 2, 1]>, [1, 2, 3]>>,
Expect<Equal<Sort<[3, 2, 1, 2]>, [1, 2, 2, 3]>>,
Expect<Equal<Sort<[3, 2, 0, 1, 0, 0, 0]>, [0, 0, 0, 0, 1, 2, 3]>>,
Expect<Equal<Sort<[2, 4, 7, 6, 6, 6, 5, 8, 9]>, [2, 4, 5, 6, 6, 6, 7, 8, 9]>>,
Expect<Equal<Sort<[1, 1, 2, 1, 1, 1, 1, 1, 1]>, [1, 1, 1, 1, 1, 1, 1, 1, 2]>>,
Expect<Equal<Sort<[], true>, []>>,
Expect<Equal<Sort<[1], true>, [1]>>,
Expect<Equal<Sort<[2, 1], true>, [2, 1]>>,
Expect<Equal<Sort<[0, 0, 0], true>, [0, 0, 0]>>,
Expect<Equal<Sort<[1, 2, 3], true>, [3, 2, 1]>>,
Expect<Equal<Sort<[3, 2, 1], true>, [3, 2, 1]>>,
Expect<Equal<Sort<[3, 2, 1, 2], true>, [3, 2, 2, 1]>>,
Expect<Equal<Sort<[3, 2, 0, 1, 0, 0, 0], true>, [3, 2, 1, 0, 0, 0, 0]>>,
Expect<Equal<Sort<[2, 4, 7, 6, 6, 6, 5, 8, 9], true>, [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<Left, Right> extends true
? [Left, Right]
: Right extends [infer Head, ...infer Tail]
? Head extends number
? Tail extends number[]
? SplitHalf<T, [...Left, Head], Tail>
: 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<T, U, [1, ...Acc]>
;
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<T, U, [...Acc, 1]>
;
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<THead, UHead> extends true
? Merge<TTail, U, Desc, [...Acc, THead]>
: Merge<T, UTail, Desc, [...Acc, UHead]>
: Greater<THead, UHead> extends true
? Merge<TTail, U, Desc, [...Acc, THead]>
: Merge<T, UTail, Desc, [...Acc, UHead]>
: 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<T> extends [infer First, infer Second, ...infer Tail]
? First extends number[]
? Second extends number[]
? Merge<
Sort<First, Desc>,
Sort<Second, Desc>,
Desc
>
: never
: never
: never
;
Loading…
Cancel
Save