import type { Index } from './base'; /** * Get the absolute value of a number */ export type Abs = `${T}` extends `-${string}` ? `${T}` extends `-${infer U}` ? `${U}` extends `${infer V extends number}` ? V : never : T : T; /** * Fill array to a certain size */ type Fill = Arr['length'] extends T ? Arr : Fill; /** * Test if integer `A` is greater than `B` */ export type IsGreater = [IsNegative, IsNegative] extends [infer NegA extends boolean, infer NegB extends boolean] ? [NegA, NegB] extends [true, true] ? [Abs, Abs] extends [infer AbsA extends number, infer AbsB extends number] ? IsGreater : never : [NegA, NegB] extends [false, true] ? true : [NegA, NegB] extends [true, false] ? false : [NegA, NegB] extends [false, false] ? _Balance extends [infer BalA extends number, number] ? BalA extends 0 ? false : true : never : never : never; /** Test if string `T` includes string `U` */ export type Includes = T extends `${string}${U}${string}` ? true : false; /** Increment number `T` */ export type Increment = Acc['length'] extends T ? [...Acc, 1]['length'] : Increment; /** Convert positive string integer `T` to `number` */ export type Int = `${T}` extends `-${string}` | `${string}.${string}` ? never : T extends `${infer U extends number}` ? U : never; /** Test if string `T` is of length `U` */ export type IsLength = T extends `${infer _}${infer Rest}` ? Acc['length'] extends U ? false : IsLength : Acc['length'] extends U ? true : false; /** Test for negative value */ export type IsNegative = `${T}` extends `-${string}` ? true : false; /** Test if a number is odd */ export type IsOdd = `${T}` extends `${string}${'1' | '3' | '5' | '7' | '9'}` ? true : false; /** Multiple a number by -1 */ export type Negate = `${T}` extends `-${infer V extends number}` ? V : ToNumber<`-${T}`>; /** Map a tuple of indices to san notation */ export type ToMoves = T extends [infer To extends Index, ...infer Tail extends Index[]] ? ToMoves : Acc; /** Cast string value to a number */ type ToNumber = T extends `${infer U extends number}` ? U : never; /** * Sum two numbers */ export type Sum = [IsNegative, IsNegative] extends [infer NegA extends boolean, infer NegB extends boolean] ? [NegA, NegB] extends [true, true] ? Negate<_Sum, Abs>> : [NegA, NegB] extends [true, false] ? _Balance extends [infer BalanceA extends number, infer BalanceB extends number] ? BalanceA extends 0 ? BalanceB : Negate : never : [NegA, NegB] extends [false, true] ? _Balance extends [infer BalanceA extends number, infer BalanceB extends number] ? BalanceB extends 0 ? BalanceA : Negate : never : _Sum : never; export type _Sum = [...Fill, ...Fill]['length'] extends infer U extends number ? U : never; /** Iterate A and B towards 0, stop when either of them reach it */ type _Balance>, SetB extends 1[] = Fill>> = SetA['length'] extends SetB['length'] ? [0, 0] : SetA extends [1, ...infer TailA extends 1[]] ? SetB extends [1, ...infer TailB extends 1[]] ? _Balance : [SetA['length'], 0] : [0, SetB['length']]; export {};