08804-hard-two-sum

Back

type IsEqual<X, Y> =
  (<T>() => T extends X ? 1 : 2) extends
  (<T>() => T extends Y ? 1 : 2) ? true : false

type Includes<T, U> = 
  U extends [infer F, ...infer Rest]
    ? IsEqual<F, T> extends true
      ? true
      : Includes<T, Rest>
    : IsEqual<U, T>

type Length<T extends unknown[]> = T['length']
type NumberToUnionArr<T extends number, R extends unknown[] = []> =
  T extends T
    ? R['length'] extends T
      ? R
      : NumberToUnionArr<T, [...R, 0]>
    : never

type Sub<U extends number, V extends number> = 
  NumberToUnionArr<U> extends [...NumberToUnionArr<V>, ...infer Rest] 
    ? Length<Rest> 
    : never

/**
 * We want u, v in T, such that u+v=U
 * 
 * T is divided into [First, ...Rest]
 * Two cases:
 * 1. (base) select 1st element in T as u, and find v in rest of T
 * 2. (resursive) find such u,v in rest
 */
type TwoSum<T extends number[], U extends number> =
  T extends [infer First extends number, ...infer Rest extends number[]] 
    ? Includes<Sub<U, First>, Rest> extends true 
      ? true 
      : TwoSum<Rest, U> 
    : false

Solution by bkmashiro #33091

Solution using solutions to previous challenges.

// 898 - Includes
type Includes<T extends readonly unknown[], U> = T extends [infer First, ...infer Rest]
  ? Equal<First, U> extends true
  ? true
  : Includes<Rest, U>
  : false;

// 7544 - Construct Tuple
type ConstructTuple<L extends number, T extends unknown[] = []> = T['length'] extends L
  ? T
  : ConstructTuple<L, [...T, unknown]>;

// Actual solution below

type AllPairs<T> = T extends [infer First, ...infer Rest]
  ? [...Pairs<[First, ...Rest]>, ...AllPairs<Rest>]
  : [];

type Pairs<T> = T extends [infer First, infer Second, ...infer Rest]
  ? [[First, Second], ...Pairs<[First, ...Rest]>]
  : [];

type SumPairwise<T> = T extends [[infer First extends number, infer Second extends number], ...infer Rest]
  ? [[...ConstructTuple<First>, ...ConstructTuple<Second>]['length'], ...SumPairwise<Rest>]
  : [];

type TwoSum<T extends number[], U extends number> = Includes<SumPairwise<AllPairs<T>>, U>;

Solution by Robinsstudio #32842

// 生成一个指定长度T的数组,用于后面剪法运算使用,原理就是通过将两个数字转换为两个数组长度推断出差值,也就是减法的结果
type MakeArr<T extends number, U extends number[]=[]> = U['length'] extends T
    ? U
    :MakeArr<T, [1,...U]>
type test1 = MakeArr<2> // type test1 = [1, 1]
// 两个数字的减法运算,目标数字U减去一个数组元素的结果还在数组剩余数组元素中出现,那这个数组中肯定存在两个元素之和等于目标整数
type Sub<A extends number,B extends number> = MakeArr<A> extends [...MakeArr<B>,...c:infer C]
    ? C['length']
    :never
// 相等判断,用于辅助下面Includes类型计算
type IsEqual<T,U> = (<P>()=>(P extends T?1:2)) extends (<P>()=>(P extends U?1:2))?true:false
// 判断数字在数组中是否包含,用于辅助下面TwoSum类型计算
type Includes<T extends readonly any[], U> =  T extends [infer F, ...infer R]
    ? IsEqual<F, U> extends true
        ?true
        :Includes<R, U>
    :false
// 取出数组第一个元素F,拿总数U减去数组第一个元素F,如果这个差值包含在剩余元素数组R中,则返回true
// 如果不成立,则继续拿剩余数组R进行此判断,直至数组时,依然不成立返回false
type TwoSum<T extends number[], U extends number> = T extends [infer F extends number,...infer R extends number[]]
    ? Includes<R, Sub<U, F>> extends true
        ? true
        :TwoSum<R, U>
    :false

