카테고리 없음

4518. Fill

최토피 2023. 8. 11. 12:41
728x90

문제

Fill, a common JavaScript function, now let us implement it with types. Fill<T, N, Start?, End?>, as you can see,Fill accepts four types of parameters, of which T and N are required parameters, and Start and End are optional parameters. The requirements for these parameters are: T must be a tupleN can be any type of value, Start and End must be integers greater than or equal to 0.

type exp = Fill<[1, 2, 3], 0> // expected to be [0, 0, 0]

cases

type cases = [
  Expect<Equal<Fill<[], 0>, []>>,
  Expect<Equal<Fill<[], 0, 0, 3>, []>>,
  Expect<Equal<Fill<[1, 2, 3], 0, 0, 0>, [1, 2, 3]>>,
  Expect<Equal<Fill<[1, 2, 3], 0, 2, 2>, [1, 2, 3]>>,
  Expect<Equal<Fill<[1, 2, 3], 0>, [0, 0, 0]>>,
  Expect<Equal<Fill<[1, 2, 3], true>, [true, true, true]>>,
  Expect<Equal<Fill<[1, 2, 3], true, 0, 1>, [true, 2, 3]>>,
  Expect<Equal<Fill<[1, 2, 3], true, 1, 3>, [1, true, true]>>,
  Expect<Equal<Fill<[1, 2, 3], true, 10, 0>, [1, 2, 3]>>,
  Expect<Equal<Fill<[1, 2, 3], true, 0, 10>, [true, true, true]>>,
]

문제 링크

풀이

조건

  1. TN으로 채운다.
  1. Start가 있는 경우는 Start 지점 부터 N으로 채운다.
  1. End가 있는 경우는 End 지점 직전까지 N으로 채운다.

정답

 

type Fill<
    T extends unknown[],
    N,
    Start extends number = 0,
    End extends number = T['length'],
    Started extends boolean = false,
    Pointer extends unknown[] = [],
> = Pointer['length'] extends End
  ? T
  : T extends [infer T1, ...infer Rest]
    ? Started extends true
      ? [N, ...Fill<Rest, N, Start, End, Started, [...Pointer, 0]>]
      : Pointer['length'] extends Start
        ? [N, ...Fill<Rest, N, Start, End, true, [...Pointer, 0]>]
        : [T1, ...Fill<Rest, N, Start, End, false, [...Pointer, 0]>]
    : T

해설

TN으로 바꾸는 로직을 추가한다.

type Fill<T extends unknown[], N> = 
	T extends [unknown, ...infer Rest]
		? [N, ...Fill<Rest, N>]
		: T

Start 이전에는 유지, Start 후에는 N으로 바꾸는 로직을 추가한다. 이를 위해 현재 진행중인 위치를 표기할 Point와 이전 상태를 기억할 Started를 추가한다.

type Fill<
    T extends unknown[],
    N,
    Start extends number = 0,
    Started extends boolean = false,
    Pointer extends unknown[] = [],
> = T extends [infer T1, ...infer Rest]
		? Started extends true
      ? [N, ...Fill<Rest, N, Start, End, Started, [...Pointer, 0]>]
      : Pointer['length'] extends Start
        ? [N, ...Fill<Rest, N, Start, End, true, [...Pointer, 0]>]
        : [T1, ...Fill<Rest, N, Start, End, false, [...Pointer, 0]>]
    : T

End 이전까지만 N으로 바꾸는 로직을 추가한다.

type Fill<
    T extends unknown[],
    N,
    Start extends number = 0,
    End extends number = T['length'],
    Started extends boolean = false,
    Pointer extends unknown[] = [],
> = Pointer['length'] extends End
  ? T
  : T extends [infer T1, ...infer Rest]
    ? Started extends true
      ? [N, ...Fill<Rest, N, Start, End, Started, [...Pointer, 0]>]
      : Pointer['length'] extends Start
        ? [N, ...Fill<Rest, N, Start, End, true, [...Pointer, 0]>]
        : [T1, ...Fill<Rest, N, Start, End, false, [...Pointer, 0]>]
    : T

리팩토링

Started를 수정해서, 코드를 조금 개선할 수 있다.

type Fill<
    T extends unknown[],
    N,
    Start extends number = 0,
    End extends number = T['length'],
    Pointer extends unknown[] = [],
    Started extends boolean = Pointer['length'] extends Start ? true : false,
> = Pointer['length'] extends End
  ? T
  : T extends [infer T1, ...infer Rest]
    ? Started extends true
      ? [N, ...Fill<Rest, N, Start, End, [...Pointer, 0], Started>]
      : [T1, ...Fill<Rest, N, Start, End, [...Pointer, 0]>]
    : T

혹시 오류나 개선점에 대한 피드백이 있으시면 언제든 댓글 부탁드립니다.

728x90