기사단원의 무기

KSang·2023년 12월 12일
0

[Kotlin]코드카타

목록 보기
59/100

🕵️문제설명

숫자나라 기사단의 각 기사에게는 1번부터 number까지 번호가 지정되어 있습니다. 기사들은 무기점에서 무기를 구매하려고 합니다.

각 기사는 자신의 기사 번호의 약수 개수에 해당하는 공격력을 가진 무기를 구매하려 합니다. 단, 이웃나라와의 협약에 의해 공격력의 제한수치를 정하고, 제한수치보다 큰 공격력을 가진 무기를 구매해야 하는 기사는 협약기관에서 정한 공격력을 가지는 무기를 구매해야 합니다.

예를 들어, 15번으로 지정된 기사단원은 15의 약수가 1, 3, 5, 15로 4개 이므로, 공격력이 4인 무기를 구매합니다. 만약, 이웃나라와의 협약으로 정해진 공격력의 제한수치가 3이고 제한수치를 초과한 기사가 사용할 무기의 공격력이 2라면, 15번으로 지정된 기사단원은 무기점에서 공격력이 2인 무기를 구매합니다. 무기를 만들 때, 무기의 공격력 1당 1kg의 철이 필요합니다. 그래서 무기점에서 무기를 모두 만들기 위해 필요한 철의 무게를 미리 계산하려 합니다.

기사단원의 수를 나타내는 정수 number와 이웃나라와 협약으로 정해진 공격력의 제한수치를 나타내는 정수 limit와 제한수치를 초과한 기사가 사용할 무기의 공격력을 나타내는 정수 power가 주어졌을 때, 무기점의 주인이 무기를 모두 만들기 위해 필요한 철의 무게를 return 하는 solution 함수를 완성하시오

⚠️제한사항

1 ≤ number ≤ 100,000
2 ≤ limit ≤ 100
1 ≤ power ≤ limit

🔎로직설명

1차 코드

fun solution(number: Int, limit: Int, power: Int): Int {
        var knights = ArrayList<Int>()

        for (i in 1 .. number) {
            if (measure(i) > limit) knights.add(power)
            else knights.add(measure(i))
        }
        var answer = knights.sum()
        return answer
    }

    fun measure(a:Int):Int {
        var result = 0

        for (i in 1 .. a){
            if (a % i == 0) result++
        }
        return result
    }

measure = 약수의 갯수 구하는 함수

기사들의 무기 공격력 배열을 만들고 각각 power를 넣어줬다

2차 수정

fun solution(number: Int, limit: Int, power: Int): Int =
        (1..number).map { it -> if(measure(it) > limit) power else measure(it) }.sum()

솔루션 함수를 매핑해 리스트를 반환하고 sum()합쳐준다

fun solution(number: Int, limit: Int, power: Int): Int =
        (1..number).map { it -> measure(it).let { if ( it > limit) power else it }}.sum()

measure(it)을 2개나 쓰니 보기 불편해서 바꿧다

.map{ it과 .let{ it이 다르니 안되지않나 싶어도 결국 let의 결과 값이 .map {}안에 추가적인 연산이 없는이상 똑같다

let은 반환값이 코드 블록 also 반환값이 수신 객체
둘다 수신 블록 받지만 헷갈리지 말자

이제 measure을 바꿔주자

fun measure(a:Int):Int = (1..a).count { a % it == 0 }

이번엔 count함수를 이용해 1부터 a까지 수들을 연산해서 결과값이 0이면 카운트게 했다

fun solution(number: Int, limit: Int, power: Int): Int =
        (1..number).map { it -> measure(it).let { if ( it > limit) power else it }}.sum()

    fun measure(a:Int):Int = (1..a).count { a % it == 0 }

코드가 점점 아름다워 지고 있다

fun solution(number: Int, limit: Int, power: Int): Int =
        (1..number).map { i -> (1..i).count{ i % it == 0}.let { if ( it > limit) power else it }}.sum()

이제 두 함수 크기도 작아졌으니 합쳐줬다

코드를 실행하는데 문제가 생겼다

1..i 까지 모든 수를 나눠줘 시간복잡도가 O(n^2)인데 number 제한이 100000이라 너무 큰수가 들어오면 연산시간이 오래걸린다

sqrt를 써서 연산을 더 간단하게 할 수 있게 만들어야겠다

fun solution(number: Int, limit: Int, power: Int): Int =
        (1..number).map { it -> measure(it).let { if ( it > limit) power else it }}.sum()

    fun measure(a:Int):Int {
        var sqrt = Math.sqrt(a.toDouble()).toInt()
        var result = (1..sqrt).count { a % it == 0 } * 2
        return if (sqrt * sqrt == a) result - 1 else result
    }

sqrt가 제곱근인경우에 -1 을 해주면서 리턴한다

0개의 댓글