Solution by wl-f #32421

type Minus<
  Minuend extends number,
  Subtrahend extends number,
  C extends 0[] = [],
  D extends 0[] = []
> = C["length"] extends Minuend
  ? D["length"] extends 0
    ? Minuend extends Subtrahend
      ? 0
      : unknown
    : D["length"]
  : C["length"] extends Subtrahend
  ? Minus<Minuend, Subtrahend, [0, ...C], [0, ...D]>
  : D["length"] extends 0
  ? Minus<Minuend, Subtrahend, [0, ...C], D>
  : Minus<Minuend, Subtrahend, [0, ...C], [0, ...D]>;

type TwoSum<T extends number[], U extends number> = T extends [
  infer F extends number,
  ...infer R extends number[]
]
  ? Minus<U, F> extends R[number]
    ? true
    : TwoSum<R, U>
  : false;

Solution by vangie #32337


type TwoSub<T extends number, U extends number, C extends any[] = [], R extends any[] = [], F extends boolean = false> = 
  T extends U ? 0 :
  C['length'] extends U ? 
    TwoSub<T, U, [1, ...C], [1, ...R], true>  
    : C['length'] extends T 
      ? (F extends false ? never : R['length']) 
      : TwoSub<T, U, [1, ...C], F extends true ? [1, ...R] : [...R], F>;
type TwoSum<T extends any[], U extends number> = 
  T['length'] extends 1 | 0 ? false :
  T extends [infer S extends number, ...infer O] ? 
    ([TwoSub<U, S>] extends [never] ? 
      TwoSum<O, U> 
    : (TwoSub<U, S> extends O[number] ? true : TwoSum<O, U>)) 
  : false;

Solution by tarotlwei #31853

// 数字类型转数组长度
type Turple<T extends number, U extends any[] = []> = U['length'] extends T ? U : Turple<T, [...U, any]>;
// 计算两数字之差
type Substract<T extends number, U extends number> = Turple<T> extends [...Turple<U>, ...infer Rest] ? Rest['length'] : unknown;
// 数组值类型
type toUnion<T extends any[]> = T extends any[] ? T[number] : T;
type TwoSum<T extends number[], U extends number> = T extends [infer Left extends number, ...infer Rest extends number[]] ? Substract<U, Left> extends toUnion<Rest> ? true : TwoSum<Rest, U> : false;

Solution by dropice #31007

// 解答をここに記入
// 数字 N の長さを持つ配列を返す
type CreateArrFromLen<N extends number, Ans extends never[] = []> = Ans["length"] extends N ? Ans : CreateArrFromLen<N, [never, ...Ans]>

// 2つの数 X, Y の和を返す
type Add<X extends number, Y extends number> = [...CreateArrFromLen<X>, ...CreateArrFromLen<Y>]["length"]

// 配列 T のそれぞれに X を足す
type AddArr<T extends number[], X extends number, G = { [P in keyof T]: Add<T[P], X> }> = G extends number[] ? G : never

type TwoSum<T extends number[], U extends number, Ans extends number[] = []> = T extends [infer F extends number, ...infer Rest extends number[]] ? TwoSum<Rest, U,  [...Ans, ...AddArr<Rest, F>]> : U extends Ans[number] ? true : false

愚直な発想ですが、TwoSum の Ans という変数に、取りうる和のすべてを記録して、最後にそれらの中に U があるか(U extends Ans[number] で判定)を返しています。

Solution by Kakeru-Miyazaki #30977

type Num2Arr<T, U extends any[] = []> = U['length'] extends T ? U : Num2Arr<T, [...U, 1]>
type Calc<T, U, O> = U extends [infer A, ...infer B] ? [...Num2Arr<T>, ...Num2Arr<A>]['length'] extends O ? true : Calc<T, B, O> : false
type TwoSum<T extends number[], U extends number> = T extends [infer A, ...infer B  extends any[]] ? Calc<A, B, U> extends true ? true : TwoSum<B, U> : false

