Skip to content

Instantly share code, notes, and snippets.

@adacola
Last active August 1, 2018 13:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adacola/153ac2d54f80f238358e0d41863e5306 to your computer and use it in GitHub Desktop.
Save adacola/153ac2d54f80f238358e0d41863e5306 to your computer and use it in GitHub Desktop.
Miller-Rabin法を使った素数判定アルゴリズム
/// Miller-Rabin法を使った素数判定
let isPrime n =
let modPow x k m =
let rec loop result x k m =
if k = 0L then result else
let result = if k &&& 1L = 0L then result else result * x % m
let k = k / 2L
let x = x * x % m
loop result x k m
loop 1L x k m
if n < 2 then false else
let nL = int64 n
let d, s = (n - 1, 0) |> Seq.unfold (fun (d, s) -> Some((d, s), (d / 2, s + 1))) |> Seq.find (fun (d, _) -> d % 2 <> 0)
let rec check = function
| [] -> true
| a::_ when a = nL -> true
| a::rest when modPow a (int64 d) nL = 1L -> check rest
| a::rest when Seq.init s id |> Seq.exists (fun r -> modPow a (int64 d * (1L <<< r)) nL = nL - 1L) -> check rest
| _ -> false
check [2L; 7L; 61L]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment