코딩,해볼까

08.16. 프로그래머스 : 행렬의 곱셈 본문

Back/TIL

08.16. 프로그래머스 : 행렬의 곱셈

떠굥 2023. 8. 16. 02:03

🔎행렬의 곱셈

2차원 그래프를 입력받아, 곱한 결과를 구하라.

행렬이란?
https://mathbang.net/562#gsc.tab=0

https://www.youtube.com/watch?v=JpSe38UHaos

💡 문제풀이#1

행을 위한 for, 열을 위한 for 이렇게 2개의 for 문이 필요하다고 생각되어 식을 만들었다. 하지만 행과 열이 항상 같은 숫자가 아니기 때문에, out of range 오류가 계속해서 났다.  arr2[ar2][ar1] 

def solution(arr1, arr2):
    answer = [[]]
    num = 0
    # case2

    if len(arr1) >= len(arr2):
        arr1.append(arr1[-1])
    else:
        arr2.append(arr2[-1])

    for ar1 in range(len(arr1)):  # 행
        num = 0
        for ar2 in range(len(arr2)):  # 열
            num += arr1[ar1][ar2] * arr2[ar2][ar1]
        answer.append(num)
    return answer

💡 문제풀이#2

행과 열에 정확한 숫자가 들어가야 하는 것이 포인트!

테스트케이스들을 가지고 행렬의 위치를 나타내봤다. 

# 테스트케이스 1
arr1 = [[1, 4], [3, 2], [4, 1]]
arr2 = [[3, 3], [3, 3]]

    0 1
   ㅡ ㅡ
0 | 1 4 
1 | 3 2 
2 | 4 1

    0 1
   ㅡ ㅡ
0 | 3 3
1 | 3 3


(행)*(열)
(0,0)*(0,0) + (0,1)*(1,0) | (0,0)*(0,1) + (0,1)*(1,1)
(1,0)*(0,0) + (1,1)*(1,0) | (1,0)*(0,1) + (1,1)*(1,1)
(2,0)*(0,0) + (2,1)*(1,0) | (2,0)*(0,1) + (2,1)*(1,1)

# 답은 2행 3열 이다.

'''
for (1) 줄별로 바뀌는 0 1 2 # arr1 열
    for (2) | 를 기점으로 0 1 # arr1 행(2번째 arr의 행)
        for (3) + 를 기점으로 0 1 # arr2 행(1번째 arr의 행)
'''

 

# 테스트케이스 2
arr1 = [[2, 3, 2], [4, 2, 4], [3, 1, 4]]
arr2 = [[5, 4, 3], [2, 4, 1], [3, 1, 1]]

    0 1 2
   ㅡ ㅡ ㅡ
0 | 2 3 2
1 | 4 2 4
2 | 3 1 4


    0 1 2
  ㅡ ㅡ ㅡ
0 | 5 4 3
1 | 2 4 1
2 | 3 1 1


(0,0)(0,0) (0,1)(1,0) (0,2)(2,0) | (0,0)(0,1) (0,1)(1,1) (0,2)(2,1) | (0,0)(0,2) (0,1)(1,2) (0,2)(2,2)
(1,0)(0,0) (1,1)(1,0) (1,2)(2,0) | (1,0)(0,1) (1,1)(1,1) (1,2)(2,1) | (1,0)(0,2) (1,1)(1,2) (1,2)(2,2)
(2,0)(0,0) (2,1)(1,0) (2,2)(2,0) | (2,0)(0,1) (2,1)(1,1) (2,2)(2,1) | (2,0)(0,2) (2,1)(1,2) (2,2)(2,2)

for문은 3개가 있어야 한다는 것을 깨달았다. 또한 각각의 range가 무엇을 뜻하는지도 아주 중요하다. 처음에는 이렇게 나타냈으며 테스트케이스는 통과하지만 제출 시 테스트를 하나도 통과하지 못하는 이상한 코드가 되었다.

    for row in range(len(arr1)):
        arr = []
        for row2 in range(len(arr2)):
            num = 0  
            for column in range(len(arr2)):
                num += arr1[row][column] * arr2[column][row2]
            arr.append(num)   
        answer.append(arr)

range의 수를 정확하게 파악하기 위해서는 답이 몇 행 몇 열인지 예상할 수 있어야 한다.
(풀이를 진행하면서 행렬은 정답의 모양을 미리 알고 있는 것이 아주 중요한 포인트였다..!!)
테스트 케이스는 통과를 했지만 채점 시 문제 실행에 실패했다.

💡 문제풀이#3

테스트케이스 1 : 2행 3열 | 테스트케이스2 : 3행 3열

range에 들어가는 숫자를 행과 열에 맞게 수정하였다.

def solution(arr1, arr2):
    answer = []
    for column in range(len(arr1)):
        arr = []
        for row2 in range(len(arr2[0])):
            num = 0  
            for row in range(len(arr1[0])):
                num += arr1[column][row] * arr2[row][row2]
            arr.append(num)   
        answer.append(arr)
    return answer

💡 배운 점

1. 한줄코딩

팀원분의 친절한 한줄코딩 방법 설명!

def solution(arr1, arr2):
    return [[sum(a*b for a, b in zip(A_row,B_col)) for B_col in zip(*arr2)] for A_row in arr1]

2. numpy 활용

장점 : 큰 데이터를 다룰 때 효율적이다.

단점 : numpy 자체가 크기 때문에 import 할 때 부담스러울 수 있다.

import numpy as np

def solution(arr1, arr2):
    return np.dot(np.array(arr1), np.array(arr2)).tolist()
Comments