class S99Int(val start: Int) {
import S99Int._
def isPrime: Boolean =
(start > 1) && (primes.takeWhile(_ <= Math.sqrt(start)).forall(start % _ != 0))
def isCoprimeTo(x: Int): Boolean = gcd(start, x) == 1
def totient: Int = (1 to start).filter(start.isCoprimeTo(_)).length
def totient2: Int = start.primeFactorMultiplicity.foldLeft(1) { (r, f) =>
f match { case (p, m) => r * (p - 1) * Math.pow(p, m - 1).toInt }
}
def primeFactors: List[Int] = {
def primeFactorsR(x: Int, ps: Stream[Int]): List[Int] = {
x match {
case n if n.isPrime => List(n)
case n if (n % ps.head) == 0 => ps.head :: primeFactorsR(n / ps.head, ps)
case n => primeFactorsR(n, ps.tail)
}
}
return primeFactorsR(start, primes)
}
def primeFactorMultiplicity: Map[Int, Int] = {
def factorCount(n: Int, p: Int): (Int, Int) =
if (n % p != 0) (0, n)
else factorCount(n / p, p) match { case (c, d) => (c + 1, d) }
def factorsR(n: Int, ps: Stream[Int]): Map[Int, Int] =
if (n == 1) Map()
else if (n.isPrime) Map(n -> 1)
else {
val nps = ps.dropWhile(n % _ != 0)
val (count, dividend) = factorCount(n, nps.head)
Map(nps.head -> count) ++ factorsR(dividend, nps.tail)
}
factorsR(start, primes)
}
def goldbach: (Int, Int) = {
if (start <= 2 || (start & 1) == 1) throw new UnsupportedOperationException("大于2的偶数才支持此操作")
primes.takeWhile(_ <= start).find(e => (start - e).isPrime) match {
case None => throw new IllegalArgumentException
case Some(x) => (x, start - x)
}
}
}
object S99Int {
implicit def int2S99Int(i: Int): S99Int = new S99Int(i)
val primes = Stream.cons(2, Stream.from(3, 2) filter { _.isPrime })
def gcd(m: Int, n: Int): Int = if (n == 0) m else gcd(n, m % n)
def listPrimesinRange(r: Range): List[Int] =
r.filter(_.isPrime).toList
def listPrimesinRange2(r: Range): List[Int] =
primes.dropWhile(_ < r.start).takeWhile(_ <= r.end).toList
def printGoldbachList(r: Range): Unit = {
r.filter(e => e > 2 && (e & 1) == 0)
.foreach(e => {
val m = e.goldbach
println(e + " = " + m._1 + " + " + m._2)
})
}
}