k진수에서 소수 개수 구하기
문제 설명
양의 정수 n이 주어짐.
해당 숫자를 k진수로 바꿨을 때, 변환된 수 안에 아래 조건에 맞는 소수(Prime number)가 몇 개인지 출력!
- 0P0처럼 소수 양쪽에 0이 있는 경우
- P0처럼 소수 오른쪽에만 0이 있고 왼쪽에는 아무것도 없는 경우
- 0P처럼 소수 왼쪽에만 0이 있고 오른쪽에는 아무것도 없는 경우
- P처럼 소수 양쪽에 아무것도 없는 경우
- 단, P는 각 자릿수에 0을 포함하지 않는 소수입니다.
예를 들어, 101은 P가 될 수 없습니다.
문제 풀이
- k진수로 변환할줄을 알아야하고
String(Int,radix : 바꾸고싶은 진수)
print(String(10, radix: 3)) //101
- 그 바뀐친구를
0
기준으로split
var n = String(n, radix: k) print(n.split(separator: "0")) // 436734를 넣으면 ["211", "2", "1", "1", "11"]
- 남은친구를 이제 십진수로 보면서
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 }
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
을 소수로 카운팅하지?싶었는데, guard num >= 1 else { return false }
때문이었다. guard
를 자주안쓰다보니 여전히 좀 어색한 문법이다.. 결국 이 부분을 더 직관적인 if num <= 1 { return false }
로 변경해주었다. 1은 그냥 return false
가 될 수 있도록.. 2%2 == 0
에 걸려서 였으므로 예외를 하나 더 추가해줬다. 오까이
문제가 의도적으로 복잡하게 써놓은 것 같은데, 결국 split
을 0
기준으로 푸는 문제라는걸 잘 인지하면 쉽게 풀리는 문제였던 것 같다.
타인의 코드
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
}
덕분에 아주 깔끔한 코드가 완성됐다.