문제가 좀 길어서 파악하기 힘들었지만 결국 문제의 본질은 주어진 discount 배열에서 연속된 10개의 상품이 want와 number에 주어진 상품의 종류와 갯수와 일치하는 것인지 묻는 것입니다.
파이썬에서는 counter라는 내장 함수가 있는데요. 이 메소드는 배열의 어떤 원소가 몇개 있는지 dict 형태로 반환해주는 메소드입니다. 아쉽게도 스위프트에는 존재하지 않으므로 직접 구현해서 풀어보겠습니다.
discount를 연속해서 10개의 배열로 나눈 다음에 counter함수를 통해 dict 형태로 물건-갯수의 형태로 정리합니다. 그리고 want와 number를 통해 구한 dict와 일치하는지 비교해서 같은 dict의 갯수를 세주면 됩니다.
func solution(_ want:[String], _ number:[Int], _ discount:[String]) -> Int {
// discount에서 연속된 10개의 상품을 dict의 형태로 리턴하는 함수
func counter(_ array: ArraySlice<String>) -> [String:Int] {
var dict = [String:Int]()
for item in array {
dict[item, default: 0] += 1
}
return dict
}
// want와 number로 dict 구하기
var dict = [String:Int]()
for i in 0..<want.count {
dict[want[i]] = number[i]
}
// 회원가입할 수 있는 날짜 수
var ans = 0
for i in 0..<(discount.count - 10 + 1) {
var slice = discount[i..<i + 10]
var sliceDict = counter(slice)
if dict == sliceDict { ans += 1 } //👉 일치하면 +1
}
return ans
}
위에서 구현한 counter 함수를 보면서 ArraySlice에 대한 주의사항을 한번 체크해보고 가도록 하겠습니다. 일단 discount[i..<i + 10] 형태로 구한 배열은 Array 자료형이 아니라 ArraySlice라는 별도의 자료형입니다. 따라서 인자의 타입도 ArraySlice로 정의해주어야 합니다.
또한 반복문을 사용할 때 주의해야 합니다. 정확히 말하면 반복문에서 index를 사용하는 경우입니다. 아래의 경우 그냥 array 안의 원소를 하나하나 순환하도록 했지만 index를 사용하는 경우에는 에러가 발생합니다. 그 원인은 ArraySlice의 index는 ArraySlice 자체의 index가 아니라 자기의 원본인 Array의 index를 의미하기 때문입니다.
만약에 [0, 1, 2, 3, 4]의 Array에서 만들어진 [1, 2, 3] ArraySlice를 예시로 들어보겠습니다. ArraySlice의 “1”의 index는 0이라고 생각하기 쉽지만 실제로는 원본은 Array의 index인 1입니다. 따라서 ArraySlice에서 index는 조심해서 사용해야 합니다.
// discount에서 연속된 10개의 상품을 dict의 형태로 리턴하는 함수
func counter(_ array: ArraySlice<String>) -> [String:Int] {
//👉 ArraySlice를 인자로 받아야 한다.
var dict = [String:Int]()
for item in array { //👉 ArraySlice의 반복문에서는 index를 사용하지 않는 것이 좋다.
dict[item, default: 0] += 1
}
return dict
}