FE/type-challenge
25270. Transpose
최토피
2023. 10. 13. 12:32
728x90
문제
The transpose of a matrix is an operator which flips a matrix over its diagonal; that is, it switches the row and column indices of the matrix A by producing another matrix, often denoted by A<sup>T</sup>.
type Matrix = Transpose <[[1]]>; // expected to be [[1]]
type Matrix1 = Transpose <[[1, 2], [3, 4]]>; // expected to be [[1, 3], [2, 4]]
type Matrix2 = Transpose <[[1, 2, 3], [4, 5, 6]]>; // expected to be [[1, 4], [2, 5], [3, 6]]
cases
type cases = [
Expect<Equal<Transpose<[]>, []>>,
Expect<Equal<Transpose<[[1]]>, [[1]]>>,
Expect<Equal<Transpose<[[1, 2]]>, [[1], [2]]>>,
Expect<Equal<Transpose<[[1, 2], [3, 4]]>, [[1, 3], [2, 4]]>>,
Expect<Equal<Transpose<[[1, 2, 3], [4, 5, 6]]>, [[1, 4], [2, 5], [3, 6]]>>,
Expect<Equal<Transpose<[[1, 4], [2, 5], [3, 6]]>, [[1, 2, 3], [4, 5, 6]]>>,
Expect<Equal<Transpose<[[1, 2, 3], [4, 5, 6], [7, 8, 9]]>, [[1, 4, 7], [2, 5, 8], [3, 6, 9]]>>,
]
정답
type Transpose<M extends number[][], R extends number[][] = []> =
M extends [] ? [] :
M[0]['length'] extends R['length']
? R
: Transpose<M, [...R, GetColumn<M, R['length']>]>
type GetColumn<M extends number[][], I extends number, R extends number[]=[]> =
R['length'] extends M['length'] ? R
: GetColumn<M, I, [...R, M[R['length']][I]]>
풀이
조건
- 2차원 행열에서 모든 column 값을 출력한다.
- 빈 배열이라면 빈배열을 출력한다.
해설
앞에서 순차적으로 돌아서 해당 열의 값을 가져오는 Transpose
를 작성한다.
type Transpose<M extends number[][], R extends number[][] = []> =
M[0]['length'] extends R['length']
? R
: Transpose<M, [...R, GetColumn<M, R['length']>]>
이 함수는 재귀적으로 수행하여, 앞에서부터 열을 생성한다.
GetColumn
은 해당 열의 배열을 생성하는 타입이다. 내부는 다음과 같다.
type GetColumn<M extends number[][], I extends number, R extends number[]=[]> =
R['length'] extends M['length'] ? R
: GetColumn<M, I, [...R, M[R['length']][I]]>
이 두 가지 타입을 조합한 후 조건 2번을 예외처리하면 다음과 같다.
type Transpose<M extends number[][], R extends number[][] = []> =
M extends [] ? [] :
M[0]['length'] extends R['length']
? R
: Transpose<M, [...R, GetColumn<M, R['length']>]>
type GetColumn<M extends number[][], I extends number, R extends number[]=[]> =
R['length'] extends M['length'] ? R
: GetColumn<M, I, [...R, M[R['length']][I]]>
혹시 오류나 개선점이 있다면 댓글 부탁드립니다.
728x90