저번에는 기초적인 문제로 기초적인 문법을 다뤘으니 이번엔 파이썬으로 작성한 코드중에 뭔가를 러스트로 변환해 보고자 하였다. 2가지 정도를 변환해 볼 것인데 이번에는 백준에서 무려 25점을 받았던 (...)
개발자 능력 실화?
K번째 소수라는 문제의 파이썬 코드를 러스트로 변환해 볼 것이다. 이 코드를 변환하는 이유는 필자의 궁금증을 해결하기 위함이다. 파이썬이기 때문에 25점을 받은건지, 아니면 내가 똥멍청인지. 일단 이 코드는 파이썬의 내부 함수가 아닌 기초적인 로직들이 들어있으므로 "기초 다지기 - 2" 정도의 포스트가 될 것이다.
K 번째 소수 — 파이썬
import math
def prime_of_number(K):
if K == 0:
return None
prime_lists = list()
counter = 0
x = 2
while True:
is_prime = True
for y in prime_lists:
if y > math.sqrt(x):
break
if x % y == 0:
is_prime = False
break
if is_prime:
prime_lists.append(x)
counter += 1
if counter >= K:
return prime_lists[counter - 1]
x += 1
if __name__=='__main__':
print(prime_of_number(int(input())))
위 코드를 고대로 러스트로 변경해 볼 것이다. 처음엔 코드가 술술 작성되서 "오? 역시 난 천재였나?" 싶었으나 온갖 오류가 발생하여 고치느라 진땀을 흘렸다. 발생했던 오류들과 해결하는 방법을 아래에 작성하였다.
cannot infer type for type parameter `T`
- 벡터에 타입이 존재하지 않는다는 에러로 이전 포스트에서 '상근날드'라는 문제를 풀이할 때는 벡터의 형태를 지정하지 않아서 이번에도 똑같이 했더니 발생한 오류다. 벡터를 선언할 때
let mut m_vec: Vec<T> = Vec::new()
로 하면 해결된다.
no method named `sqrt` found for type `i32` in the current scope
- 구글에 검색하였더니
var.sqrt()
로 제곱근을 구하길래 똑같이 따라했더니 발생한 오류였는데i32
에는sqrt()
라는 함수가 존재하지 않는다. 따라서 실수로 형태를 변환하고 제곱근을 구하였다. 그리고 실수와 정수를 비교할 수 없다는 오류도 있었는데... 러스트가 정적 타입의 언어라는 걸 자꾸 망각하는 듯 하다. 비교되는 값도 실수형으로 변환하고 값을 비교해 주었다. 형변환은 무조건parse
와match
를 써야하는 줄 알았는데var as Type
으로 변환이 가능했다. 나중에 더 알아봐야 할 듯.
value moved here, in previous iteration of loop
- 벡터를 반복문의
iterator
로 넣었더니 발생한 오류였다.for
문에 들어가는 벡터의 이름앞에&
를 표시하는 것으로 오류를 해결하였다.
cannot cast `&i32` as `f32`
for
문의iterator
로 들어온y
라는 변수가&i32
라서f32
로 형변환이 안된다는 오류로 여러 게시글을 찾아보다가C
언어와 마찬가지로*
과&
를 교차하는 방식으로 사용하길래 이걸 힌트로 해결할 수 있었다. 다만 러스트에서*
과&
가 무엇을 의미하는지 잘 모르겠다. 메모리에 접근하려면unsafe
라는 키워드를 사용한다는 것으로 알고 있어서 메모리 관련된 건 아니라 생각했는데... 찾아봐야 할 것 같다.
K 번째 소수 — 러스트
use std::io;
fn input_int() -> i32 {
let mut temp_str = String::new();
io::stdin().read_line(&mut temp_str)
.expect("Falied to read line");
let result = match temp_str.trim().parse::<i32>() {
Ok(i) => i,
Err(_e) => {
-1
}
};
return result;
}
fn prime_of_number(_k: i32) -> i32 {
if _k == 0 {
return 0;
}
let mut prime_lists: Vec<i32> = Vec::new();
let mut counter: i32 = 0;
let mut x: i32 = 2;
loop {
let mut is_prime = true;
for y in &prime_lists {
let f_x = x as f32;
let f_y = *y as f32;
if f_y > f_x.sqrt() {
break;
}
if x % y == 0 {
is_prime = false;
break;
}
}
if is_prime {
prime_lists.push(x);
counter += 1;
if counter >= _k {
return prime_lists[prime_lists.len() - 1];
}
}
x += 1;
}
}
fn main() {
println!("{}", prime_of_number(input_int()));
}
결과값 비교해보려고 파이썬과 러스트를 교차해서 실행했는데 파이썬에 값을 넣고 엔터를 치고 이후 러스트에 값 넣고 엔터를 쳤더니 러스트에서 결과가 먼저 나오는 걸 보고 굉장히 신기했다. 이대로라면 50점은 넘게 나오지 않을까!
예상외로 100점이 나와버렸다. 나는 똥멍청이가 아니었다!
Ghost