실버단계 도달... 부끄럽지만 처음이라 기록
문제링크
1) 범위안의 소수 찾기
2) 소수 중 상근수 찾기
그대이름 소수 소수
[에라토스테네스의 체]
이렇게 구하는 방법을 안다.
그래서
func primeNum(_ range: Int) {
var numSet: [Bool] = Array(repeating: false, count: range + 1)
numSet.enumerated().forEach{ set in
let index = set.offset
let element = set.element
if index == 1 || index == 0 {
return
}
if element == false {
for i in 2... {
if index * i <= range {
if numSet[index * i] == false {
numSet[index * i] = true
}
} else {
return
}
}
}
}
절씨구 이렇게 구했다.
여기서 배운건 그간 forEach
쓸 때 index를 알아야하는 경우가 별로 없었다.(있었던 적도 있었지만 그땐 그냥 깔끔하게(?) enumerate() 메소드를 이용해서for
문 돌렸다.)
offset : index
element : value
index와 value에 접근이 가능해졌다.
코드가 그닥 깔끔해 보이진 않아보이는데 더 효율적인 방법으로 에라토스테네스의 체를 구하는 방법이 있으면 적어놓겠다!
위키백과 - 에라토스테네스의 체
var primeSet = numSet.enumerated().filter{ $0.element == false }.map{ $0.offset }
primeSet.removeSubrange(0...1)
primeSet.forEach{ num in
var dict: [Int: Bool] = [:]
let stringNum = String(num)
var arr = stringNum.compactMap{ Int(String($0)) }
var sum = 0
while sum != 1 {
arr.forEach {
sum += ($0)*($0)
}
if dict[sum] == nil {
dict[sum] = true
arr = String(sum).compactMap{ Int(String($0)) }
sum = 0
} else if sum == 1 {
print(num)
return
} else {
return
}
}
}
딕셔너리 사용해서 primeSet.forEach
의 num
이 반복되는지 체크한다.
반복된다면, 상근수가 아니다.
enumerated()
소수 구하기
위에 적어놓은 primeNum
함수 보다 더 나은 방법이 있어서 적어놓겠다.
func isPrime(_ num: Int) -> Bool {
if num <= 1 { return false }
if num == 2 { return true }
if num % 2 == 0 { return false }
let sqrtn = Int(sqrt(Double(num)))
for div in stride(from: 3, through: sqrtn, by: 2) {
if num % div == 0 {
return false
}
}
return true
}
//출처 : 종만북 - 정수론