Solution by dreamluo-plus #30780

type markArr<T,U extends any[] = []> = T extends U["length"] ? U : markArr<T,[...U,U["length"]]>;

type plus<A,B> = [...markArr<A>,...markArr<B>]["length"]

type plusArr<V ,T,U > = U extends [] ?never: U extends [infer S,... infer O] ? plus<V,S> extends T ? true :plusArr<V,T,O>:never;

type IsNever<T> = [T] extends [never] ? true : false;

type TwoSum<T extends number[] , U extends number> = T extends [] ? false:  T extends [infer S extends number ,...infer O extends number[] ]  ?  IsNever<plusArr<S,U,O>>  extends true ?TwoSum<O ,U>: true : false;

Solution by jiangxd2016 #30584

type NumToUnion<T extends number, K extends any[]  = []> = K['length'] extends T 
? K 
: NumToUnion<T, [...K, 1]>

type IsEqual<T, A extends number, B extends number[]> = B extends [infer C extends number, ...infer D extends number[]] 
? [...NumToUnion<A>, ...NumToUnion<C>]['length'] extends T 
? true 
: IsEqual<T, A, D> 
: false

type TwoSum<T extends number[], U extends number> = T extends [infer A extends number, ...infer B  extends number[]] 
? IsEqual<U, A, B> extends true 
? true 
: TwoSum<B, U> 
: false

Solution by dreamluo-plus #30462

// 你的答案
type ArrLength<T extends number, A extends 1[] = []> = A['length'] extends T ? A : ArrLength<T, [...A, 1]>

type SmallerThan<T extends number, U extends number, A extends 1[] = []> = T extends U ? true : A['length'] extends T ? false : A['length'] extends U ? true : SmallerThan<T, U, [...A, 1]>

type Differ<T extends number, U extends number> = ArrLength<T> extends [...ArrLength<U>, ...infer Reset] ? Reset['length'] : never

type TwoSum<T extends number[], U extends number> = T extends [T[0], ...infer Reset extends number[]] ? SmallerThan<U, T[0]> extends true ? (Differ<U, T[0]> extends Reset[number] ? true : TwoSum<Reset, U>) : TwoSum<Reset, U> : false

Solution by YE840926098 #29998

// your answers

type GetAray<T, R extends number[] = []> = R['length'] extends T ? R : GetAray<T, [...R, 0]>

type Add<A, B> = B extends number ? [...GetAray<A>, ...GetAray<B>]['length'] : never

type GetSum<T> = T extends [infer Head, ...infer Rest] ? Add<Head, Rest[number]> | GetSum<Rest> : -1

type TwoSum<T extends number[], U extends number> = U extends GetSum<T> ? true : false

Solution by 437204933 #29719

type NumberToTuple<
  T extends number,
  U extends number[] = []
> = U['length'] extends T ? U : NumberToTuple<T, [...U, 1]>;

type SumUnion<T extends number, U extends number, O = U> = U extends O
  ? [...NumberToTuple<T>, ...NumberToTuple<U>]['length']
  : never;

type TwoSum<T extends number[], U extends number> = T extends [
  infer F extends number,
  ...infer R extends number[]
]
  ? U extends SumUnion<F, R[number]>
    ? true
    : TwoSum<R, U>
  : false;

Solution by JohnLi1999 #26082

type Length<Num extends number, Len extends number[] = []>  = 
  Len['length'] extends Num 
    ? Len 
    : Length<Num, [...Len, 1]>;

type Sum<T extends any[], U extends any[]> = [...T, ...U]['length'];

type FindTarget<Num extends number, R extends number[], Target extends number> = 
  R extends [infer First extends number, ...infer Rest extends number[]]
    ? Sum<Length<Num>, Length<First>> extends Target 
      ? true
      : FindTarget<Num, Rest, Target> extends true 
        ? true
        : FindTarget<First, Rest, Target> 
    : false;

