import Foundation
let input = readLine()!.split(separator: " ").map{ Int(String($0))! }
var result = ""
let m = input[0]
let n = input[1]
var y = 2
for x in m...n { // x : 소수 판별 당할 아이
y = 2
while (y <= x - 1) { // y : x 가 소수인지 판별할, 나누어줄 아이
if (x % y == 0) { break }
y += 1
}
if (y == x) { print(String(x)) }
}
일반적인 반복문을 이용해 풀었더니 시간 초과가 나서, 에라토스테네스의 체 알고리즘을 이용해 풀었습니다.
스위프트를 이용해서 문제를 푼 게 처음이라 입출력부터 배열 선언, 반복문까지 스위프트 문법에 대해 찾아 보며 풀었습니다.
에라토스테네스의 체 알고리즘
은 소수 판별에 사용되는 효율적인 알고리즘입니다.
1 부터 n 까지의 수에서 소수를 판별한다고 할 때,
n 만큼의 0 이 아닌 수로 초기화 된 배열을 만들어놓은 후 소수인 수는 0으로 배열의 값을 채워줍니다.
2 부터 n / 2 까지 j 의 값을 1 씩 증가시키면서, j 의 배수에 해당하는 수는 소수가 아닌 수에 해당하므로 해당 인덱스의 값을 0 으로 만들어줍니다.
배수를 확인할 때에는 7 x 1, 7 x 2, ... 로 확인하지 않고 7 x 7, 7 x 8 부터 확인해줍니다.
7 x 6 같은 경우 6 의 배수를 확인할 때 이미 확인이 완료되었기 때문입니다.
이런 식으로 n 까지 소수인지를 판별한 후, 최종적으로 인덱스의 값이 0 이 아닌 수들만 프린트해주면 됩니다.
import Foundation
let input = readLine()!.split(separator: " ").map{ Int($0)! }
let M = input[0]
let N = input[1]
var arr: [Int] = Array(repeating: 0, count: N + 1)
for i in 2...N {
arr[i] = i
}
for j in 2...N {
if arr[j] == 0 { continue }
for k in stride(from: j + j, through: N, by: j) {
arr[k] = 0
}
}
for w in M...N {
if arr[w] != 0 {
print("\(arr[w])")
}
}
let input = readLine()!.split(separator: " ").map{ Int($0)! }
let M = input[0]
let N = input[1]
readLine
을 이용해 한 줄로 입력받은 문자열을 " " 를 기준으로 split
해준 뒤, map
을 이용해 Int 형으로 저장합니다.
배열 형태로 input 에 저장되고, 인덱스를 이용해 M 과 N 을 뽑아내면 됩니다.
아래 두 경우와 같이 사용되는데, from
은 초기화, through
는 end 값, by
는 값과 값 사이 넘어가는 연산 수를 의미합니다.
for countdown in stride(from: 3, through: 1, by: -1) {
print("\(countdown)...")
}
// 3...
// 2...
// 1...
for multipleOfThree in stride(from: 3, through: 10, by: 3) {
print(multipleOfThree)
}
// 3
// 6
// 9