본문 바로가기

공부/알고리즘

Codility - lesson 5 : CountDiv

 

  기본 아이디어는 간단했다. B를 K로 나눈 뒤의 바닥 값에서 A를 K로 나눈 다음의 천장 값을 빼면 대충 답이 나오지 않겠느냐는 생각이었다. 하지만 당장 문제에 있는 케이스인 [6, 11, 2]는 floor(11 / 2) - ceil(6 / 2) = 5 - 3 = 2가 되어버려 성립되지 않게 된다.

 

  그래서 if (A % K === 0) { plus += 1 }을 추가해줬다.

 

  그렇게 하니 [6, 11, 2]는 통과했지만 이번엔 [11, 14, 2]가 실패했다. 위의 식대로 하면 이것의 값은 7 - 6으로 1이 나온다. 그래서 또 if (B % K === 0) { plus += 1 }도 추가해줬다.

 

  그런데 그러고도 에러 케이스가 존재했다. 이번엔 [11, 13, 2]이 문제다. 이것의 답은 1이지만, 알고리즘 대로라면 0이 나온다. 여기서부터 고민을 굉장히 하기 시작했다. 덕지덕지 지저분한 if else를 붙여봤지만 딱히 해결이 되진 않았다. 그러다가 문득 K로 나누기를 할 B와 A에서 1씩 뺀 다음에 해보는건 어떨까란 막연한 생각이 들었다.

 

  그래서 return Math.floor((B - 1) / K) - Math.ceil((A - 1) / K + plus; 로 해보니 해결이 됐다.(;;;) 

 

  하지만 여전히 에러 케이스는 존재했다. 이번엔 [11, 345, 17] 케이스. 이 케이스를 해결하기 위해  return Math.floor((B - 1) / K) - (A > K ? Math.ceil((A - 1) / K) : 0) + plus;  로 수정을 해서 해결을 했다.

 

  최종 통과 답은 아래와 같다.

function solution(A, B, K) {
    if (A === 0) {
        return Math.floor(B / K) + 1;
    }

    if (A === B) {
        return A % K === 0 ? 1 : 0;
    }

    if (K === 1) {
        return B - A + 1;
    }

    let plus = 0;
    if (A % K === 0) {
        plus += 1;
    }

    if (B % K === 0) {
        plus += 1;
    }

    return Math.floor((B - 1) / K) -
        (A > K ? Math.ceil((A - 1) / K) : 0) +
        plus;
}

 

  결과

 

 100% 가 나오긴 했지만 여러모로 찝찝한 결과였다. 초반 방향은 맞긴 했지만, 나 자신도 왜 이렇게 해야하는지 잘 이해 못하는 직감적인 방법으로 결정적인 이슈를 해결했다는게 영 기분이 좋지 않다.

 

 

'공부 > 알고리즘' 카테고리의 다른 글

Codility - lesson 5 : PassingCars  (0) 2022.04.11
Codility - Lesson 4 : MissingInteger  (0) 2022.03.28
Codility - Lesson 4 : MaxCounters  (0) 2022.03.24
Codility - Lesson 4: FrogRiverOne  (0) 2022.03.24
Codility - Lesson 3 : PermMissingElem  (0) 2022.03.22