type TwoSum<T extends number[], U extends number> = T extends [infer First extends number,  ... infer Rest extends number[]]
  ? FindTarget<First, Rest, U> 
  : false

Solution by JhonLandy #25861

type MakeCounter<T extends number, _Result extends 1[] = [], U = T> =
  U extends T ? _Result[`length`] extends U ? _Result | MakeCounter<Exclude<T, U>> : MakeCounter<U, [..._Result, 1]> : never;
type SimpleAdd<T extends number, U extends number> = [...MakeCounter<T>, ...MakeCounter<U>][`length`];

type TwoSum<T extends number[], U extends number> =
  T extends [infer F extends number, ...infer R extends number[]] ?
  U extends SimpleAdd<F, R[number]> ? true : TwoSum<R, U>
  : false;


// 加法器版本
// /**0~9 */
// type Digit = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
// /**个位 RRRF ==> F */
// type DigitFirst<T extends number | string> = T extends string ?
//   (Number<T> extends Digit ?
//     Number<T> :
//     (T extends `${number}${infer R}` ? DigitFirst<R> : never)) :
//   DigitFirst<`${T}`>;
// /**个位以上 RRRF ==> RRR */
// type DigitRest<T extends number | string, _Result extends string = ``> = T extends string ?
//   (T extends `${infer F}${infer R extends `${any}${any}`}` ?
//     DigitRest<R, `${_Result}${F}`> :
//     _Result) :
//   DigitRest<`${T}`>;
// type MakeCounter<T extends number, _Result extends 1[] = []> = _Result[`length`] extends T ? _Result : MakeCounter<T, [..._Result, 1]>;
// /**个位相加 */
// type DigitAdd<X extends Digit, Y extends Digit> = [...MakeCounter<X>, ...MakeCounter<Y>][`length`] extends (infer N extends number) ? N : 0;
// /**Parse Int */
// type Number<T extends string | number> = T extends `${infer F extends number}` ? F : 0;
// /**+1(进位) */
// type AddOne<T extends number | string, _DigitAdd extends number = DigitAdd<DigitFirst<T>, 1>> = `${_DigitAdd extends // Digit ? DigitRest<T> : /*进位*/AddOne<DigitRest<T>>}${DigitFirst<_DigitAdd>}`;
// /**加法器 */
// type Add<X extends number | string, Y extends number | string, _Result extends string = ``, _DigitAdd extends number = DigitAdd<DigitFirst<X>, DigitFirst<Y>>> =
//   `${X}${Y}` extends `` | `00` ? Number<_Result> :    //return
//   Add<DigitRest<X>, _DigitAdd extends Digit ? DigitRest<Y> : /*进位*/AddOne<DigitRest<Y>>, `${DigitFirst<_DigitAdd>}${_Result}`>;

// type TwoSum<T extends number[], U extends number, _SubStack extends number[] = []> =
//   (T extends [infer F extends number, ...[infer RF extends number, ...infer RR extends number[]]] ?
//     (U extends Add<F, RF> ? true : TwoSum<[F, ...RR], U, [..._SubStack, RF]>)     //TwoSum<[1, 2, 3], 0> ==> 1+2!=0 ==> _SubStack:[2] ==> [1, 3] ==> 1+3!=0 ==> _SubStack:[2, 3] ==> [1] ==>
//     : (_SubStack extends [] ? false/*return*/ : TwoSum<_SubStack, U, []>));       //==>TwoSum<_SubStack:[2, 3], 0, []> ==>  ... ==> [3] && _SubStack:[] ==> false

// type case_deep_pass = TwoSum<[1000, 1000], 2000>;

Solution by E-uler #25041

type NumberToArray<T extends number, Acc extends unknown[] = []> = Acc['length'] extends T
? Acc
: NumberToArray<T, [...Acc, '']>

type TwoSum<T extends unknown[], U extends number> = T extends [infer First extends number, infer Second extends number, ...infer Rest]
? [...NumberToArray<First>, ...NumberToArray<Second>]['length'] extends U
  ? true 
  : TwoSum<[First, ...Rest], U> extends false
    ? TwoSum<[Second, ...Rest], U>
    : true
