알고리즘/풀이

[프로그래머스] 행렬의 곱셈 파이썬

목표는 커리 2023. 4. 1. 14:32
728x90
SMALL

문제 설명

2차원 행렬 arr1과 arr2를 입력받아, arr1에 arr2를 곱한 결과를 반환하는 함수, solution을 완성해주세요.

제한 조건
  • 행렬 arr1, arr2의 행과 열의 길이는 2 이상 100 이하입니다.
  • 행렬 arr1, arr2의 원소는 -10 이상 20 이하인 자연수입니다.
  • 곱할 수 있는 배열만 주어집니다.
입출력 예
arr1 arr2 return
[[1, 4], [3, 2], [4, 1]] [[3, 3], [3, 3]] [[15, 15], [15, 15], [15, 15]]
[[2, 3, 2], [4, 2, 4], [3, 1, 4]] [[5, 4, 3], [2, 4, 1], [3, 1, 1]] [[22, 22, 11], [36, 28, 18], [29, 20, 14]]

제출 답안

행렬의 곱셈

  1. mxk , kxn이어야 곱셈이 가능하다.
    1. 그러면 mxn형태의 최종 결과 행렬이 탄생한다.
  2. 먼저 mn을 구해서 answer를 최종 결과 형태의 행렬로 만든다.
  3. arr1부터 for loop를 시작한다.
  4. 그 다음엔 arr2의 행렬이 돌면서 열에 먼저 접근해야 한다.
    1. 그래서 map함수를 사용하여 0 번째 열부터 리스트로 만들었다.
  5. 그렇게 구한 2개의 리스트를 zip으로 한 번에 값으로 받아서 곱하고 합하여 answer에 다시 대입하였다.
  6. 문제를 풀다가 보니 3번의 for loop를 만들어야 할 것 같아 피하기 위해 a2리스트를 다시 만든것이다.
def solution(arr1, arr2):
    m, n = len(arr1), len(arr2[0])
    answer = [[0] * n for _ in range(m)]
    for i,val in enumerate(arr1):
        for j in range(n):
            a2 = list(map(lambda x:x[j], arr2))
            answer[i][j] = sum(x * y for x, y in zip(val, a2))
    return answer

문제 풀이보고 찾은 더 좋은 방법

  • 위에서 a2대신 zip으로 한 것처럼 *arr2를 하여 리스트를 각각의 리스트로 만들면 0번째 열부터 가져올 수 있다.
  • 그 값을 바로 대입하면 훨씬 쉽다.
  • 예를 들어 *arr1을 하면 [1,4] [3,2] [4,1]이 각각 따로 리스트가 되고 zip을 하면 [1,3,4] , [4,2,1]이 넘어오게 된다.
  • 그러니 *arr2도 그렇게 하면 [3,3] [3,3]이 a2에 대입되는 것이다.
def solution(arr1, arr2):
    m, n = len(arr1), len(arr2[0])
    answer = [[0] * n for _ in range(m)]
    for i,a1 in enumerate(arr1):
        for j, a2 in enumerate(zip(*arr2)):
            answer[i][j] = sum(x * y for x, y in zip(a1, a2))
    return answer
728x90
LIST