我开始学习Rust,它看起来很棒,但它与任何基于C的语言都不一样。我想知道如何使这段代码更加实用,以及如何改进我的解决方案本身。
2520是最小的数,可以除以从1到10的每一个数,没有任何余数。什么是最小的正数,可以被从1到20的所有数字整除?
fn near_pow(number:f64, exponent:f64)-> f64
{
exponent.powf(number.log(exponent).floor())
}
fn is_prime(number:i32) -> bool
{
use std::ops::Rem;
if number == 2 { return true; }
if number.rem(2)== 0 { return false; }
let mut i = 3;
while (i*i) <= number
{
if number.rem(i) == 0 {return false;}
i+= 2;
}
true
}
fn euler_problem5(to:i32) -> f64
{
(1..to+1).filter(|&x| is_prime(x))
.fold(1f64, |p , x|p * near_pow(to as f64, x as f64))
}
fn main() {
let x = euler_problem5(20);
println!("{}",x);
}链接到操场
发布于 2015-09-28 15:24:56
:后的空格。fn foo(值:类型)==、+和* )以及符号(如-> )周围使用空格。I += 2;,之后使用空格。(“{}”,x);;子句)中使用。如果编号== 2{返回true }%操作符而不是调用rem方法:如果编号%2 == 0{返回false }fold内嵌,特别是因为您无法给它命名比fold_op更好的名称(OP更改了我所指的代码;查看修订历史以了解我在说什么)。(1..to + 1).fold(1f64,区p,x区{ // .fold })return语句(或者在任何地方都不是卫士子句)。尝试使用迭代器代替。合在一起:
fn near_pow(number: f64, exponent: f64) -> f64 {
exponent.powf(number.log(exponent).floor())
}
fn is_prime(number: i32) -> bool {
if number == 2 { return true }
if number % 2 == 0 { return false }
(0..)
.map(|v| 3 + 2 * v) // Can use `Range::step_by` when stable
.take_while(|i| i * i <= number)
.all(|i| number % i != 0)
}
fn euler_problem5(to: i32) -> f64 {
(1..to + 1).fold(1f64, |p, x| {
if is_prime(x) {
p * near_pow(to as f64, x as f64)
} else {
p
}
})
}
fn main() {
println!("{}", euler_problem5(20));
}我不太熟悉如何有效地解决欧拉问题,所以希望其他人也能加入进来。
原始代码更改
更新
fn euler_problem5(to: i32) -> f64 {
(1..to + 1)
.filter(|&v| is_prime(v))
.fold(1f64, |p, x| p * near_pow(to as f64, x as f64))
}基于其他答案的
user5402主张用整数运算代替浮点数,但无论哪种方法,您都应该使用无符号整数,因为不需要支持负数。这也让你对你的价值观有了更多的上限。
发布于 2015-09-28 16:11:08
我最大的批评是,您正在使用浮点算法来解决整数问题。
考虑到舍入错误和不精确答案的可能性,我会选择一个简单的while-循环来计算nearest_pow:
(对不起-这是Python,我还不是一个锈蚀程序员)
def nearest_pow(p,n):
a = 1
while a*p <= n:
a = a * p
return a铁锈有fold和take_while,所以我相信您可以以一种功能的方式实现这一点。
这是有效的-它只执行日志n迭代-不会遭受任何轮转错误。
此外,它也适用于可能适用于其他数论问题的大整数。
另外,我将以整数的形式返回答案--也许是一个i64。
https://codereview.stackexchange.com/questions/105930
复制相似问题