🔴 문제
프로그래머스 링크: https://school.programmers.co.kr/learn/courses/30/lessons/70128
문제 설명
길이가 같은 두 1차원 정수 배열 a, b가 매개변수로 주어집니다. a와 b의 내적을 return 하도록 solution 함수를 완성해주세요.
이때, a와 b의 내적은 a[0]*b[0] + a[1]*b[1] + ... + a[n-1]*b[n-1] 입니다. (n은 a, b의 길이)
제한사항
a, b의 길이는 1 이상 1,000 이하입니다.a, b의 모든 수는 -1,000 이상 1,000 이하입니다.
입출력 예
a b result [1,2,3,4] [-3,-1,0,2] 3 [-1,0,1] [1,0,-1] -2
🔵 풀이 - zip(_:_:), map(_:), reduce(_:_:)
문제를 보자마자 < #26. 음양 더하기 > 에서 처음 접했던 zip(_:_:) 함수가 떠올랐다.
zip 함수로 a, b를 쌍으로 만든 후, 같은 인덱스끼리 곱하여 합으로 반환해야 하므로, reduce 클로저를 활용해야겠다고 생각했다.
(zip 키워드가 기억이 안 나서 헤매긴 했지만 결국 찾아냈다.)
▶️ 링크: 2024.02.19 - [Swift/Code Kata (알고리즘)] - [Swift|코드카타] (프로그래머스) 입문 #26. 음양 더하기 -시퀀스 쌍 만드는 zip(_:_:)
▶️ 문제 발생 및 해결
reduce를 다양한 방식으로 사용할 수 있지만,
일단 reduce의 기본 구조는 다음과 같이 두 개의 인자가 필요하다.
- $0 : 은 더할 값, 즉 배열의 인덱스 값.
- $1 : $0이 더해진 현재의 누적값
배열.reduce(초깃값, { 더할 값 $0 연산자 누적값 $1 })
만약, 배열 대신 zip 시퀀스 쌍에 reduce를 붙인다면 어떻게 될까?
나는 reduce 클로저가 다음과 같이 두 개의 배열을 연산한 합을 반환할 줄 알았다...
- $0 : 첫 번재 배열의 인덱스 값
- $1 : 두 번째 배열의 인덱스 값
그래서 zip(a,b).reduce(0, {$0 * $1}) 라고 했더니....
오류가 난다 ^0^
reduce는 단일 시퀀스에만 사용할 수 있는 것 같다ㅜㅜ
따라서 예전 알고리즘을 참고하여 'map'을 활용하면 된다는 힌트를 얻고 코드를 수정했다.
▶️ 최종 코드
import Foundation
func solution(_ a:[Int], _ b:[Int]) -> Int {
return zip(a,b)
.map {$0 * $1}
.reduce(0, {$0 + $1})
}
🔵 코드 줄이기 - 매개변수 식별자($0, $1) 생략
다른 사람 코드를 보니, map을 'map(*)'로 작성한 경우가 있었다.
map도 reduce처럼 매개변수 식별자($0, $1)를 생략할 수 있음을 새롭게 알게 되었다.
코드>
import Foundation
func solution(_ a:[Int], _ b:[Int]) -> Int {
return zip(a, b).map(*).reduce(0, +)
}
😊 느낀점
분명히 사용해본 적이 있는 함수임에도, 꾸준히 안 쓰다보면 잊어버린다는 것을 오늘 느꼈다.
일주일에 한 번이라도 복습하는 시간을 가져야겠다.