Last active
December 7, 2018 09:23
-
-
Save yasuabe/ba9a04e67140dbfa56b2e0c60640be26 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import scala.collection.mutable | |
trait Prime4949Solver { | |
def primes: Stream[Int] | |
def is4949Prime(n: Int): Boolean = { | |
def loop(m: Int): Boolean = (m / 10, m % 10) match { | |
case (_, 4) | (_, 9) => true | |
case (0, _) => false | |
case (d, _) => loop(d) | |
} | |
loop(n) | |
} | |
def main(args: Array[String]): Unit = { | |
val n = args.head.toInt | |
println(primes.filter(is4949Prime).take(n).mkString(",")) | |
} | |
} | |
object EratosthenesSieveSolver extends Prime4949Solver { | |
def sieve(limit: Int): Stream[Int] = { | |
val bs = mutable.BitSet(limit) | |
(2 to limit) foreach (bs += _) | |
(2 to math.sqrt(limit).toInt) foreach { n => | |
(n * n to limit by n) foreach (bs -= _) | |
} | |
bs.toStream | |
} | |
override def primes = sieve(9999) | |
} | |
sealed trait PairingHeap { | |
def merge(another: PairingHeap): PairingHeap | |
} | |
case object Empty extends PairingHeap { | |
def merge(another: PairingHeap): PairingHeap = another | |
} | |
case class Tree(ns: Stream[Int], phs: List[PairingHeap]) extends PairingHeap { | |
private def join(t: Tree): PairingHeap = | |
if (ns.head <= t.ns.head) Tree(ns, t :: phs) else t.join(this) | |
def merge(another: PairingHeap): PairingHeap = another match { | |
case Empty => this | |
case t: Tree => join(t) | |
} | |
} | |
object PairingHeap { | |
def enqueue(ns: Stream[Int], q: PairingHeap): PairingHeap = Tree(ns, Nil) merge q | |
def mergeAll(phs: List[PairingHeap]): PairingHeap = phs match { | |
case Nil => Empty | |
case ph1 :: Nil => ph1 | |
case ph1 :: ph2 :: pht => ph1 merge ph2 merge mergeAll(pht) | |
} | |
} | |
object WheelSieveSolver extends Prime4949Solver { | |
import PairingHeap._ | |
private def spin(start: Int, wheel: Stream[Int]): Stream[Int] = { | |
def repeat: Stream[Int] = wheel append repeat | |
repeat.scan(start)(_ + _) | |
} | |
private def composites(ns: Stream[Int]): Stream[Int] = { | |
def loop(ms: Stream[Int]): Stream[Int] = (ns.head * ms.head) #:: loop(ms.tail) | |
loop(ns) | |
} | |
private def sieve(ns: Stream[Int], ph: PairingHeap): Stream[Int] = (ns, ph) match { | |
case (n #:: nt, Empty) => n #:: sieve(nt, enqueue(composites(ns), Empty)) | |
case (n #:: nt, Tree(m #:: ms, qs)) => | |
if (n < m) n #:: sieve(nt, enqueue(composites(ns), ph )) | |
else if (n > m) sieve(ns, enqueue(ms, mergeAll(qs))) | |
else sieve(nt, enqueue(ms, mergeAll(qs))) | |
} | |
override def primes: Stream[Int] = sieve(Stream(2, 3) append spin(5, Stream(2, 4)), Empty) | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment