Project Euler - Scala 中最大的素因子

发布于 2024-10-12 20:38:03 字数 1370 浏览 9 评论 0原文

我一直在尝试在 Scala 中解决项目 Euler number in 3,这就是我到目前为止所得到的:

def largestPrimeFactor(in:BigInt) : Option[BigInt] = {
  def isPrime(in:BigInt) : Boolean = {
    def innerIsPrime(in:BigInt, currentFactor:BigInt) : Boolean = {
        if(in % currentFactor == 0) {
        false
      }
      else {
        if(currentFactor > (in / 2)){
           true
        }
        else {
          innerIsPrime(in, currentFactor + 1)
        }
      }
    }

     innerIsPrime(in, 2)
  }

   def nextLargeFactor(in:BigInt, divisor:BigInt) : (Option[BigInt], BigInt) = {
     if((in / 2) > divisor) {
       if(in % divisor == 0) (Some(in / divisor), divisor) 
       else nextLargeFactor(in, divisor + 1)
     }
     else
       (None, divisor)
   }

   def innerLargePrime(in : BigInt, divisor:BigInt) : (Option[BigInt], BigInt) = {
     nextLargeFactor(in, divisor) match {
       case (Some(factor), div) => {
         if(isPrime(factor)) (Some(factor), div)
         else innerLargePrime(in, div + 1)
       }
       case (None, _) => (None, divisor)
     }
  }

  innerLargePrime(in, 2)._1
}

我认为这会起作用,但我被困在工作中(在缓慢的构建过程中利用时间)并且只有 SimplyScala 服务 - 这是超时的(我会检查它在家里)。

但由于这是我写的第一篇 Scala 文章,所以我想问一下,我犯了什么可怕的罪过?我的解决方案有多不理想?我践踏了哪些约定?

谢谢!

I've been trying to solve project Euler number in 3 in Scala, and this is what I've got so far:

def largestPrimeFactor(in:BigInt) : Option[BigInt] = {
  def isPrime(in:BigInt) : Boolean = {
    def innerIsPrime(in:BigInt, currentFactor:BigInt) : Boolean = {
        if(in % currentFactor == 0) {
        false
      }
      else {
        if(currentFactor > (in / 2)){
           true
        }
        else {
          innerIsPrime(in, currentFactor + 1)
        }
      }
    }

     innerIsPrime(in, 2)
  }

   def nextLargeFactor(in:BigInt, divisor:BigInt) : (Option[BigInt], BigInt) = {
     if((in / 2) > divisor) {
       if(in % divisor == 0) (Some(in / divisor), divisor) 
       else nextLargeFactor(in, divisor + 1)
     }
     else
       (None, divisor)
   }

   def innerLargePrime(in : BigInt, divisor:BigInt) : (Option[BigInt], BigInt) = {
     nextLargeFactor(in, divisor) match {
       case (Some(factor), div) => {
         if(isPrime(factor)) (Some(factor), div)
         else innerLargePrime(in, div + 1)
       }
       case (None, _) => (None, divisor)
     }
  }

  innerLargePrime(in, 2)._1
}

Which I think will work, but I'm stuck at work (making use of time during slow builds) and only have the SimplyScala service - which is timing out (I'll check it at home).

But as this is the first bit of Scala of any length I've written I'd thought I'd ask, what horrendous sins have I committed? How hopelessly suboptimal is my solution? What conventions have I trampled on?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

别理我 2024-10-19 20:38:03

我真的不明白你想要完成什么。就这么简单:

def largestPrimeFactor(b : BigInt) = {
  def loop(f:BigInt, n: BigInt): BigInt =
     if (f == n) n else 
     if (n % f == 0) loop(f, n / f) 
     else loop(f + 1, n)
  loop (BigInt(2), b)
}

虽然这里没有任何优化,但我立即得到了结果。唯一的“技巧”是你必须知道一个数字的最小因子(较大的一个)“自动”是质数,并且一旦找到一个因子你就可以除以该数字。

I don't really get what you try to accomplish. It's that simple:

def largestPrimeFactor(b : BigInt) = {
  def loop(f:BigInt, n: BigInt): BigInt =
     if (f == n) n else 
     if (n % f == 0) loop(f, n / f) 
     else loop(f + 1, n)
  loop (BigInt(2), b)
}

Although there is nothing optimized here, I get the result instantly. The only "tricks" are that you have to know that the smallest factor (greater one) of a number is "automatically" prime, and that you can divide the number once you have found a factor.

怎樣才叫好 2024-10-19 20:38:03

摘自这里

lazy val ps: Stream[Int] =
  2 #:: ps.map(i =>
    Stream.from(i + 1).find(j =>
      ps.takeWhile(k => k * k <= j).forall(j % _ > 0)
    ).get
)

val n = 600851475143L
val limit = math.sqrt(n)
val r = ps.view.takeWhile(_ < limit).filter(n % _ == 0).max

r是你的答案

Taken from here:

lazy val ps: Stream[Int] =
  2 #:: ps.map(i =>
    Stream.from(i + 1).find(j =>
      ps.takeWhile(k => k * k <= j).forall(j % _ > 0)
    ).get
)

val n = 600851475143L
val limit = math.sqrt(n)
val r = ps.view.takeWhile(_ < limit).filter(n % _ == 0).max

r is your answer

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文