달달한 스토리

728x90
반응형

출처 핀터레스트

 

주말이라도 예외는 없다.

 

문제를 풀어보자.

 

나누어 떨어지는 숫자 배열

 

//나누어 떨어지는 숫자 배열
class DivisibleArrayOfNumbers {
    fun solution(arr: IntArray, divisor: Int): IntArray =
        arr.filter { it % divisor == 0 }
            .sorted()
            .toMutableList()
            .also {
                if(it.isEmpty()) it.add(-1)
            }.toIntArray()
}

이 문제는 약간의 답을 참고하여 풀었다.

 

also의 재발견...

 

also로 객체 자체를 전달받아.. 코드를 한 줄로 스무스하게

 

만들 수 있는 좋은 메서드이다.

 

divisor로 나누어지는 요소들을 필터링하고,

 

오름차순으로 정렬한 다음, 수정할 수 있는 mutableList로 변환해준다.

 

그리고,

 

also를 통해 객체를전달받고, 만약 비어 있다면, 리스트에 -1만을 add 해준다.

 

마지막은 IntArray로 변환하고 반환한다.

 

 

제일 작은 수 제거하기

 

//제일 작은 수 제거하기
class RemoveSmallestNumber {
    fun solution(arr: IntArray): IntArray {
        return if(arr.size == 1) intArrayOf(-1)
        else arr.filter {  it != arr.minOrNull() }.toIntArray()
    }
}

 

이 문제는 IntArray에서 제공하는 min()이라는 메서드를 사용하여 풀려고 하는데,

 

해당 메서드는 Deprecated가 되어, 프로그래머스 에디터에서 계속 resolved가

 

되는 것이었다.

 

처음에 Deprecated 된 줄 모르고, 왜 에러가 뜨는지 몰라, 내부를 보니 명시가 되어있었다..

 

 

그래서 minOrNull를 대신 쓰라고 친절하게 설명이 되어,

 

해당 메서드를 사용하여 풀었다.

 

arr 사이즈가 1이면 -1만을 담은 IntArray를 반환하고,

 

그게 아니라면, 최솟값만을 제외한 IntArray를 반환하게 하였다.

 

 

음양 더하기

 

//음양 더하기
class AddYinAndYang {
    fun solution(absolutes: IntArray, signs: BooleanArray): Int =
        absolutes.also {
            signs.mapIndexed { i, b ->
                if(!b) it[i] *= -1
            }
        }.sum()
}

 

이번에도 깔끔하게 한 줄로 나타내게 하기 위해 

 

also로 쓴 방법이다.

 

그런데, 이 방법을 사용하고 나서 더 효율 좋고 간단하고 유용한 메서드를 사용한 답안을 보았다.

 

아래 코드이다.

 

//음양 더하기
class AddYinAndYang {
    fun solution(absolutes: IntArray, signs: BooleanArray): Int =
        absolutes.foldIndexed(0) { idx, acc, num ->
            acc + if(signs[idx]) num else -num }
}

 

바로 foldIndexed() 메서드이다..

 

나는 이 메서드가 생소하여 공부해보았다.

 

fold라는 메서드가 있는데, 이 메서드는 계산 결과를 저장하는 누산기를 제공한다.

 

누산기(accumulator)를 제공한다는 말이 어려울 수 있다.

 

fold 메서드의 사용법을 간단히 알아보자.

 

val intArr = intArrayOf(1, 2, 3)
val result = intArr.foldIndexed(0) {
         idx, acc, num -> num
}

 

foldIndexed는 처음에 accumulator의 초깃값을 정해야하한다. (코드에서는 0으로 지정했다.)

 

그리고 다음과 같이 인덱스(idx), 누산기(acc 초깃값 0), 배열의 요소(num)를 전달받게 된다.

 

여기서 idx와 num을 전달받는 것까지는 이해할 수 있겠지만,

 

저 acc(누산기)는 어떻게 활용할까?

 

쉽게 말하자면 누산기와 같이 연산하게 되면, 값이 저장되게 된다.

 

아래 코드를 보면서, 쉽게 이해가 갈 것이다.

 

//case 1: acc에 값을 연산하지 않았기 때문에(누산하지 않았기 때문에) 저장되지 않고,
//마지막 요소 3이 출력된다.

val intArr = intArrayOf(1, 2, 3)
val result = intArr.foldIndexed(0) {
         idx, acc, num -> num
}

print(result) //3



//case 2: 이 역시 acc에 값을 누산하지 않았기 때문에, 마지막 인덱스 값인 2가 출력된다.

val intArr = intArrayOf(1, 2, 3)
val result = intArr.foldIndexed(0) {
         idx, acc, num -> idx
}

print(result) //2


//case 3: acc에 값을 누산하지 않았기 때문에 초깃값으로 설정한 0이 출력된다.

val intArr = intArrayOf(1, 2, 3)
val result = intArr.foldIndexed(0) {
         idx, acc, num -> acc
}

print(result) //0


//case 4: 왼쪽 요소 부터 차례대로 1, 2, 3씩 acc(0)에 값을 더하며 누산하였기 때문에,
//6이 출력된다.

val intArr = intArrayOf(1, 2, 3)
val result = intArr.foldIndexed(0) {
         idx, acc, num -> acc + num
}
print(result) //6


//case 5: 요소들의 인덱스 값이 0, 1, 2 값이 acc(0)에 값을 더하며, 누산하였기 때문에,
//3이 출력된다.

val intArr = intArrayOf(1, 2, 3)
val result = intArr.foldIndexed(0) {
         idx, acc, num -> acc + idx
}
print(result) //3

역시 말보다는 코드로 설명하는 게 이해가 가기 쉬울 것이다.

 

한마디로 전달받은 누산기(acc)에 값을 차례대로 계산하여 저장하는 느낌이라고 생각하면

 

쉬울 것이다.

 

차례로 계산할 때 유용한 메서드가 될 것 같다.

 

그럼 다시 한번 코드를 보게 되면,

 

//음양 더하기
class AddYinAndYang {
    fun solution(absolutes: IntArray, signs: BooleanArray): Int =
        absolutes.foldIndexed(0) { idx, acc, num ->
            acc + if(signs[idx]) num else -num }
}

 

누산기인 acc에 signs배열에 요소들이 true인지 false인지에 따라,

 

양수 num을 더해줄지 음수 num을 더해줄지 조건문을 통해

 

값을 누산 하고, int 값을 반환해주는 식이 완성이 된다.

728x90
반응형

공유하기

facebook twitter kakaoTalk kakaostory naver band
loading