[프로그래머스 2레벨] 행렬의 곱셈

이민선(Jasmine)·2023년 2월 7일
0

문제

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

나의 코드

function solution(arr1, arr2) {
    const [row, col] = [arr1.length, arr2[0].length];
    const base = [...Array(row)].map(v=> [...Array(col)]);
    return base.map((row,i,base)=> row.map((v,j,row) => {
       return arr2.reduce((el,_,idx,arr2)=> {
         el+=arr1[i][idx] * arr2[idx][j];
           return el;
        },0)
    }))
}

행렬 곱셈의 결과는 앞의 행렬의 행과 뒤 행열의 열만큼의 크기의 행렬이 된다!! 즉 앞의 행렬의 열 개수와 뒤 행렬의 행의 개수가 같아야만 행렬 곱셈이 가능하다.
초보자답게 행과 열 숫자부터 맞춰줘야 마음이 편하기 때문에, 행과 열의 길이부터 각각 선언한다. [row, col]
그리고 해당 row * col 크기인 null로 가득 채워진 빈 행렬을 정의한다.
그리고 이중 map의 index를 활용하여 row * col 행렬의 null값들을 채워나간다.
이중 map에서 i는 행번호, j는 열번호를 의미하게 된다.
그리고 arr1이 아닌 arr2에 reduce를 적용한 이유는 arr2의 행 개수(= arr1의 열 개수)만큼 순회하며 누산기에 각 원소들의 곱셈을 더해나가야 하기 때문이다.
여기서 idx를 지정하는 부분이 많이 헷갈렸었다. (사실 그냥 다 헷갈리는 거 아닐까)
우리는 arr2를 순회하고 있다는 사실을 잊지 말아야 한다! reduce를 사용하면 arr2의 원소 개수만큼(arr의 행 개수만큼) 순회한다. 즉, arr1의 행 번호와 arr2의 열번호가 고정인 상태에서 각 원소의 곱셈 값을 누산하기 위해 idx를 사용할 수 있는 것이다.

후하후하 헷갈렸지만 풀어내니 뿌듯하다 !

그런데.. 이거 한 줄로 가능한 거였다.ㅋㅋㅋㅋㅋ

다른 코드

function solution(arr1, arr2) {
    return arr1.map((row) => arr2[0].map((x,y) => row.reduce((a,b,c) => a + b * arr2[c][y], 0)))
}

결과적으로 나오는 행렬의 행의 개수는 arr1의 원소개수(=행의 개수)와 동일할 것이다. 따라서 arr1에 map을 걸어주는게 직관적, 논리적으로 와닿는다.
그리고 저저..arr2[0]..저거는 무엇인고(여기서 한참 헤맴)
헤매다가 뒷 부분을 보니 x는 사용하지 않고 y만 사용함을 알 수 있었다.
그래 우리는 y가 필요한거야!!!
y는 arr2에서의 현재 열번호를 나타낸다.
그리고 arr1의 row에 reduce를 걸었기 때문에 arr1의 열의 개수이자 arr2의 행의 개수만큼 순회하게 된다. c는 arr1의 행과 arr2의 열이 고정인 상태에서 순회할 때의 arr1의 열번호와 arr2의 행번호를 가리키게 된다.
각각의 y에 대해서 reduce로 한번 순회하게 되면 결과 행렬의 원소 하나가 뚝딱 완성!

이해한 것 같지만 내일 보면 또 헷갈릴 것 같다 ㅠㅠ 다행히도 내일 제코베에서 행렬 곱셈을 한번 더 연습할 예정! 행렬 곱셈이랑 친해지기는 내일도 to be continued..⭐️

profile
기록에 진심인 개발자 🌿

0개의 댓글