LV.1 추억 점수

이 녀석에게는 아주 슬픈 전설이있다..

오늘 거하게 망한 코테 전에 몸풀기랍시고 의기양양하게 푼 프로그래머스 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()에 대한 내용은 내용이 생각 보다 많고 재미있어서 따로 다른 포스팅에 정리해서 다시 올리기로했다!

👉[kotlin] withIndex() 동작 원리 분석

댓글남기기