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…
Reference in new issue