: false

Solution by NeylonR #24599

type LengToArray<L, E extends number[] = []> = E['length'] extends L ? E : LengToArray<L, [1, ...E]>

type TwoSum<
  T extends number[],
  U extends number,
  C extends number = T[0],
  A extends number[] = T,
  N extends number[] = [],
  B extends boolean = false,
  I extends number[] = []
> 
= B extends true
? true
: T extends [infer F extends number, ...infer R extends number[]]
? TwoSum<R,U,C,
    A,
    I['length'] extends 0 ? [...N] : [...N, F],
    I['length'] extends 0
      ? false
      : I['length'] extends A['length']
      ? false
      : [...LengToArray<C>, ...LengToArray<F>]['length'] extends U
      ? true
      : false,
    [...I, 0]
  >
: A['length'] extends 0
? false
: A['length'] extends 1
? false
: TwoSum<N, U>

Solution by TKBnice #23527

type NumberToUnionArr<T extends number, R extends unknown[] = []> =
  T extends T
    ? R['length'] extends T
      ? R
      : NumberToUnionArr<T, [...R, 0]>
    : never

type SumUnion<
  T extends number[],
  R = never,
> =
  T['length'] extends 0 | 1
    ? R
    : T extends [infer A extends number, ...infer Rest extends number[]]
      ? SumUnion<Rest, R | [...NumberToUnionArr<A>, ...NumberToUnionArr<Rest[number]>]['length']>
      : never

type TwoSum<
  T extends number[],
  U extends number,
> = U extends SumUnion<T> ? true : false

Solution by drylint #22938

type Build<T extends number , Arr extends any[] = []> = Arr['length'] extends T ? Arr : Build<T, [...Arr, 1]>

type ArrayToBuild<T extends number[], Result extends any[] = []> = T extends [infer F extends number, ...infer Rest extends number[]] ? ArrayToBuild<Rest, [...Result, ...Build]> : Result

type PickTwo<T extends number[]> = T extends [infer F, ...infer Rest extends number []] ? Rest extends [infer L , ...infer Last] ? Last extends [] ? [F, L] : [F,L] | PickTwo : Rest extends [] ? never : never :never

type TwoSum<T extends number[], U extends number> = U extends ArrayToBuild<PickTwo>['length'] ? true: false

Solution by amcguire704 #22488

type BuildArray<Len extends number, Arr extends unknown[] = [] > = Arr['length'] extends Len ? Arr : BuildArray<Len, [...Arr, unknown]>
type Sub<A extends number, B extends number> = BuildArray<A> extends [...BuildArray<B>, ...infer Rest] ? Rest['length'] : never
type TwoSum<T extends number[], U extends number, M extends Record<keyof any, true> = {}> =
  T extends [infer F extends number, ...infer R extends number[]]
    ? M[F] extends true
      ? true
      : TwoSum<R, U, { [K in Sub<U, F>]: true } & M>
    : false

Solution by XkSuperCool #22279

// math types
type NTuple<N extends number, C extends unknown[]=[]> = C['length'] extends N ? C : NTuple<N,[...C, 0]>; 
type Add<T extends number, U extends number> = [...NTuple<T>, ...NTuple<U>]['length']; 
// search for sum of T with all of A that results in Comp
type TwoSumSingle<T extends number, A extends number[], Comp extends number> = 
A extends [infer F extends number, ...infer Rest extends number[]] ?
Add<T, F> extends Comp ? true : TwoSumSingle<T, Rest, Comp> : false;

type TwoSum<T extends number[], U extends number> = T extends [infer F extends number, ...infer Rest extends number[]] ? 
TwoSumSingle<F, Rest, U> extends true ? true : TwoSum<Rest, U> : false;

Solution by Karamuto #22222

type Number2Tuple<T extends number, _T extends unknown[] = []> = 
  _T['length'] extends T
  ? _T
  : Number2Tuple<T, [unknown, ..._T]>

