[Swift] 1929 : 소수 구하기

kpk0616·2022년 8월 13일
0

Algorithm

목록 보기
1/2
post-thumbnail

시간 초과

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])")
    }
}

Swift 문법

Swift 정수 여러 개 입력받기

let input = readLine()!.split(separator: " ").map{ Int($0)! }

let M = input[0]
let N = input[1]

readLine 을 이용해 한 줄로 입력받은 문자열을 " " 를 기준으로 split 해준 뒤, map 을 이용해 Int 형으로 저장합니다.
배열 형태로 input 에 저장되고, 인덱스를 이용해 M 과 N 을 뽑아내면 됩니다.

stride(from, through, by)

아래 두 경우와 같이 사용되는데, 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

참고

profile
가능한 한 빨리 틀렸음을 증명하려고 노력합니다.그래야만 발전을 찾을 수 있기 때문입니다.

0개의 댓글