문제 링크
코딩테스트 연습 - 신고 결과 받기
문제
이용자의 ID가 담긴 문자열 배열 id_list,
각 이용자가 신고한 이용자의 ID 정보가 담긴 문자열 배열 report,
정지 기준이 되는 신고 횟수 k가 매개변수로 주어질 때,
각 유저별로 처리 결과 메일을 받은 횟수를 배열에 담아 return 하도록 solution 함수를 완성해주세요.
입력
let id_list = ["muzi", "frodo", "apeach", "neo"]
let report = ["muzi frodo", "muzi frodo","apeach frodo","frodo neo","muzi neo","apeach muzi"]
let k = 2
출력
[2,1,1,0]
문제 풀이
Array extension
- Playground에서는 generic하게 작성한 코드가 잘 돌아가나,
- 프로그래머스에서 문제 실행시 where에서 에러가 발생하므로 Element 타입을 String으로 고정함
extension Array {
func indexDictionary() -> [Element: Int] where Element: Hashable {
var dict: [Element: Int] = [:]
for (index, element) in self.enumerated() {
dict[element] = index
}
return dict
}
mutating func appendIfNeeded(_ newElement: Element) where Element: Equatable {
guard self.contains(newElement) == false else { return }
self.append(newElement)
}
}
extension Array where Element == String {
func indexDictionary() -> [Element: Int] {
...
}
mutating func appendIfNeeded(_ newElement: Element) {
...
}
}
indexDictionary
- 배열을 [인덱스: element]로 transform하는 함수
- 이름에 해당하는 id값을 조회하기 위해 만듦
let id_list = ["muzi", "frodo", "apeach", "neo"]
let idDict: [String: Int] = id_list.indexDictionary()
appendIfNeeded
- 배열에 있으면 추가하지 않고, 없으면 추가하는 함수
- report가 중복되는 경우도 있기에 만듦
- 아래의 경우, list에 reporter가 중복되는 경우는 발생하지 않게 됨
list.appendIfNeeded(reporter)
solution 함수
- reportDict를 구현함
- 1에서 구한 reportDict의 values의 길이가 k보다 클 때, countList에 1을 더함
func solution(_ id_list:[String], _ report:[String], _ k:Int) -> [Int] {
let idDict: [String: Int] = id_list.indexDictionary()
var countList: [Int] = Array(repeating: 0, count: id_list.count)
var reportDict: [String: [String]] = [:]
for repo in report {
let arr = repo.components(separatedBy: " ")
guard let reporter = arr.first,
let reported = arr.last else { continue }
guard var list = reportDict[reported] else {
reportDict[reported] = [reporter]
continue
}
list.appendIfNeeded(reporter)
reportDict[reported] = list
}
reportDict.values.forEach {
guard $0.count >= k else { return }
$0.forEach {
guard let id = idDict[$0] else { return }
countList[id] += 1
}
}
return countList
}
전체 코드
extension Array {
func indexDictionary() -> [Element: Int] where Element: Hashable {
var dict: [Element: Int] = [:]
for (index, element) in self.enumerated() {
dict[element] = index
}
return dict
}
mutating func appendIfNeeded(_ newElement: Element) where Element: Equatable {
guard self.contains(newElement) == false else { return }
self.append(newElement)
}
}
func solution(_ id_list:[String], _ report:[String], _ k:Int) -> [Int] {
let idDict: [String: Int] = id_list.indexDictionary()
var countList: [Int] = Array(repeating: 0, count: id_list.count)
var reportDict: [String: [String]] = [:]
for repo in report {
let arr = repo.components(separatedBy: " ")
guard let reporter = arr.first,
let reported = arr.last else { continue }
guard var list = reportDict[reported] else {
reportDict[reported] = [reporter]
continue
}
list.appendIfNeeded(reporter)
reportDict[reported] = list
}
reportDict.values.forEach {
guard $0.count >= k else { return }
$0.forEach {
guard let id = idDict[$0] else { return }
countList[id] += 1
}
}
return countList
}