type Sum<A extends number, B extends number> = [...Number2Tuple<A>, ...Number2Tuple<B>]['length']

type CanSum<F extends number, T extends number[], U extends number> = 
  T extends [infer First extends number, ...infer Rest extends number[]]
  ? Sum<F, First> extends U
    ? true
    : CanSum<F, Rest, U>
  : false

type TwoSum<T extends number[], U extends number> = 
  T extends [infer First extends number, ...infer Rest extends number[]]
  ? CanSum<First, Rest, U> extends true
    ? true
    : TwoSum<Rest, U>
  : false

playground

Solution by zhaoyao91 #22005

// your answers
type createLenByNum<N,T extends any[] = []> = T['length'] extends N ? T : T extends [...infer Rest] ? createLenByNum<N,[...Rest,1]> : []

type TwoSum<T extends any[], U extends number> = T extends [infer F,infer M,...infer Rest] ? 
[...createLenByNum<F>,...createLenByNum<M>]['length'] extends U ? true : 
TwoSum<[F,...Rest],U> extends false ? TwoSum<[M,...Rest],U> : true
 : false

Solution by YqxLzx #21835

type Build<
  T extends number,
  Result extends Array<never> = []
> = Result["length"] extends T ? Result : Build<T, [...Result, never]>;

type Add<A extends number, B extends number> = [
  ...Build<A>,
  ...Build<B>
]["length"];

type Div<A extends number, B extends number> = Build<A> extends [
  ...Build<B>,
  ...infer C
]
  ? C["length"]
  : Build<B> extends [...Build<A>, ...infer C]
  ? `-${C["length"]}`
  : never;

type TwoSum<
  T extends number[],
  U extends number,
  D extends Array<any> = Build<U>
> = T extends [infer A extends number, ...infer B extends number[]]
  ? D extends [...Build<A>, ...infer G]
    ? G["length"] extends B[number]
      ? true
      : TwoSum<B, U>
    : TwoSum<B, U>
  : false;

Solution by so11y #21300

// Iterate over T 
// -> If current element CURR > TARGET and TARGET - CURR exists in the remainder of T, return true.
// -> Else, recursively call TwoSum over remainder of T.
// -> If iteration is completed, return false.
type TwoSum<
  T extends number[], 
  TARGET extends number,
  CURR extends number = T[0],
  NEXT extends number[] = Shift<T>,
  RESULT extends boolean = T extends [] ? false
    : LessThan<TARGET, CURR> extends true ? TwoSum<NEXT, TARGET>
    : Subtract<TARGET, CURR> extends NEXT[number] ? true
      : TwoSum<NEXT, TARGET>
> = RESULT;
/** Helpers */
// new Array(N).fill(T)
type Repeat<N extends number, T extends any = null, M extends T[] = []> = 
  M["length"] extends N ? M : Repeat<N, T, [T, ...M]>;

// If A >= B, return A - B. Else, return never.
type Subtract<A extends number, B extends number> = 
  Repeat<A> extends [...Repeat<B>, ...infer Rest] 
    ? Rest["length"]
    : never;

type LessThan<T extends number, U extends number> = 
  Equal<T, U> extends true ? false
    : Subtract<T, U> extends never ? true : false;

type Shift<T extends any[], N extends number = 1> = 
  N extends 0 ? T 
    : T extends [infer _, ...infer Rest]
      ? Shift<Rest, Subtract<N, 1>>
      : [];
type TwoSumNewTests = [
  // The following incorrect solution passes all other test cases:
  // ... ? Subtract<U, E> extends never
  //       ? false ...
  Expect<Equal<TwoSum<[3, 2, 0], 2>, true>>
];

type SubtractTests = [
  Expect<Equal<Subtract<0, 0>, 0>>,
  Expect<Equal<Subtract<1, 0>, 1>>,
  Expect<Equal<Subtract<2, 1>, 1>>,
  Expect<Equal<Subtract<1, 2>, never>>,
];

