카테고리 없음
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 tuple
, N
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]>>,
]
풀이
조건
T
를N
으로 채운다.
Start
가 있는 경우는Start
지점 부터N
으로 채운다.
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
해설
T
를 N
으로 바꾸는 로직을 추가한다.
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