// type BuildTuple<L extends number, T extends unknown[] = []> =
T['length'] extends L ? T : BuildTuple<L, [...T, unknown]>;
type Subtract<M extends number, S extends number> =
BuildTuple<M> extends [...BuildTuple<S>, ...infer R]
? R['length']
: never;
Solution by Swastik777YT #34917
// M => minuend, S => subtrahend
type _Generator<T, R extends any[] = []> = R["length"] extends T
? R
: _Generator<T, [...R, unknown]>;
type Pop<T extends any[]> = T extends [...infer Next, infer _] ? Next : [];
type Subtract<
T,
S,
_T extends any[] = _Generator<T>,
_S extends any[] = _Generator<S>,
> = _S["length"] extends 0
? _T["length"]
: [Pop<_T>["length"]] extends [0]
? [Pop<_S>["length"]] extends [0]
? Pop<_T>["length"]
: never
: Subtract<T, S, Pop<_T>, Pop<_S>>;
Solution by ickynavigator #33904
type ParseInt<T> = T extends `${infer R extends number}` ? R : T
type RemoveZero<T> = T extends '0'
? T
: T extends `${infer F}${infer R}` ? F extends '0' ? RemoveZero<R> : T : T
type Reverse<T> = T extends `${infer F}${infer R}`
? `${Reverse<R>}${F}`
: ''
type NextNumber = { '0': '1', '1': '2', '2': '3', '3': '4', '4': '5', '5': '6', '6': '7', '7': '8', '8': '9' }
type PlusOne<T extends string> = T extends `${infer F}${infer R}`
? F extends '9'
? `0${PlusOne<R>}`
: `${NextNumber[F & keyof NextNumber]}${R}`
: '1'
type ReversedSubtract<
M extends string,
S extends string,
> = `${M}` extends `${infer F1}${infer R1}`
? `${S}` extends `${infer F2}${infer R2}`
? F1 extends F2
? `0${ReversedSubtract<R1, R2>}`
: F2 extends '0'
? `${F1}${ReversedSubtract<R1, R2>}`
: ReversedSubtract<PlusOne<M>, PlusOne<S>>
: ''
: `${S}` extends `${infer _}${infer _}` ? never : M
// M => minuend, S => subtrahend
type Subtract<
M extends number,
S extends number,
> = ParseInt<RemoveZero<Reverse<ReversedSubtract<Reverse<`${M}`>, Reverse<`${S}`>>>>>
Solution by Heonys #32510
type Subtract<
Minuend extends number,
Subtrahend extends number,
C extends 0[] = [],
D extends 0[] = []
> = C["length"] extends Minuend
? D["length"] extends 0
? Minuend extends Subtrahend
? 0
: never
: D["length"]
: C["length"] extends Subtrahend
? Subtract<Minuend, Subtrahend, [0, ...C], [0, ...D]>
: D["length"] extends 0
? Subtract<Minuend, Subtrahend, [0, ...C], D>
: Subtract<Minuend, Subtrahend, [0, ...C], [0, ...D]>;
Solution by vangie #32340
type NTuple<N extends number, Arr extends any[] = []> = Arr extends {
length: N;
}
? Arr
: NTuple<N, [...Arr, any]>;
type Substract<N1 extends number, N2 extends number> = NTuple<N1> extends [
...infer R,
...NTuple<N2>
]
? R["length"]
: never;
Solution by slemchik03 #27660
type MakeCounter<N extends number, _Result extends 1[] = []> = _Result[`length`] extends N ? _Result : MakeCounter<N, [..._Result, 1]>;
type Pop<T extends any[]> = T extends [...infer R, any] ? R : [];
type SimpleCounterMinu<C1 extends any[], C2 extends any[]> = C1 extends [] ?
(C2 extends [] ? 0 : never) : //0-0 or Negative
(C2 extends [] ? C1[`length`] /*return*/ : SimpleCounterMinu<Pop<C1>, Pop<C2>>);
type Subtract<M extends number, S extends number> = SimpleCounterMinu<MakeCounter<M>, MakeCounter<S>>;
Solution by E-uler #25875
type NumberToArray<T extends number, Result extends 0[] = []> = Result['length'] extends T
? Result
: NumberToArray<T, [...Result, 0]>
type Subtract<
T extends number,
U extends number,
TCounter extends 0[] = [],
UCounter extends 0[] = []
> = TCounter['length'] extends T
? TCounter extends [...UCounter, ...infer AfterSubtract]
? AfterSubtract['length']
: never
: Subtract<T, U, NumberToArray<T>, NumberToArray<U>>
Solution by NeylonR #24995
type Subtract<T extends number,U extends number,N extends 0[] = [],V extends 0[] = []> =
T extends N['length']
? T extends U
? 0
: V['length'] extends 0
? never
: N extends [...V, ...infer L]
? L['length']
: 0
: U extends N['length']
? Subtract<T, U, [...N, 0], N>
: Subtract<T, U, [...N, 0], V>
Solution by TKBnice #24554
type BuildTuple<T extends number, _TP extends unknown[] = []> =
_TP['length'] extends T
? _TP
: BuildTuple<T, [..._TP, unknown]>
// M => minuend, S => subtrahend
type Subtract<M extends number, S extends number> =
BuildTuple<M> extends [...BuildTuple<S>, ...infer Rest]
? Rest['length']
: never
Finally! Last challenge completed!
I don't know why this is marked as extreme, it's so simple...
Solution by zhaoyao91 #23451
type NTuple<N extends number, C extends unknown[]=[]>=C['length'] extends N ? C : NTuple<N, [...C, 0]>;
type Subtract<M extends number, S extends number> = NTuple<M> extends [...NTuple<S> , ...infer Rest] ? Rest['length'] : never;
Solution by Karamuto #22360
// M => minuend, S => subtrahend
type CreateTuple<
N extends number,
Tuple extends 1[] = []
> = Tuple["length"] extends N ? Tuple : CreateTuple<N, [...Tuple, 1]>;
type Subtract<M extends number, S extends number> = CreateTuple<M> extends [
...CreateTuple<S>,
...infer Rest
]
? Rest["length"]
: never;
Solution by wubetter #21037
// Create array of N length
type NArray<N extends number, A extends any[]= []> = A['length'] extends N ? A : NArray<N, [...A, never]>;
type Reduce<M extends any[], S extends any[]> =
S extends [infer S1, ...infer SR]
? M extends [infer M1, ...infer MR]
? Reduce<MR, SR>
: never
: M['length'];
// M => minuend, S => subtrahend
type Subtract<M extends number, S extends number> = Reduce<NArray<M>, NArray<S>>
Solution by mdakram28 #20678
type GreaterThan<T extends number, U extends number, K extends any[] = []> = K['length'] extends T
? false
: K['length'] extends U
? true
: GreaterThan<T, U, [...K, any]>;
type NumToArr<Num extends number, Res extends any[] = []> = Res['length'] extends Num ? Res : NumToArr<Num, [1, ...Res]>
type Pop<Arr extends any[], P extends number, Count extends any[] = []> = Arr extends [...infer Head, infer Tail]
? Count['length'] extends P
? Arr : Pop<Head, P, [...Count, 1]>
: GreaterThan<P, Count['length']> extends true ? never : []
type Subtract<M extends number, S extends number, Arr1 extends any[] = NumToArr<M>> = Pop<Arr1, S>['length']
Solution by Zhukov87 #19994
type TenTimesArray<T extends unknown[]> = [
...T,
...T,
...T,
...T,
...T,
...T,
...T,
...T,
...T,
...T
]
type ArrayWithinTen<
T extends string | number,
R extends unknown[] = []
> = `${R['length']}` extends `${T}` ? R : ArrayWithinTen<T, [unknown, ...R]>
type ArrayWithLength<
T extends string | number,
R extends unknown[] = []
> = `${T}` extends `${infer A}${infer B}`
? ArrayWithLength<B, [...TenTimesArray<R>, ...ArrayWithinTen<A>]>
: R
type Subtract<
M extends number,
S extends number
> = `${M}` extends `${number}${number}${number}${number}`
? never
: ArrayWithLength<M> extends [...ArrayWithLength<S>, ...infer R]
? R['length']
: never
Solution by theoolee #19897
// your answers
type Digits =
{
'0':[],
'1':[0],
'2':[0,0],
'3':[0,0,0],
'4':[0,0,0,0],
'5':[0,0,0,0,0],
'6':[0,0,0,0,0,0],
'7':[0,0,0,0,0,0,0],
'8':[0,0,0,0,0,0,0,0],
'9':[0,0,0,0,0,0,0,0,0],
} ;
type _10=[0,0,0,0,0,0,0,0,0,0] ;
type ReverseString<
Str> =
Str extends `${infer R extends string}${infer U extends string}`
? `${ReverseString<U>}${R}`
: '' ;
type Multiply<
A extends readonly any[],
B extends readonly any[]> =
A extends readonly [infer R,...infer U extends readonly any[]]
? [...B,...Multiply<U,B>]
: [] ;
type ReversedStringToTuple<
Str extends string> =
Str extends `${infer R extends keyof Digits}${infer U extends string}`
? [...Digits[R],...Multiply<_10,ReversedStringToTuple<U>>]
: [] ;
type Subtract<
M extends number,
S extends number> =
ReversedStringToTuple<ReverseString<`${M}`>> extends
readonly [...ReversedStringToTuple<ReverseString<`${S}`>>,...infer U extends readonly any[]]
? U['length']
: never ;
Solution by justBadProgrammer #17148
// your answers
type NumberToTuple<T extends number, Result extends 0[] = []> = Result['length'] extends T
? Result
: NumberToTuple<T, [0, ...Result]>
type MinusOne<T extends number, Result extends 0[] = NumberToTuple<T>> = Result extends [infer F, ...infer R]
? R['length']
: 0
type GT<A extends number, B extends number> = A extends B
? false
: A extends 0
? false
: B extends 0
? true
: GT<MinusOne<A>, MinusOne<B>>
type PlusOne<T extends number, Result extends 0[] = NumberToTuple<T>> = [...Result, 0]['length'] & number
type Minus<M extends number, N extends number, Result extends number = 0> = M extends N
? Result
: Minus<M, PlusOne<N>, PlusOne<Result>>
// M => minuend, S => subtrahend
type Subtract<M extends number, S extends number> = GT<S, M> extends true
? never
: Minus<M, S>
Solution by humandetail #16699
/*
Return if a number is smaller than another number
Input: 2,1
Output: true
*/
type IsSmallerThan<T extends number, U extends number, US extends number[] = []> =
US['length'] extends T
? US['length'] extends U
? true
: false
:US['length'] extends U
? true
: IsSmallerThan<T, U, [...US, 1]>
/*
Fills an array with ones until the length of the array is the same as the provided number
Input: 5
Output: [1,1,1,1,1]
*/
type FillArray<T extends number, Acc extends 1[] =[]> = Acc['length'] extends T ? Acc : FillArray<T, [...Acc,1]>
/*
Idea (3, 1): Fill an array to the length of the lower number (1 => [1]), then add an temporary array and fill it until the length of the combined arrays [1] and temp[] is [1,1,1] (3)
Solution 1:
Let Typescript do the work by infering via a Rest parameter, and if the condition is meet, return the length of the infered Array
*/
type Subtract<M extends number, S extends number> = FillArray<M> extends [...FillArray<S>, ...infer Rest] ? Rest['length'] : never
/*
Solution 2:
Use an accumulator that stores the current diff between T and U. Fill that accumulator until the union of accumulator and the filled array of the smaller number sums up to the higher number
*/
type Subtract<M extends number, S extends number, MA extends number[]= FillArray<M>, SA extends number[] = FillArray<S>, Temp extends number[] =[]> = IsSmallerThan<M,S> extends false ? never:[...SA, ...Temp]['length'] extends M ? Temp['length'] : Subtract<M,S, MA,SA, [...Temp,1]>
Solution by JohannesSchwegler #16386
// your answers
type Subtract<M extends number, S extends number, P extends unknown[] = [], R extends unknown[] = []> = P['length'] extends S
? (
[...P, ...R]['length'] extends M ? R['length'] : Subtract<M, S, P, [...R, 1]>
)
: (
P['length'] extends M ? never : Subtract<M, S, [...P, 1], R>
)
Solution by fengchunqi #14953
// your answers
type Rang<T extends Number = 0, P extends 1[] = []> =
P['length'] extends T ?
P : Rang<T, [1, ...P]>
type Shift<T extends 1[]> = T extends [infer F, ...infer Rest] ? Rest : []
type Subtract<M extends number, S extends number, L extends 1[] = Rang<M>, R extends 1[] = Rang<S>> =
L['length'] extends 0
? R['length'] extends 0
? 0
: never
: R['length'] extends 0
? L['length']
: Subtract<M, S, Shift<L>, Shift<R>>
Solution by Sliect #14578
type Subtract<M extends number, S extends number> = M extends -1
? never
: S extends 0
? M
: Subtract<MinusOne<M>, MinusOne<S>>;
type MinusOne<T extends number> = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9][T];
Solution by fardolieri #14186
type Number<T extends number> = _while<T, []>
type _while<T extends number, L extends NumberLike> =
Equal<L["length"], T> extends true
? L
: _while<T, [...L, 0]>
type Numbering<T extends NumberLike> = T["length"]
type NumberLike = Array<any>
type Minus<T extends NumberLike, K extends NumberLike> =
T extends [...K, ...infer I] ? I : never
type Subtract<M extends number, S extends number> = Numbering<Minus<Number<M>, Number<S>>>
Solution by DrLee-lihr #11989
type Subtract<M extends number, S extends number> = TrimZero<Minus<M, S>> extends `${infer N extends number}` ? N : never
type TrimZero<S extends string> = S extends `0${infer R extends `${any}${any}`}` ? TrimZero<R> : S
type Minus<M extends number | string, S extends number | string, Suffix extends string = ''>
= `${M}-${S}` extends
Match<'00'|'11'|'22'|'33'|'44'|'55'|'66'|'77'|'88'|'99', infer C00, infer D00> |
Match<'10'|'21'|'32'|'43'|'54'|'65'|'76'|'87'|'98', infer C01, infer D01> | Match<'09', infer C11, infer D11> |
Match<'20'|'31'|'42'|'53'|'64'|'75'|'86'|'97', infer C02, infer D02> | Match<'08'|'19', infer C12, infer D12> |
Match<'30'|'41'|'52'|'63'|'74'|'85'|'96', infer C03, infer D03> | Match<'07'|'18'|'29', infer C13, infer D13> |
Match<'40'|'51'|'62'|'73'|'84'|'95', infer C04, infer D04> | Match<'06'|'17'|'28'|'39', infer C14, infer D14> |
Match<'50'|'61'|'72'|'83'|'94', infer C05, infer D05> | Match<'05'|'16'|'27'|'38'|'49', infer C15, infer D15> |
Match<'60'|'71'|'82'|'93', infer C06, infer D06> | Match<'04'|'15'|'26'|'37'|'48'|'59', infer C16, infer D16> |
Match<'70'|'81'|'92', infer C07, infer D07> | Match<'03'|'14'|'25'|'36'|'47'|'58'|'69', infer C17, infer D17> |
Match<'80'|'91', infer C08, infer D08> | Match<'02'|'13'|'24'|'35'|'46'|'57'|'68'|'79', infer C18, infer D18> |
Match<'90', infer C09, infer D09> | Match<'01'|'12'|'23'|'34'|'45'|'56'|'67'|'78'|'89', infer C19, infer D19>
? C00 extends `${any}` ? Minus<C00, D00, `0${Suffix}`> :
C01 extends `${any}` ? Minus<C01, D01, `1${Suffix}`> : C11 extends `${any}` ? Minus<Minus<C11, D11>, 1, `1${Suffix}`> :
C02 extends `${any}` ? Minus<C02, D02, `2${Suffix}`> : C12 extends `${any}` ? Minus<Minus<C12, D12>, 1, `2${Suffix}`> :
C03 extends `${any}` ? Minus<C03, D03, `3${Suffix}`> : C13 extends `${any}` ? Minus<Minus<C13, D13>, 1, `3${Suffix}`> :
C04 extends `${any}` ? Minus<C04, D04, `4${Suffix}`> : C14 extends `${any}` ? Minus<Minus<C14, D14>, 1, `4${Suffix}`> :
C05 extends `${any}` ? Minus<C05, D05, `5${Suffix}`> : C15 extends `${any}` ? Minus<Minus<C15, D15>, 1, `5${Suffix}`> :
C06 extends `${any}` ? Minus<C06, D06, `6${Suffix}`> : C16 extends `${any}` ? Minus<Minus<C16, D16>, 1, `6${Suffix}`> :
C07 extends `${any}` ? Minus<C07, D07, `7${Suffix}`> : C18 extends `${any}` ? Minus<Minus<C18, D18>, 1, `8${Suffix}`> :
C08 extends `${any}` ? Minus<C08, D08, `8${Suffix}`> : C19 extends `${any}` ? Minus<Minus<C19, D19>, 1, `9${Suffix}`> :
C09 extends `${any}` ? Minus<C09, D09, `9${Suffix}`> : never
: `${S}` extends '' ? `${M}${Suffix}` : never
type Match<P extends string, C extends string, D extends string> = P extends `${infer X}${infer Y}` ? `${C}${X}-${D}${Y}` : never
Solution by teamchong #11577
Can display actual numbers instead of number
type Tuple<T, Res extends 1[] = []> = 0 extends 1 ? never : Res['length'] extends T ? Res : Tuple<T, [...Res, 1]>;
type Subtract<M extends number, S extends number> = Tuple<M> extends [...Tuple<S>, ...infer Rest] ? Rest['length'] : never
Solution by ProsperBao #11216
type CreateArr<T extends number , Res extends any[] = []> = Res['length'] extends T ? Res: CreateArr<T,[...Res,unknown]>
type Subtract<M extends number, S extends number> = CreateArr<M> extends [...start:CreateArr<S>,...end: infer Res] ? Res['length'] : never
Solution by EGyoung #10243
type Length<T extends any[]> = T['length']
type ToArray<T extends number, R extends any[] = []> = Length<R> extends T ? R : ToArray<T, [...R, any]>
type Subtract<M extends number, S extends number> = ToArray<M> extends [...ToArray<S>, ...infer Rest] ? Length<Rest> : never
Solution by xuemanchi #9157
type GetLenTuple<L extends number, R extends any[]=[]> = R['length'] extends L ? R:GetLenTuple<L, [...R,any]>;
type N1 = [any];
type N2 = [any, any];
type N3 = [any, any, any];
type N4 = [any, any, any, any];
type N5 = [any, any, any, any, any];
type N6 = [any, any, any, any, any, any];
type N7 = [any, any, any, any, any, any, any];
type N8 = [any, any, any, any, any, any, any, any];
type N9 = [any, any, any, any, any, any, any, any, any];
type N10 = [...N9, any];
type DigitToTuple<N, L = N extends string | number ? `${N}` : ''> = L extends `${N1['length']}` ? N1
: L extends `2`? N2
: L extends `3`? N3
: L extends `4`? N4
: L extends `5`? N5
: L extends `6`? N6
: L extends `7`? N7
: L extends `8`? N8
: L extends `9`? N9
: [];
type ToTuple<T extends bigint | string | number, S = `${T}`> = S extends `${infer F}${infer O}` ? [F, ...ToTuple<O>] : [];
type TupleTail<T extends any[]> = T extends [...infer F, any] ? F : never;
type TupleLast<T extends any[]> = T extends [...any, infer L] ? L : never;
type Comparator<L extends any[], R extends any[]> = L extends [...R, ...infer O] ? O['length'] extends 0 ? 0 : 1 : -1;
type LowSub<M extends any[], S extends any[]> =
M extends [...S, ...infer N] ? [N['length'], []]
: [...N10, ...M] extends [...S, ...infer N] ? [N['length'],[any]]
: never;
type OrderSub<M extends any[], S extends any[], R extends any[] = [], P extends any[] = [], ML extends any[] =DigitToTuple<TupleLast<M>>, SL extends any [] = [...DigitToTuple<TupleLast<S>>, ...P] > =
M extends [] ? ( P extends [] ? R:never)
: S extends []? R
: LowSub<ML, SL> extends [infer R1, infer N] ? OrderSub<TupleTail<M>, TupleTail<S>, [R1,...R], (N extends any[]?N:[])>
:never;
type TupleRepeat<T extends any[], N extends any, L extends any[] = [any], NS = N extends string | number ? `${N}` : ''> = NS extends '0'
? [] : `${L['length']}` extends NS
? T : [...T, ...TupleRepeat<T, N, [...L, any]>];
type Result<T extends any[], B extends any[] = [any], R extends any[]=[]> = T extends [...infer F, infer L] ? Result<F, TupleRepeat<B, 10>, [...R, ...TupleRepeat<B, L>]> : R['length'];
// M => minuend, S => subtrahend
type Subtract<M extends number, S extends number, Mu extends any[] = ToTuple<M>, Su extends any[] = ToTuple<S>> =
Comparator<GetLenTuple<Mu['length']>, GetLenTuple<Su['length']>> extends -1 ? never
:Result<OrderSub<Mu, Su>>;
Solution by venusliang #8044
// your answers
type NumberToTupleBase<T extends string, R extends any[] = []> = `${T}` extends `${number}`
? `${T}` extends `${R['length']}`
? R
: NumberToTupleBase<T, [...R, unknown]>
: []
type Expand10<T extends any[]> = [...T, ...T, ...T, ...T, ...T, ...T, ...T, ...T, ...T, ...T]
type ConstructTuple<S extends number | string, Res extends any[] = []> = `${S}` extends `${infer L}${infer R}`
? ConstructTuple<R, [...Expand10<Res>, ...NumberToTupleBase<L>]>
: Res
type Subtract<M extends number, S extends number> = ConstructTuple<M> extends [...ConstructTuple<S>, ...infer R] ? R['length'] : never
Solution by ch3cknull #7963
type ConstructTuple<L extends number, R extends unknown[] = []> = R["length"] extends L ? R : ConstructTuple<L, [...R, unknown]>
// M => minuend, S => subtrahend
type Subtract<M extends number, S extends number> = ConstructTuple<M> extends [...subtrahend: ConstructTuple<S>, ...rest: infer Rest] ? Rest["length"] : never
Solution by LoTwT #7680
θ½ηΆδ½ζ―γγγζθ§
// @ts-expect-error
Expect<Equal<ExtremeSubtract<1000, 999>, 1>>
δΈεΊθ―₯ζ―ζζζ₯ιε§γγγ
// your answers
type EqualOrGreaterThan<F extends number, S extends number, CountArr extends Array<unknown> = []> =
F extends S
? true
: CountArr['length'] extends F
? false
: CountArr['length'] extends S
? true
: EqualOrGreaterThan<F, S, [...CountArr, unknown]>
type BuildTuple<N extends number, CountArr extends Array<unknown> = []> =
CountArr['length'] extends N ? CountArr : BuildTuple<N, [...CountArr, unknown]>
type SubtractHelper<M extends number, S extends number> =
BuildTuple<M> extends [...infer Rest, ...BuildTuple<S>] ? Rest['length'] : 0
// M => minuend, S => subtrahend
type ExtremeSubtract < M extends number, S extends number > =
EqualOrGreaterThan < M, S > extends true
? SubtractHelper<M, S>
: never
Solution by HongxuanG #7669