type RepeatTests = [
  Expect<Equal<Repeat<0>, []>>,
  Expect<Equal<Repeat<3>, [null, null, null]>>,
  Expect<Equal<Repeat<3, "1">, ["1", "1", "1"]>>,  
];

Solution by MajorLift #21260

type Length<T extends any[]> = T extends { length: infer L } ? L : never;
type Tuple<L extends number, T extends any[] = []> = T extends { length: L } ? T : Tuple<L, [...T, any]>;

type Sum<A extends number, B extends number> = Length<[...Tuple<A>, ...Tuple<B>]>;

type OneSum<T extends number[], C extends number, U extends number> = T extends [infer H extends number, ...infer R extends number[]] ?
  Equal<Sum<H, C>, U> extends true ? true : OneSum<R, C, U>
  : false;


type TwoSum<T extends number[], U extends number> = T extends [infer C extends number, ...infer R extends number[]] ?
    OneSum<R, C, U> extends true ? true :
    TwoSum<R, U> 
  : false;

Solution by cezarguimaraes #21055

type ArrayWithLength<
  T extends string | number,
  R extends unknown[] = []
> = `${R['length']}` extends `${T}` ? R : ArrayWithLength<T, [unknown, ...R]>

type Sum<T1 extends unknown, T2 extends unknown> = T1 extends number
  ? T2 extends number
    ? [...ArrayWithLength<T1>, ...ArrayWithLength<T2>]['length']
    : never
  : never

type TwoSum<T extends unknown[], U extends unknown> = T extends [
  infer A,
  ...infer B
]
  ? U extends Sum<A, B[number]>
    ? true
    : TwoSum<B, U>
  : false

Solution by theoolee #19752

type NumberToArray<N, Result extends any[] = []> = Result['length'] extends N ? Result : NumberToArray<N, [...Result, 1]>;

type AddMethod<F extends number, Rest extends number[], U extends number> = Rest extends [infer F1, ...infer R extends number[]]
  ? [...NumberToArray<F>, ...NumberToArray<F1>]['length'] extends U
    ? true
    : AddMethod<F, R, U>
  : false;

type TwoSum<T extends number[], U extends number> = 
T extends [infer F extends number, ...infer R extends number[]] 
? (AddMethod<F, R, U> extends false ? TwoSum<R, U> : true) 
: false;

Solution by CaoXueLiang #19510

// your answers
type NumToTuple<T extends number, Result extends unknown[] = []> = Result['length'] extends T
                                                                        ? Result
                                                                        : NumToTuple<T, [...Result, unknown]>;

type Sum<T extends number, R extends number> = [...NumToTuple<T>, ...NumToTuple<R>]['length'];

type GetSumList<L extends number[], Num extends number, Result extends number[] = []> = L extends [infer R, ...infer U extends number[]]
                                                                    ? R extends number ? GetSumList<U, Num, [...Result, Sum<R, Num> & number]> : never
                                                                    : Result

type SumList<L extends number[], Result extends number[] = []> = L extends [infer R extends number, ...infer U extends number[]]
                                                                ? SumList<U, [...Result, ...GetSumList<U, R>]>
                                                                : Result;
                                                                
type TwoSum<T extends number[], U extends number> = U extends SumList<T>[number] ? true : false;

Solution by jiaaoMario #18266

type Encode<X extends number, R extends unknown[] = []> = R['length'] extends X ? R : Code<X, [...R, unknown]>;

type Add<X extends number, Y> = Y extends any ? [...Encode<X>, ...Encode<Y>]['length'] : never;
// assumes X is a single number, Y can be unions like 3|4|5

type PickAdd<T extends number[]> = T extends [infer Head extends number, ...infer Tail extends number[]]
   ? Add<Head, Tail[number]> | PickAdd<Tail>
   : never;
// pick a table entry and ADD<> to the other entries of the array

type TwoSum<T extends number[], U extends number> = U extends PickAdd<T> ? true : false;
// convert result to required boolean

Solution by alexfung888 #17957