Skip to content

Instantly share code, notes, and snippets.

@futurGH
Last active September 4, 2024 03:08
Show Gist options
  • Save futurGH/98593dc2f7d3e5488a990f1c31fb3c25 to your computer and use it in GitHub Desktop.
Save futurGH/98593dc2f7d3e5488a990f1c31fb3c25 to your computer and use it in GitHub Desktop.
A TypeScript type-only bubble sort
// https://www.typescriptlang.org/play#code/C4TwDgpgBAyg9gJ2BAJlAvFAQgVwEZ4A2E8SAPANoCMANFACx21QDMdATHQLQCcdAHHQDs3TlABsdRlCrSu7ZlUEzmQtlHbsAugD4AsACgA9EahmAegH5DhkyahdHT5y65YAqliwAZAKKwAeQAlABVXcKcbA1BIbHwiEkRgMgA5KAgAD2QAOxQAZyhsnABbPAgECl0MQzNcAmJSYAAFAEM8vNSddKyIXIKAS2yAM3KoAOyIVvbunPzCkrKKrRqzKEs4+sSkKY7xyba8rszZgrqExp3OldW1jfOky5T9AxuzAC47hqSyPZ3nm4+EwAbuUojFoGcvtsDqkZr05kVSuVKl10Cs0sd4QUKIMRggoAAxfoIPLAOF9eZIhB0XGjGAQADGcFy5IRC3KdAAdNzafighBSayCojFpVli9Vut+YLMRTKtdJVBvAK8iEABYtbJkIkk4B0elM3JHHoU4AIHAQBU3dYUHWk-WM5kocWvVYfCgGp10O3AF2vD7K9rqzXa4n22COo1CqBmi1WxW2sN6qDczmQrbNGEeyMoLnc6W+nR+13uz25PNp+JQzPtSg+isF3TFqCAiAghBROymCLhdwhACS3n7IQAmlBR01fDAe64weBoIHVRqtQBBaMijnYdfshColZr2VzLAK9ZDFqEPKWiXvKAAAwAJABvFcAX1v0dvXCfvKgK7weQPE02SpN943WB9HywN8Py-R8fz-PIsG3EDb3jMx1kXYNV3-LA6AQlcunsNcyCgAAGOgkJI0i0JbGNzWgIioCoiioB0TBqOvN07yfKD30PApPyfDcEFAzj0KgM8LwY0w1zYsiWKo+MPhgfAzRaBlkhXCjjROQo21GewkK6FcaPWWMr1dG9JMvOdYhXFAUDIQDdOElj+MpRZUSgChUxCHAwGIAIhmVbIAHNgDVJydArPyAogIKQvCyKsCLCgACJiDCiK0q0ABuWzoBUvA1I0pzkMWNygOFHcvJWWLAuC3okqi6MfO5er4sarLkuilMeWGUZpRwQhfUMABIcShpGigAHJMqSmbxQm2jgXKfKDEMcFx38hrEoishxu8cqOXGoJo1IyoMG8rQaEMLyglm+aIsW6MjqlWiOoSpr9u8Og2s5II6FI3RcqAA
type Sorted = BubbleSort<[1, 4, 1, 3, 2, -9, 8, 7, -2, 6, 4, 14, -21, 18, 11, 73, 22]>
// ^? - type Sorted = [-21, -9, -2, 1, 1, 2, 3, 4, 4, 6, 7, 8, 11, 14, 18, 22, 73]
//// ----------------BUBBLE SORT----------------
type BubbleSort<N extends number[]> =
BubbleSortPass<N> extends infer OnePass extends number[]
? BubbleSortPass<OnePass> extends BubbleSortPass<N>
? BubbleSortPass<N>
: BubbleSort<OnePass>
: never
type BubbleSortPass<N extends number[]> =
N extends [infer First extends number, infer Second extends number, ...infer Rest extends number[]]
? Rest extends []
? LessThan<First, Second> extends true
? [First, Second]
: [Second, First]
: LessThan<First, Second> extends true
? [First, ...BubbleSortPass<[Second, ...Rest]>]
: [Second, ...BubbleSortPass<[First, ...Rest]>]
: never
//// ---------------UTILITY TYPES---------------
type LessThan<A extends number, B extends number> =
A extends B
? false
: `${A}` extends `-${infer AbsA extends number}`
? `${B}` extends `-${infer AbsB extends number}`
? LessThan<AbsB, AbsA> // A < 0, B < 0
: true // A < 0, B >= 0
: `${B}` extends `-${number}`
? false // A >= 0, B < 0
: Subtract<A, B> extends never // B > A
? true
: false
type Add<A extends number, B extends number> = [...TupleOfLength<A>, ...TupleOfLength<B>]["length"];
type Subtract<A extends number, B extends number> =
TupleOfLength<A> extends [...TupleOfLength<B>, ...infer Result]
? Result['length']
: never;
type TupleOfLength<
L extends number,
R extends 0[] = [],
> = R['length'] extends L ? R : TupleOfLength<L, [...R, 0]>;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment