[프로그래머스]추억 점수(lv.1) (kotlin)
이 녀석에게는 아주 슬픈 전설이있다..
오늘 거하게 망한 코테 전에 몸풀기랍시고 의기양양하게 푼 프로그래머스 lv1의 문제이다.😭😭😭😭
입력으로는 각 인물의 이름과 추억점수가 배열형태로 주어지고 등장 인물의 이름을 가진 photo가 배열 형태로 주어진다.
이 정보를 가지고 각 사진의 추억점수를 계산하여 출력하는 간단한 문제였다.
추억점수는 다음과 같이 계산한다.
- 사진 속 인물의 추억점수 총 합
🙌Solution
class Solution {
fun solution(name: Array<String>, yearning: IntArray, photo: Array<Array<String>>): IntArray {
var answer: IntArray = IntArray(photo.size){0}
var nameMap = name.withIndex().associate{it.value to yearning[it.index]}
for(photoIndex in photo.indices){
photo[photoIndex].forEach{name->
nameMap[name]?.let{ answer[photoIndex]+=it }
}
}
return answer
}
}
이 문제는 다음과 같이 접근했다.
- 이름과 추억점수를 map으로 매칭시켜 탐색시간을 줄이자
- 각 사진을 forEach로 반복하며 추억점수 계산
이름과 추억점수를 map으로 변환할때는 최근 배운 withIndex와 associate를 써먹어 보았다.
🚀Advanced
var nameMap = name.withIndex().associate{it.value to yearning[it.index]}
막상 위와같이 코드를 짜니 이렇게 매핑하는게 좋을까 하는 생각이 들었다.
withIndex()와 associate()를 사용하여 이렇게 매핑하는게 입력이 간단하면 성능에 문제가 없지만 둘 다 반복이 필요한 함수인 것 같아서 입력이 커지면 성능저하의 원인이 될 수 도 있을 것 같았다.
헤엑 놀랍게도😮!
associate()는 반복을 통해 매핑을 하는 함수가 맞다.
그렇지만! 놀랍게도! withIndex()는 조금다르다!
역시 함수를 쓰려면 잘 알아보고 써야겠다는 생각이 들었다.
Iterable.withIndex()
이것도 자세히 원리를 쓰고 싶지만 너무 열심히 쓰면 포스팅의 주객전도가 되니 아래 주석을 보면서 간단하게 설명하고 넘어가기로 한다.
/**
* Returns an [Iterator] that wraps each element produced by the original iterator
* into an [IndexedValue] containing the index of that element and the element itself.
*
* @sample samples.collections.Iterators.withIndexIterator
*/
public fun <T> Iterator<T>.withIndex(): Iterator<IndexedValue<T>> = IndexingIterator(this)
위에 주석을 보면 lazy Iterable을 반환한다고 되어있는데 이 말의 의미를 list.withIndex()를 예를 들어 설명하면 아래와같다.
- list를 순회하며 즉시 원소의 타입을 변환하는것이 아님.
- lazy하게 해당 원소가 호출될 때 해당원소를 IndexedValue로 만들어 반환함!
- 따라서 list의 값은 변하지 않음
어쨌든 결론은 withIndex()는 순회를 하지 않고 associate에서만 순회하며 맵을 생성하므로 내가 생각한 그런 우려는 일어나지 않는다!
+) withIndex()에 대한 내용은 내용이 생각 보다 많고 재미있어서 따로 다른 포스팅에 정리해서 다시 올리기로했다!
댓글남기기