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]]>

풀이

조건

  1. 2차원 행열에서 모든 column 값을 출력한다.
  1. 빈 배열이라면 빈배열을 출력한다.

해설

앞에서 순차적으로 돌아서 해당 열의 값을 가져오는 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