반응형
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- Nestjs
- Crawling
- TCP
- 자바스크립트
- typescript
- 타입스크립트
- type challenge
- 문자열
- 크롤링
- javascript
- 그래프
- 프로그래머스
- Algorithm
- 쉬운 문제
- HTTP
- 알고리즘
- dp
- 프로그래머스 레벨 2
- ip
- dfs
- socket
- HTTP 완벽 가이드
- Node.js
- 레벨 1
- 소켓
- BFS
- 백준
- 가천대
- 수학
- 타입 챌린지
Archives
- Today
- Total
kakasoo
[Type-Challenge] 04518-medium-fill 본문
반응형
type Length<T extends any[]> = T['length'];
type Push<T extends any[], P> = [...T, P];
type NTuple<N extends number, T extends any[] = []> = Length<T> extends N ? T : NTuple<N, Push<T, any>>;
type Add<N1 extends number, N2 extends number> = Length<[...NTuple<N1>, ...NTuple<N2>]>;
이렇게 4개는 타입 챌린지를 풀다 보면 많이들 쓰게 되는 타입들이다.
- Length는 사실 제네릭 T[’length’]의 접근을 축약한 것이기 때문에 크게 어렵지 않을 것이다.
- Push는 Tuple T를 받아 P를 담은 새 튜플로 추론되는 타입이다.
- NTuple은 튜플 T가 N만큼의 크기가 될 때까지 재귀적으로 Push하는 타입이다.
- Add는 N1, N2를 그 크기만큼의 튜플로 만든 다음, 그 튜플을 합쳐 다시 Length를 구하는 방식으로 두 수의 합을 구하는 타입이다.
이 네 가지 타입이 자주 쓰이는 것은, 그만큼 타입챌린지에 튜플을 이용한 타입 문제가 많이 나오기 때문일 것이다.
// N1이 큰 경우에만 true
type IsBiggerOrEqual<N1 extends number, N2 extends number> = NTuple<N1> extends [...NTuple<N2>, ...any[]] ? true : false;
type IsBigger<N1 extends number, N2 extends number> = IsBiggerOrEqual<N1, N2> extends true ? N1 extends N2 ? false : true : false;
Fill 문제를 풀기 위해서는 현재 인덱스가 문제에 주어진 Start 이상 End 미만인지를 검증할 필요가 있다.
따라서 이상, 미만을 체크하기 위해 두 가지 타입을 만든다.
IsBiggerOrEqual은 이름만큼이나 직관적인 타입인데 N1, N2 튜플이 있다고 할 때,
N1 튜플이 N2 튜플과 몇 개 요소가 더해진 것과 동일한 튜플인지 비교하는 타입이다. ( = any로만 이루어진 튜플이기 때문에 가능하다 )
IsBigger 타입은 'N1이 N2보다 크거나 같은' 상황에서 '값이 같은' 경우를 제외하여 오로지 큰 경우만 남기는 타입이다.
이로써 인덱스를 비교할 준비는 되었다.
// 두 값 사이에 속한 경우에만 true (TargetNumber가 Minimum 이상, Maximum 미만인 경우)
type Between<TargetNumber extends number, Minimum extends number, Maximum extends number> =
IsBiggerOrEqual<TargetNumber, Minimum> extends true
? IsBigger<Maximum, TargetNumber> extends true
? true
: false
: false
마지막으로 Between 타입을 구현한다.
Between 타입이 true로 추론되는 경우는 타겟이 되는 숫자가 Minimum 이상이고, Maximum보다는 미만인 경우이다.
이제 TargetNumber의 위치로 인덱스를 주기만 하면 된다.
type ToNumber<T> = T extends number ? T : never;
type Fill<
T extends unknown[],
N,
Start extends number = 0,
End extends number = T['length'],
CurrentIndex extends number = 0
> = T extends [infer First, ...infer Rest]
? Between<CurrentIndex, Start, End> extends true
? [N, ...Fill<Rest, N, Start, End, ToNumber<Add<CurrentIndex, 1>>>]
: [First, ...Fill<Rest, N, Start, End, ToNumber<Add<CurrentIndex, 1>>>]
: []
따라서 Fill 타입은 위처럼 구현한다.
T가 First와 나머지 배열로 이루어진 배열이라고 가정할 때, CurrentIndex가 Start, End 사이이면 N으로 바꾸고 아니면 그대로 한다.
이를 재귀적으로 돌면서 계속 반복하는 것이다.
반응형
'프로그래밍 > TypeScript' 카테고리의 다른 글
[Type-Challenge] 04518-medium-fill, 더 좋은 풀이법 (0) | 2024.03.24 |
---|---|
FindAll 특정 문자열이 나오는 인덱스를 검색하는 타입 (0) | 2024.03.23 |
달과 일자로 이루어진 MMDD 타입 (0) | 2024.03.17 |
튜플의 가운데 요소들을 가져오는 타입 (0) | 2024.02.10 |
Currying, 인자를 커링으로 변경하는 타입 (1) | 2023.12.03 |