[Swift] [89일차] k진수에서 소수 개수 구하기_programmers

·2025년 3월 8일
0

SwiftAlgorithm

목록 보기
94/105
post-thumbnail

k진수에서 소수 개수 구하기


문제 설명

양의 정수 n이 주어짐.
해당 숫자를 k진수로 바꿨을 때, 변환된 수 안에 아래 조건에 맞는 소수(Prime number)가 몇 개인지 출력!

  • 0P0처럼 소수 양쪽에 0이 있는 경우
  • P0처럼 소수 오른쪽에만 0이 있고 왼쪽에는 아무것도 없는 경우
  • 0P처럼 소수 왼쪽에만 0이 있고 오른쪽에는 아무것도 없는 경우
  • P처럼 소수 양쪽에 아무것도 없는 경우
  • 단, P는 각 자릿수에 0을 포함하지 않는 소수입니다.
    예를 들어, 101은 P가 될 수 없습니다.

문제 풀이

  1. k진수로 변환할줄을 알아야하고

String(Int,radix : 바꾸고싶은 진수)

print(String(10, radix: 3)) //101
  1. 그 바뀐친구를 0기준으로 split
  var n = String(n, radix: k)
    print(n.split(separator: "0"))  // 436734를 넣으면 ["211", "2", "1", "1", "11"]
  1. 남은친구를 이제 십진수로 보면서 isPrime 소수인지 판단! 해서 카운팅해주면 끝

isPrime함수

  func isPrime(_ num: Int) -> Bool {
        var isPrime = false
        for i in 2 ... Int(sqrt(Double(num))) {
            if num % i == 0 { // 나눠지니까 이거는 안됨
                return false
            }
        }
        return true
    }

오류발생 !

for문의 범위의 하한선(2)이 Int(sqrt(Double(num))) 보다 작다는 에러가 발생 !

소수 판단에 시간복잡도 최소화하려고 좀 빡빡하게 걸었는데 만약 num=2라면 이게 2...1 이 되므로 이상한 코드가 되는것이었다. 때문에 +1 걸어줘서 에러안뜨게 해줬다.

최종 제출 코드

import Foundation

func solution(_ n: Int, _ k: Int) -> Int {
    var answer = 0
    func isPrime(_ num: Int) -> Bool {
        if num <= 1 { return false }
        else if num == 2 { return true }
        for i in 2 ... Int(sqrt(Double(num))) + 1 {
            if num % i == 0 { // 나눠지니까 이거는 안됨
                return false
            }
        }

        return true
    }

    var n = String(n, radix: k).split(separator: "0").map { Int($0)! }
    
    for item in n {
        if isPrime(item) {
            answer += 1
        }
    }

    return answer
}
  1. 이 친구들이 왜 1을 소수로 카운팅하지?싶었는데, guard num >= 1 else { return false } 때문이었다. guard를 자주안쓰다보니 여전히 좀 어색한 문법이다.. 결국 이 부분을 더 직관적인 if num <= 1 { return false }로 변경해주었다. 1은 그냥 return false 가 될 수 있도록..
  2. 마지막 점검을 하는데, 얘가 2일때는 또 소수로 판단을 안해주고 있었다. 반복문에서 2...2로 2%2 == 0 에 걸려서 였으므로 예외를 하나 더 추가해줬다.

오까이
문제가 의도적으로 복잡하게 써놓은 것 같은데, 결국 split0기준으로 푸는 문제라는걸 잘 인지하면 쉽게 풀리는 문제였던 것 같다.


타인의 코드

import Foundation

func solution(_ n:Int, _ k:Int) -> Int {
    let map = String(n, radix: k, uppercase: false).split(separator: "0")

    return map.filter{ isPrime(Int($0)!) }.count
}

func isPrime(_ n : Int) -> Bool {
    if n <= 1 { return false }
    else if n == 2 || n == 3 { return true }
    else {
        for i in 2...Int(sqrt(Double(n))) {
            if n % i == 0 { return false }
        }
        return true
    }
}

여기서 배울점은 filter을 활용이었다. 나도 이미 다 만들어놓은 상황이라 isPrime 그대로 썼으면 됐는데, 억지로 for문 돌리면서 투박하게 좀 해결한 것 같아서 아쉬운느낌이 들었다.
추가로, Int(sqrt(Double(n)))도 굳이 내가 +1을 근거없이 해주지말고, 예외처리를 해줬다면 굳이 + 1을 냅둘필요가 없었다.
이를 기반으로 좀 다듬어봤다.

import Foundation

func solution(_ n: Int, _ k: Int) -> Int {
    func isPrime(_ num: Int) -> Bool {
        if num <= 1 { return false }
        else if num == 2 { return true }
        for i in 2 ... Int(sqrt(Double(num))) + 1 {
            if num % i == 0 { // 나눠지니까 이거는 안됨
                return false
            }
        }
        return true
    }
    return String(n, radix: k).split(separator: "0").map { Int($0)! }.filter { isPrime($0) }.count
}

덕분에 아주 깔끔한 코드가 완성됐다.

profile
기억보단 기록을

0개의 댓글