Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

View file

@ -0,0 +1,3 @@
---
from: http://rosettacode.org/wiki/Fermat_numbers
note: Prime Numbers

View file

@ -0,0 +1,24 @@
In mathematics, a Fermat number, ''named after Pierre de Fermat who first studied them,'' is a positive integer of the form <big>'''F<sub>n</sub> = 2<sup>''2''<sup>''n''</sup></sup> + 1'''</big> where '''n''' is a non-negative integer.
Despite the simplicity of generating Fermat numbers, they have some powerful mathematical properties and are extensively used in cryptography & pseudo-random number generation, and are often linked to other number theoric fields.
As of this writing, (mid 2019), there are only five known prime Fermat numbers, the first five ('''F<sub>0</sub>''' through '''F<sub>4</sub>'''). Only the first twelve Fermat numbers have been completely factored, though many have been partially factored.
;Task:
:* Write a routine (function, procedure, whatever) to generate '''Fermat numbers'''.
:* Use the routine to find and display here, on this page, the first '''10 Fermat numbers''' - '''F<sub>0</sub>''' through '''F<sub>9</sub>'''.
:* Find and display here, on this page, the '''prime factors''' of as many Fermat numbers as you have patience for. (Or as many as can be found in five minutes or less of processing time). ''Note: if you make it past '''F<sub>11</sub>''', there may be money, and certainly will be acclaim in it for you.''
;See also:
:* '''[[wp:Fermat_number|Wikipedia - Fermat numbers]]'''
:* '''[[oeis:A000215|OEIS:A000215 - Fermat numbers]]'''
:* '''[[oeis:A019434|OEIS:A019434 - Fermat primes]]'''
<br>

View file

@ -0,0 +1,10 @@
nPowers: [1 2 4 8 16 32 64 128 256 512]
fermatSet: map 0..9 'x -> 1 + 2 ^ nPowers\[x]
loop 0..9 'i ->
print ["F(" i ") =" fermatSet\[i]]
print ""
loop 0..9 'i ->
print ["Prime factors of F(" i ") =" factors.prime fermatSet\[i]]

View file

@ -0,0 +1,83 @@
#include <iostream>
#include <vector>
#include <boost/integer/common_factor.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/multiprecision/miller_rabin.hpp>
typedef boost::multiprecision::cpp_int integer;
integer fermat(unsigned int n) {
unsigned int p = 1;
for (unsigned int i = 0; i < n; ++i)
p *= 2;
return 1 + pow(integer(2), p);
}
inline void g(integer& x, const integer& n) {
x *= x;
x += 1;
x %= n;
}
integer pollard_rho(const integer& n) {
integer x = 2, y = 2, d = 1, z = 1;
int count = 0;
for (;;) {
g(x, n);
g(y, n);
g(y, n);
d = abs(x - y);
z = (z * d) % n;
++count;
if (count == 100) {
d = gcd(z, n);
if (d != 1)
break;
z = 1;
count = 0;
}
}
if (d == n)
return 0;
return d;
}
std::vector<integer> get_prime_factors(integer n) {
std::vector<integer> factors;
for (;;) {
if (miller_rabin_test(n, 25)) {
factors.push_back(n);
break;
}
integer f = pollard_rho(n);
if (f == 0) {
factors.push_back(n);
break;
}
factors.push_back(f);
n /= f;
}
return factors;
}
void print_vector(const std::vector<integer>& factors) {
if (factors.empty())
return;
auto i = factors.begin();
std::cout << *i++;
for (; i != factors.end(); ++i)
std::cout << ", " << *i;
std::cout << '\n';
}
int main() {
std::cout << "First 10 Fermat numbers:\n";
for (unsigned int i = 0; i < 10; ++i)
std::cout << "F(" << i << ") = " << fermat(i) << '\n';
std::cout << "\nPrime factors:\n";
for (unsigned int i = 0; i < 9; ++i) {
std::cout << "F(" << i << "): ";
print_vector(get_prime_factors(fermat(i)));
}
return 0;
}

View file

@ -0,0 +1,41 @@
#include <stdlib.h>
#include <stdio.h>
#include <gmp.h>
void mpz_factors(mpz_t n) {
int factors = 0;
mpz_t s, m, p;
mpz_init(s), mpz_init(m), mpz_init(p);
mpz_set_ui(m, 3);
mpz_set(p, n);
mpz_sqrt(s, p);
while (mpz_cmp(m, s) < 0) {
if (mpz_divisible_p(p, m)) {
gmp_printf("%Zd ", m);
mpz_fdiv_q(p, p, m);
mpz_sqrt(s, p);
factors ++;
}
mpz_add_ui(m, m, 2);
}
if (factors == 0) printf("PRIME\n");
else gmp_printf("%Zd\n", p);
}
int main(int argc, char const *argv[]) {
mpz_t fermat;
mpz_init_set_ui(fermat, 3);
printf("F(0) = 3 -> PRIME\n");
for (unsigned i = 1; i < 10; i ++) {
mpz_sub_ui(fermat, fermat, 1);
mpz_mul(fermat, fermat, fermat);
mpz_add_ui(fermat, fermat, 1);
gmp_printf("F(%d) = %Zd -> ", i, fermat);
mpz_factors(fermat);
}
return 0;
}

View file

@ -0,0 +1,16 @@
(defun fermat-number (n)
"Return the n-th Fermat number"
(1+ (expt 2 (expt 2 n))) )
(defun factor (n &optional (acc '()))
"Return the list of factors of n"
(when (> n 1) (loop with max-d = (isqrt n)
for d = 2 then (if (evenp d) (1+ d) (+ d 2)) do
(cond ((> d max-d) (return (cons (list n 1) acc)))
((zerop (rem n d))
(return (factor (truncate n d) (if (eq d (caar acc))
(cons
(list (caar acc) (1+ (cadar acc)))
(cdr acc))
(cons (list d 1) acc)))))))))

View file

@ -0,0 +1,14 @@
require "big"
def factors(n)
factors = `factor #{n}`.split(' ')[1..-1].map(&.to_big_i)
factors.group_by(&.itself).map { |prime, exp| [prime, exp.size] }
end
def fermat(n); (1.to_big_i << (1 << n)) | 1 end
puts "Value for each Fermat Number F0 .. F9."
(0..9).each { |n| puts "F#{n} = #{fermat(n)}" }
puts
puts "Factors for each Fermat Number F0 .. F8."
(0..8).each { |n| puts "F#{n} = #{factors fermat(n)}" }

View file

@ -0,0 +1,15 @@
USING: formatting io kernel lists lists.lazy math math.functions
math.primes.factors sequences ;
: lfermats ( -- list )
0 lfrom [ [ 1 2 2 ] dip ^ ^ + ] lmap-lazy ;
CHAR: ₀ 10 lfermats ltake list>array [
"First 10 Fermat numbers:" print
[ dupd "F%c = %d\n" printf 1 + ] each drop nl
] [
"Factors of first few Fermat numbers:" print [
dupd factors dup length 1 = " (prime)" "" ?
"Factors of F%c: %[%d, %]%s\n" printf 1 +
] each drop
] 2bi

View file

@ -0,0 +1,361 @@
package main
import (
"fmt"
"github.com/jbarham/primegen"
"math"
"math/big"
"math/rand"
"sort"
"time"
)
const (
maxCurves = 10000
maxRnd = 1 << 31
maxB1 = uint64(43 * 1e7)
maxB2 = uint64(2 * 1e10)
)
var (
zero = big.NewInt(0)
one = big.NewInt(1)
two = big.NewInt(2)
three = big.NewInt(3)
four = big.NewInt(4)
five = big.NewInt(5)
)
// Uses algorithm in Wikipedia article, including speed-up.
func pollardRho(n *big.Int) (*big.Int, error) {
// g(x) = (x^2 + 1) mod n
g := func(x, n *big.Int) *big.Int {
x2 := new(big.Int)
x2.Mul(x, x)
x2.Add(x2, one)
return x2.Mod(x2, n)
}
x, y, d := new(big.Int).Set(two), new(big.Int).Set(two), new(big.Int).Set(one)
t, z := new(big.Int), new(big.Int).Set(one)
count := 0
for {
x = g(x, n)
y = g(g(y, n), n)
t.Sub(x, y)
t.Abs(t)
t.Mod(t, n)
z.Mul(z, t)
count++
if count == 100 {
d.GCD(nil, nil, z, n)
if d.Cmp(one) != 0 {
break
}
z.Set(one)
count = 0
}
}
if d.Cmp(n) == 0 {
return nil, fmt.Errorf("Pollard's rho failure")
}
return d, nil
}
// Gets all primes under 'n' - uses a Sieve of Atkin under the hood.
func getPrimes(n uint64) []uint64 {
pg := primegen.New()
var primes []uint64
for {
prime := pg.Next()
if prime < n {
primes = append(primes, prime)
} else {
break
}
}
return primes
}
// Computes Stage 1 and Stage 2 bounds.
func computeBounds(n *big.Int) (uint64, uint64) {
le := len(n.String())
var b1, b2 uint64
switch {
case le <= 30:
b1, b2 = 2000, 147396
case le <= 40:
b1, b2 = 11000, 1873422
case le <= 50:
b1, b2 = 50000, 12746592
case le <= 60:
b1, b2 = 250000, 128992510
case le <= 70:
b1, b2 = 1000000, 1045563762
case le <= 80:
b1, b2 = 3000000, 5706890290
default:
b1, b2 = maxB1, maxB2
}
return b1, b2
}
// Adds two specified P and Q points (in Montgomery form). Assumes R = P - Q.
func pointAdd(px, pz, qx, qz, rx, rz, n *big.Int) (*big.Int, *big.Int) {
t := new(big.Int).Sub(px, pz)
u := new(big.Int).Add(qx, qz)
u.Mul(t, u)
t.Add(px, pz)
v := new(big.Int).Sub(qx, qz)
v.Mul(t, v)
upv := new(big.Int).Add(u, v)
umv := new(big.Int).Sub(u, v)
x := new(big.Int).Mul(upv, upv)
x.Mul(x, rz)
if x.Cmp(n) >= 0 {
x.Mod(x, n)
}
z := new(big.Int).Mul(umv, umv)
z.Mul(z, rx)
if z.Cmp(n) >= 0 {
z.Mod(z, n)
}
return x, z
}
// Doubles a point P (in Montgomery form).
func pointDouble(px, pz, n, a24 *big.Int) (*big.Int, *big.Int) {
u2 := new(big.Int).Add(px, pz)
u2.Mul(u2, u2)
v2 := new(big.Int).Sub(px, pz)
v2.Mul(v2, v2)
t := new(big.Int).Sub(u2, v2)
x := new(big.Int).Mul(u2, v2)
if x.Cmp(n) >= 0 {
x.Mod(x, n)
}
z := new(big.Int).Mul(a24, t)
z.Add(v2, z)
z.Mul(t, z)
if z.Cmp(n) >= 0 {
z.Mod(z, n)
}
return x, z
}
// Multiplies a specified point P (in Montgomery form) by a specified scalar.
func scalarMultiply(k, px, pz, n, a24 *big.Int) (*big.Int, *big.Int) {
sk := fmt.Sprintf("%b", k)
lk := len(sk)
qx := new(big.Int).Set(px)
qz := new(big.Int).Set(pz)
rx, rz := pointDouble(px, pz, n, a24)
for i := 1; i < lk; i++ {
if sk[i] == '1' {
qx, qz = pointAdd(rx, rz, qx, qz, px, pz, n)
rx, rz = pointDouble(rx, rz, n, a24)
} else {
rx, rz = pointAdd(qx, qz, rx, rz, px, pz, n)
qx, qz = pointDouble(qx, qz, n, a24)
}
}
return qx, qz
}
// Lenstra's two-stage ECM algorithm.
func ecm(n *big.Int) (*big.Int, error) {
if n.Cmp(one) == 0 || n.ProbablyPrime(10) {
return n, nil
}
b1, b2 := computeBounds(n)
dd := uint64(math.Sqrt(float64(b2)))
beta := make([]*big.Int, dd+1)
for i := 0; i < len(beta); i++ {
beta[i] = new(big.Int)
}
s := make([]*big.Int, 2*dd+2)
for i := 0; i < len(s); i++ {
s[i] = new(big.Int)
}
// stage 1 and stage 2 precomputations
curves := 0
logB1 := math.Log(float64(b1))
primes := getPrimes(b2)
numPrimes := len(primes)
idxB1 := sort.Search(len(primes), func(i int) bool { return primes[i] >= b1 })
// compute a B1-powersmooth integer 'k'
k := big.NewInt(1)
for i := 0; i < idxB1; i++ {
p := primes[i]
bp := new(big.Int).SetUint64(p)
t := uint64(logB1 / math.Log(float64(p)))
bt := new(big.Int).SetUint64(t)
bt.Exp(bp, bt, nil)
k.Mul(k, bt)
}
g := big.NewInt(1)
for (g.Cmp(one) == 0 || g.Cmp(n) == 0) && curves <= maxCurves {
curves++
st := int64(6 + rand.Intn(maxRnd-5))
sigma := big.NewInt(st)
// generate a new random curve in Montgomery form with Suyama's parameterization
u := new(big.Int).Mul(sigma, sigma)
u.Sub(u, five)
u.Mod(u, n)
v := new(big.Int).Mul(four, sigma)
v.Mod(v, n)
vmu := new(big.Int).Sub(v, u)
a := new(big.Int).Mul(vmu, vmu)
a.Mul(a, vmu)
t := new(big.Int).Mul(three, u)
t.Add(t, v)
a.Mul(a, t)
t.Mul(four, u)
t.Mul(t, u)
t.Mul(t, u)
t.Mul(t, v)
a.Quo(a, t)
a.Sub(a, two)
a.Mod(a, n)
a24 := new(big.Int).Add(a, two)
a24.Quo(a24, four)
// stage 1
px := new(big.Int).Mul(u, u)
px.Mul(px, u)
t.Mul(v, v)
t.Mul(t, v)
px.Quo(px, t)
px.Mod(px, n)
pz := big.NewInt(1)
qx, qz := scalarMultiply(k, px, pz, n, a24)
g.GCD(nil, nil, n, qz)
// if stage 1 is successful, return a non-trivial factor else
// move on to stage 2
if g.Cmp(one) != 0 && g.Cmp(n) != 0 {
return g, nil
}
// stage 2
s[1], s[2] = pointDouble(qx, qz, n, a24)
s[3], s[4] = pointDouble(s[1], s[2], n, a24)
beta[1].Mul(s[1], s[2])
beta[1].Mod(beta[1], n)
beta[2].Mul(s[3], s[4])
beta[2].Mod(beta[2], n)
for d := uint64(3); d <= dd; d++ {
d2 := 2 * d
s[d2-1], s[d2] = pointAdd(s[d2-3], s[d2-2], s[1], s[2], s[d2-5], s[d2-4], n)
beta[d].Mul(s[d2-1], s[d2])
beta[d].Mod(beta[d], n)
}
g.SetUint64(1)
b := new(big.Int).SetUint64(b1 - 1)
rx, rz := scalarMultiply(b, qx, qz, n, a24)
t.Mul(two, new(big.Int).SetUint64(dd))
t.Sub(b, t)
tx, tz := scalarMultiply(t, qx, qz, n, a24)
q, step := idxB1, 2*dd
for r := b1 - 1; r < b2; r += step {
alpha := new(big.Int).Mul(rx, rz)
alpha.Mod(alpha, n)
limit := r + step
for q < numPrimes && primes[q] <= limit {
d := (primes[q] - r) / 2
t := new(big.Int).Sub(rx, s[2*d-1])
f := new(big.Int).Add(rz, s[2*d])
f.Mul(t, f)
f.Sub(f, alpha)
f.Add(f, beta[d])
g.Mul(g, f)
g.Mod(g, n)
q++
}
trx := new(big.Int).Set(rx)
trz := new(big.Int).Set(rz)
rx, rz = pointAdd(rx, rz, s[2*dd-1], s[2*dd], tx, tz, n)
tx.Set(trx)
tz.Set(trz)
}
g.GCD(nil, nil, n, g)
}
// no non-trivial factor found, return an error
if curves > maxCurves {
return zero, fmt.Errorf("maximum curves exceeded before a factor was found")
}
return g, nil
}
// find prime factors of 'n' using an appropriate method.
func primeFactors(n *big.Int) ([]*big.Int, error) {
var res []*big.Int
if n.ProbablyPrime(10) {
return append(res, n), nil
}
le := len(n.String())
var factor1 *big.Int
var err error
if le > 20 && le <= 60 {
factor1, err = ecm(n)
} else {
factor1, err = pollardRho(n)
}
if err != nil {
return nil, err
}
if !factor1.ProbablyPrime(10) {
return nil, fmt.Errorf("first factor is not prime")
}
factor2 := new(big.Int)
factor2.Quo(n, factor1)
if !factor2.ProbablyPrime(10) {
return nil, fmt.Errorf("%d (second factor is not prime)", factor1)
}
return append(res, factor1, factor2), nil
}
func fermatNumbers(n int) (res []*big.Int) {
f := new(big.Int).SetUint64(3) // 2^1 + 1
for i := 0; i < n; i++ {
t := new(big.Int).Set(f)
res = append(res, t)
f.Sub(f, one)
f.Mul(f, f)
f.Add(f, one)
}
return res
}
func main() {
start := time.Now()
rand.Seed(time.Now().UnixNano())
fns := fermatNumbers(10)
fmt.Println("First 10 Fermat numbers:")
for i, f := range fns {
fmt.Printf("F%c = %d\n", 0x2080+i, f)
}
fmt.Println("\nFactors of first 10 Fermat numbers:")
for i, f := range fns {
fmt.Printf("F%c = ", 0x2080+i)
factors, err := primeFactors(f)
if err != nil {
fmt.Println(err)
continue
}
for _, factor := range factors {
fmt.Printf("%d ", factor)
}
if len(factors) == 1 {
fmt.Println("- prime")
} else {
fmt.Println()
}
}
fmt.Printf("\nTook %s\n", time.Since(start))
}

View file

@ -0,0 +1,36 @@
import Data.Numbers.Primes (primeFactors)
import Data.Bool (bool)
fermat :: Integer -> Integer
fermat = succ . (2 ^) . (2 ^)
fermats :: [Integer]
fermats = fermat <$> [0 ..]
--------------------------- TEST ---------------------------
main :: IO ()
main =
mapM_
putStrLn
[ fTable "First 10 Fermats:" show show fermat [0 .. 9]
, fTable
"Factors of first 7:"
show
showFactors
primeFactors
(take 7 fermats)
]
------------------------- DISPLAY --------------------------
fTable :: String -> (a -> String) -> (b -> String) -> (a -> b) -> [a] -> String
fTable s xShow fxShow f xs =
unlines $
s : fmap (((++) . rjust w ' ' . xShow) <*> ((" -> " ++) . fxShow . f)) xs
where
rjust n c = drop . length <*> (replicate n c ++)
w = maximum (length . xShow <$> xs)
showFactors :: [Integer] -> String
showFactors x
| 1 < length x = show x
| otherwise = "(prime)"

View file

@ -0,0 +1,129 @@
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class FermatNumbers {
public static void main(String[] args) {
System.out.println("First 10 Fermat numbers:");
for ( int i = 0 ; i < 10 ; i++ ) {
System.out.printf("F[%d] = %s\n", i, fermat(i));
}
System.out.printf("%nFirst 12 Fermat numbers factored:%n");
for ( int i = 0 ; i < 13 ; i++ ) {
System.out.printf("F[%d] = %s\n", i, getString(getFactors(i, fermat(i))));
}
}
private static String getString(List<BigInteger> factors) {
if ( factors.size() == 1 ) {
return factors.get(0) + " (PRIME)";
}
return factors.stream().map(v -> v.toString()).map(v -> v.startsWith("-") ? "(C" + v.replace("-", "") + ")" : v).collect(Collectors.joining(" * "));
}
private static Map<Integer, String> COMPOSITE = new HashMap<>();
static {
COMPOSITE.put(9, "5529");
COMPOSITE.put(10, "6078");
COMPOSITE.put(11, "1037");
COMPOSITE.put(12, "5488");
COMPOSITE.put(13, "2884");
}
private static List<BigInteger> getFactors(int fermatIndex, BigInteger n) {
List<BigInteger> factors = new ArrayList<>();
BigInteger factor = BigInteger.ONE;
while ( true ) {
if ( n.isProbablePrime(100) ) {
factors.add(n);
break;
}
else {
if ( COMPOSITE.containsKey(fermatIndex) ) {
String stop = COMPOSITE.get(fermatIndex);
if ( n.toString().startsWith(stop) ) {
factors.add(new BigInteger("-" + n.toString().length()));
break;
}
}
factor = pollardRhoFast(n);
if ( factor.compareTo(BigInteger.ZERO) == 0 ) {
factors.add(n);
break;
}
else {
factors.add(factor);
n = n.divide(factor);
}
}
}
return factors;
}
private static final BigInteger TWO = BigInteger.valueOf(2);
private static BigInteger fermat(int n) {
return TWO.pow((int)Math.pow(2, n)).add(BigInteger.ONE);
}
// See: https://en.wikipedia.org/wiki/Pollard%27s_rho_algorithm
@SuppressWarnings("unused")
private static BigInteger pollardRho(BigInteger n) {
BigInteger x = BigInteger.valueOf(2);
BigInteger y = BigInteger.valueOf(2);
BigInteger d = BigInteger.ONE;
while ( d.compareTo(BigInteger.ONE) == 0 ) {
x = pollardRhoG(x, n);
y = pollardRhoG(pollardRhoG(y, n), n);
d = x.subtract(y).abs().gcd(n);
}
if ( d.compareTo(n) == 0 ) {
return BigInteger.ZERO;
}
return d;
}
// Includes Speed Up of 100 multiples and 1 GCD, instead of 100 multiples and 100 GCDs.
// See Variants section of Wikipedia article.
// Testing F[8] = 1238926361552897 * Prime
// This variant = 32 sec.
// Standard algorithm = 107 sec.
private static BigInteger pollardRhoFast(BigInteger n) {
long start = System.currentTimeMillis();
BigInteger x = BigInteger.valueOf(2);
BigInteger y = BigInteger.valueOf(2);
BigInteger d = BigInteger.ONE;
int count = 0;
BigInteger z = BigInteger.ONE;
while ( true ) {
x = pollardRhoG(x, n);
y = pollardRhoG(pollardRhoG(y, n), n);
d = x.subtract(y).abs();
z = z.multiply(d).mod(n);
count++;
if ( count == 100 ) {
d = z.gcd(n);
if ( d.compareTo(BigInteger.ONE) != 0 ) {
break;
}
z = BigInteger.ONE;
count = 0;
}
}
long end = System.currentTimeMillis();
System.out.printf(" Pollard rho try factor %s elapsed time = %d ms (factor = %s).%n", n, (end-start), d);
if ( d.compareTo(n) == 0 ) {
return BigInteger.ZERO;
}
return d;
}
private static BigInteger pollardRhoG(BigInteger x, BigInteger n) {
return x.multiply(x).add(BigInteger.ONE).mod(n);
}
}

View file

@ -0,0 +1,32 @@
# To take advantage of gojq's arbitrary-precision integer arithmetic:
def power($b): . as $in | reduce range(0;$b) as $i (1; . * $in);
def gcd(a; b):
# subfunction expects [a,b] as input
# i.e. a ~ .[0] and b ~ .[1]
def rgcd: if .[1] == 0 then .[0]
else [.[1], .[0] % .[1]] | rgcd
end;
[a,b] | rgcd;
# This is fast because the state of `until` is just a number
def is_prime:
. as $n
| if ($n < 2) then false
elif ($n % 2 == 0) then $n == 2
elif ($n % 3 == 0) then $n == 3
elif ($n % 5 == 0) then $n == 5
elif ($n % 7 == 0) then $n == 7
elif ($n % 11 == 0) then $n == 11
elif ($n % 13 == 0) then $n == 13
elif ($n % 17 == 0) then $n == 17
elif ($n % 19 == 0) then $n == 19
elif ($n % 23 == 0) then $n == 23
elif ($n % 29 == 0) then $n == 29
elif ($n % 31 == 0) then $n == 31
elif ($n % 37 == 0) then $n == 37
elif ($n % 41 == 0) then $n == 41
else 43
| until( (. * .) > $n or ($n % . == 0); . + 2)
| . * . > $n
end;

View file

@ -0,0 +1,37 @@
def fermat:
. as $n
| (2 | power( 2 | power($n))) + 1;
# https://en.wikipedia.org/wiki/Pollard%27s_rho_algorithm
def pollardRho($x):
. as $n
| def g: (.*. + 1) % $n ;
{x:$x, y:$x, d:1}
| until(.d != 1;
.x |= g
| .y |= (g|g)
| .d = gcd((.x - .y)|length; $n) )
| if .d == $n then 0
else .d
end ;
def rhoPrimeFactors:
. as $n
| pollardRho(2)
| if . == 0
then [$n, 1]
else [., ($n / .)]
end ;
"The first 10 Fermat numbers are:",
[ range(0;10) | fermat ] as $fns
| (range(0;10) | "F\(.) is \($fns[.])"),
("\nFactors of the first 7 Fermat numbers:",
range(0;7) as $i
| $fns[$i]
| rhoPrimeFactors as $factors
| if $factors[1] == 1
then "F\($i) : rho-prime", " ... => \(if is_prime then "prime" else "not" end)"
else "F\($i) => \($factors)"
end )

View file

@ -0,0 +1,20 @@
using Primes
fermat(n) = BigInt(2)^(BigInt(2)^n) + 1
prettyprint(fdict) = replace(replace(string(fdict), r".+\(([^)]+)\)" => s"\1"), r"\=\>" => "^")
function factorfermats(max, nofactor=false)
for n in 0:max
fm = fermat(n)
if nofactor
println("Fermat number F($n) is $fm.")
continue
end
factors = factor(fm)
println("Fermat number F($n), $fm, ",
length(factors) < 2 ? "is prime." : "factors to $(prettyprint(factors)).")
end
end
factorfermats(9, true)
factorfermats(10)

View file

@ -0,0 +1,122 @@
import java.math.BigInteger
import kotlin.math.pow
fun main() {
println("First 10 Fermat numbers:")
for (i in 0..9) {
println("F[$i] = ${fermat(i)}")
}
println()
println("First 12 Fermat numbers factored:")
for (i in 0..12) {
println("F[$i] = ${getString(getFactors(i, fermat(i)))}")
}
}
private fun getString(factors: List<BigInteger>): String {
return if (factors.size == 1) {
"${factors[0]} (PRIME)"
} else factors.map { it.toString() }
.joinToString(" * ") {
if (it.startsWith("-"))
"(C" + it.replace("-", "") + ")"
else it
}
}
private val COMPOSITE = mutableMapOf(
9 to "5529",
10 to "6078",
11 to "1037",
12 to "5488",
13 to "2884"
)
private fun getFactors(fermatIndex: Int, n: BigInteger): List<BigInteger> {
var n2 = n
val factors: MutableList<BigInteger> = ArrayList()
var factor: BigInteger
while (true) {
if (n2.isProbablePrime(100)) {
factors.add(n2)
break
} else {
if (COMPOSITE.containsKey(fermatIndex)) {
val stop = COMPOSITE[fermatIndex]
if (n2.toString().startsWith(stop!!)) {
factors.add(BigInteger("-" + n2.toString().length))
break
}
}
//factor = pollardRho(n)
factor = pollardRhoFast(n)
n2 = if (factor.compareTo(BigInteger.ZERO) == 0) {
factors.add(n2)
break
} else {
factors.add(factor)
n2.divide(factor)
}
}
}
return factors
}
private val TWO = BigInteger.valueOf(2)
private fun fermat(n: Int): BigInteger {
return TWO.pow(2.0.pow(n.toDouble()).toInt()).add(BigInteger.ONE)
}
// See: https://en.wikipedia.org/wiki/Pollard%27s_rho_algorithm
@Suppress("unused")
private fun pollardRho(n: BigInteger): BigInteger {
var x = BigInteger.valueOf(2)
var y = BigInteger.valueOf(2)
var d = BigInteger.ONE
while (d.compareTo(BigInteger.ONE) == 0) {
x = pollardRhoG(x, n)
y = pollardRhoG(pollardRhoG(y, n), n)
d = (x - y).abs().gcd(n)
}
return if (d.compareTo(n) == 0) {
BigInteger.ZERO
} else d
}
// Includes Speed Up of 100 multiples and 1 GCD, instead of 100 multiples and 100 GCDs.
// See Variants section of Wikipedia article.
// Testing F[8] = 1238926361552897 * Prime
// This variant = 32 sec.
// Standard algorithm = 107 sec.
private fun pollardRhoFast(n: BigInteger): BigInteger {
val start = System.currentTimeMillis()
var x = BigInteger.valueOf(2)
var y = BigInteger.valueOf(2)
var d: BigInteger
var count = 0
var z = BigInteger.ONE
while (true) {
x = pollardRhoG(x, n)
y = pollardRhoG(pollardRhoG(y, n), n)
d = (x - y).abs()
z = (z * d).mod(n)
count++
if (count == 100) {
d = z.gcd(n)
if (d.compareTo(BigInteger.ONE) != 0) {
break
}
z = BigInteger.ONE
count = 0
}
}
val end = System.currentTimeMillis()
println(" Pollard rho try factor $n elapsed time = ${end - start} ms (factor = $d).")
return if (d.compareTo(n) == 0) {
BigInteger.ZERO
} else d
}
private fun pollardRhoG(x: BigInteger, n: BigInteger): BigInteger {
return (x * x + BigInteger.ONE).mod(n)
}

View file

@ -0,0 +1,28 @@
val .fermat = f 2 ^ 2 ^ .n + 1
val .factors = f(var .x) {
for[.f=[]] .i, .s = 2, truncate .x ^/ 2; .i < .s; .i += 1 {
if .x div .i {
.f ~= [.i]
.x \= .i
.s = truncate .x ^/ 2
}
} ~ [.x]
}
writeln "first 10 Fermat numbers"
for .i in 0..9 {
writeln $"F\(.i + 16x2080:cp) = \(.fermat(.i))"
}
writeln()
writeln "factors of first few Fermat numbers"
for .i in 0..9 {
val .ferm = .fermat(.i)
val .fac = .factors(.ferm)
if len(.fac) == 1 {
writeln $"F\(.i + 16x2080:cp) is prime"
} else {
writeln $"F\(.i + 16x2080:cp) factors: ", .fac
}
}

View file

@ -0,0 +1,4 @@
ClearAll[Fermat]
Fermat[n_] := 2^(2^n) + 1
Fermat /@ Range[0, 9]
Scan[FactorInteger /* Print, %]

View file

@ -0,0 +1,112 @@
import math
import bignum
import strformat
import strutils
import tables
import times
const Composite = {9: "5529", 10: "6078", 11: "1037", 12: "5488", 13: "2884"}.toTable
const Subscripts = ["", "", "", "", "", "", "", "", "", ""]
let One = newInt(1)
#---------------------------------------------------------------------------------------------------
func fermat(n: int): Int {.inline.} = 2^(culong(2^n)) + 1
#---------------------------------------------------------------------------------------------------
template isProbablyPrime(n: Int): bool = n.probablyPrime(25) != 0
#---------------------------------------------------------------------------------------------------
func pollardRhoG(x, n: Int): Int {.inline.} = (x * x + 1) mod n
#---------------------------------------------------------------------------------------------------
proc pollardRhoFast(n: Int): Int =
let start = getTime()
var
x = newInt(2)
y = newInt(2)
count = 0
z = One
while true:
x = pollardRhoG(x, n)
y = pollardRhoG(pollardRhoG(y, n), n)
result = abs(x - y)
z = z * result mod n
inc count
if count == 100:
result = gcd(z, n)
if result != One: break
z = One
count = 0
let duration = (getTime() - start).inMilliseconds
echo fmt" Pollard rho try factor {n} elapsed time = {duration} ms (factor = {result})."
if result == n:
result = newInt(0)
#---------------------------------------------------------------------------------------------------
proc factors(fermatIndex: int; n: Int): seq[Int] =
var n = n
var factor: Int
while true:
if n.isProbablyPrime():
result.add(n)
break
if fermatIndex in Composite:
let stop = Composite[fermatIndex]
let s = $n
if s.startsWith(stop):
result.add(newInt(-s.len))
break
factor = pollardRhoFast(n)
if factor.isZero():
result.add(n)
break
result.add(factor)
n = n div factor
#---------------------------------------------------------------------------------------------------
func `$`(factors: seq[Int]): string =
if factors.len == 1:
result = fmt"{factors[0]} (PRIME)"
else:
result = $factors[0]
let start = result.high
for factor in factors[1..^1]:
result.addSep(" * ", start)
result.add(if factor < 0: fmt"(C{-factor})" else: $factor)
#---------------------------------------------------------------------------------------------------
func subscript(n: Natural): string =
var n = n
while true:
result.insert(Subscripts[n mod 10], 0)
n = n div 10
if n == 0: break
#———————————————————————————————————————————————————————————————————————————————————————————————————
echo "First 10 Fermat numbers:"
for i in 0..9:
echo fmt"F{subscript(i)} = {fermat(i)}"
echo ""
echo "First 12 Fermat numbers factored:"
for i in 0..12:
echo fmt"F{subscript(i)} = {factors(i, fermat(i))}"

View file

@ -0,0 +1,17 @@
use strict;
use warnings;
use feature 'say';
use bigint try=>"GMP";
use ntheory qw<factor>;
my @Fermats = map { 2**(2**$_) + 1 } 0..9;
my $sub = 0;
say 'First 10 Fermat numbers:';
printf "F%s = %s\n", $sub++, $_ for @Fermats;
$sub = 0;
say "\nFactors of first few Fermat numbers:";
for my $f (map { [factor($_)] } @Fermats[0..8]) {
printf "Factors of F%s: %s\n", $sub++, @$f == 1 ? 'prime' : join ' ', @$f
}

View file

@ -0,0 +1,51 @@
(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #000080;font-style:italic;">-- demo\rosetta\Fermat.exw</span>
<span style="color: #008080;">include</span> <span style="color: #004080;">mpfr</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">fermat</span><span style="color: #0000FF;">(</span><span style="color: #004080;">mpz</span> <span style="color: #000000;">res</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">pn</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">mpz_ui_pow_ui</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">pn</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">mpz_add_si</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #004080;">mpz</span> <span style="color: #000000;">fn</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_init</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">lim</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()=</span><span style="color: #004600;">JS</span><span style="color: #0000FF;">?</span><span style="color: #000000;">18</span><span style="color: #0000FF;">:</span><span style="color: #000000;">29</span><span style="color: #0000FF;">),</span> <span style="color: #000080;font-style:italic;">-- (see note)</span>
<span style="color: #000000;">print_lim</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()=</span><span style="color: #004600;">JS</span><span style="color: #0000FF;">?</span><span style="color: #000000;">16</span><span style="color: #0000FF;">:</span><span style="color: #000000;">20</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">lim</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">fermat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">i</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">print_lim</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"F%d = %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">shorten</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">mpz_get_str</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">))})</span>
<span style="color: #008080;">else</span> <span style="color: #000080;font-style:italic;">-- (since printing it takes too long...)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"F%d has %,d digits\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">mpz_sizeinbase</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">flimit</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()=</span><span style="color: #004600;">JS</span><span style="color: #0000FF;">?</span><span style="color: #000000;">11</span><span style="color: #0000FF;">:</span><span style="color: #000000;">13</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">flimit</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">fermat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">f</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_prime_factors</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">200000</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">fs</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">ts</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">elapsed</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">f</span><span style="color: #0000FF;">[$])=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> <span style="color: #000080;font-style:italic;">-- (as per docs)</span>
<span style="color: #7060A8;">mpz_set_str</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">,</span><span style="color: #000000;">f</span><span style="color: #0000FF;">[$][</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #7060A8;">mpz_prime</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">f</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">fs</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">" (not prime)"</span>
<span style="color: #008080;">else</span>
<span style="color: #000000;">fs</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">" (last factor is not prime)"</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">f</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">f</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">f</span><span style="color: #0000FF;">[$][</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">shorten</span><span style="color: #0000FF;">(</span><span style="color: #000000;">f</span><span style="color: #0000FF;">[$][</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">elsif</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">f</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">1</span>
<span style="color: #008080;">and</span> <span style="color: #7060A8;">mpz_prime</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">fs</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">" (prime)"</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">fs</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_factorstring</span><span style="color: #0000FF;">(</span><span style="color: #000000;">f</span><span style="color: #0000FF;">)&</span><span style="color: #000000;">fs</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Factors of F%d: %s [%s]\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">fs</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ts</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--

View file

@ -0,0 +1,100 @@
(seed (in "/dev/urandom" (rd 8)))
(de **Mod (X Y N)
(let M 1
(loop
(when (bit? 1 Y)
(setq M (% (* M X) N)) )
(T (=0 (setq Y (>> 1 Y)))
M )
(setq X (% (* X X) N)) ) ) )
(de isprime (N)
(cache '(NIL) N
(if (== N 2)
T
(and
(> N 1)
(bit? 1 N)
(let (Q (dec N) N1 (dec N) K 0 X)
(until (bit? 1 Q)
(setq
Q (>> 1 Q)
K (inc K) ) )
(catch 'composite
(do 16
(loop
(setq X
(**Mod
(rand 2 (min (dec N) 1000000000000))
Q
N ) )
(T (or (=1 X) (= X N1)))
(T
(do K
(setq X (**Mod X 2 N))
(when (=1 X) (throw 'composite))
(T (= X N1) T) ) )
(throw 'composite) ) )
(throw 'composite T) ) ) ) ) ) )
(de gcd (A B)
(until (=0 B)
(let M (% A B)
(setq A B B M) ) )
(abs A) )
(de g (A)
(% (+ (% (* A A) N) C) N) )
(de pollard-brent (N)
(let
(A (dec N)
Y (rand 1 (min A 1000000000000000000))
C (rand 1 (min A 1000000000000000000))
M (rand 1 (min A 1000000000000000000))
G 1
R 1
Q 1 )
(ifn (bit? 1 N)
2
(loop
(NIL (=1 G))
(setq X Y)
(do R
(setq Y (g Y)) )
(zero K)
(loop
(NIL (and (> R K) (=1 G)))
(setq YS Y)
(do (min M (- R K))
(setq
Y (g Y)
Q (% (* Q (abs (- X Y))) N) ) )
(setq
G (gcd Q N)
K (+ K M) )
)
(setq R (* R 2)) )
(when (== G N)
(loop
(NIL (> G 1))
(setq
YS (g YS)
G (gcd (abs (- X YS)) N) ) ) )
(if (== G N)
NIL
G ) ) ) )
(de factors (N)
(sort
(make
(loop
(setq N (/ N (link (pollard-brent N))))
(T (isprime N)) )
(link N) ) ) )
(de fermat (N)
(inc (** 2 (** 2 N))) )
(for (N 0 (>= 8 N) (inc N))
(println N ': (fermat N)) )
(prinl)
(for (N 0 (>= 8 N) (inc N))
(let N (fermat N)
(println
N
':
(if (isprime N) 'PRIME (factors N)) ) ) )

View file

@ -0,0 +1,26 @@
def factors(x):
factors = []
i = 2
s = int(x ** 0.5)
while i < s:
if x % i == 0:
factors.append(i)
x = int(x / i)
s = int(x ** 0.5)
i += 1
factors.append(x)
return factors
print("First 10 Fermat numbers:")
for i in range(10):
fermat = 2 ** 2 ** i + 1
print("F{} = {}".format(chr(i + 0x2080) , fermat))
print("\nFactors of first few Fermat numbers:")
for i in range(10):
fermat = 2 ** 2 ** i + 1
fac = factors(fermat)
if len(fac) == 1:
print("F{} -> IS PRIME".format(chr(i + 0x2080)))
else:
print("F{} -> FACTORS: {}".format(chr(i + 0x2080), fac))

View file

@ -0,0 +1,137 @@
'''Fermat numbers'''
from itertools import count, islice
from math import floor, sqrt
# fermat :: Int -> Int
def fermat(n):
'''Nth Fermat number.
Nth term of OEIS A000215.
'''
return 1 + (2 ** (2 ** n))
# fermats :: () -> [Int]
def fermats():
'''Non-finite series of Fermat numbers.
OEIS A000215.
'''
return (fermat(x) for x in enumFrom(0))
# --------------------------TEST---------------------------
# main :: IO ()
def main():
'''First 10 Fermats, and factors of first 7.'''
print(
fTable('First ten Fermat numbers:')(str)(str)(
fermat
)(enumFromTo(0)(9))
)
print(
fTable('\n\nFactors of first seven:')(str)(
lambda xs: repr(xs) if 1 < len(xs) else '(prime)'
)(primeFactors)(
take(7)(fermats())
)
)
# -------------------------DISPLAY-------------------------
# fTable :: String -> (a -> String) ->
# (b -> String) -> (a -> b) -> [a] -> String
def fTable(s):
'''Heading -> x display function -> fx display function ->
f -> xs -> tabular string.
'''
def go(xShow, fxShow, f, xs):
ys = [xShow(x) for x in xs]
w = max(map(len, ys))
return s + '\n' + '\n'.join(map(
lambda x, y: y.rjust(w, ' ') + ' -> ' + fxShow(f(x)),
xs, ys
))
return lambda xShow: lambda fxShow: lambda f: lambda xs: go(
xShow, fxShow, f, xs
)
# -------------------------GENERIC-------------------------
# enumFrom :: Enum a => a -> [a]
def enumFrom(x):
'''A non-finite stream of enumerable values,
starting from the given value.
'''
return count(x) if isinstance(x, int) else (
map(chr, count(ord(x)))
)
# enumFromTo :: Int -> Int -> [Int]
def enumFromTo(m):
'''Enumeration of integer values [m..n]'''
def go(n):
return list(range(m, 1 + n))
return lambda n: go(n)
# primeFactors :: Int -> [Int]
def primeFactors(n):
'''A list of the prime factors of n.
'''
def f(qr):
r = qr[1]
return step(r), 1 + r
def step(x):
return 1 + (x << 2) - ((x >> 1) << 1)
def go(x):
root = floor(sqrt(x))
def p(qr):
q = qr[0]
return root < q or 0 == (x % q)
q = until(p)(f)(
(2 if 0 == x % 2 else 3, 1)
)[0]
return [x] if q > root else [q] + go(x // q)
return go(n)
# take :: Int -> [a] -> [a]
# take :: Int -> String -> String
def take(n):
'''The prefix of xs of length n,
or xs itself if n > length xs.
'''
return lambda xs: (
xs[0:n]
if isinstance(xs, (list, tuple))
else list(islice(xs, n))
)
# until :: (a -> Bool) -> (a -> a) -> a -> a
def until(p):
'''The result of repeatedly applying f until p holds.
The initial seed value is x.
'''
def go(f, x):
v = x
while not p(v):
v = f(v)
return v
return lambda f: lambda x: go(f, x)
# MAIN ---
if __name__ == '__main__':
main()

View file

@ -0,0 +1,33 @@
/*REXX program to find and display Fermat numbers, and show factors of Fermat numbers.*/
parse arg n . /*obtain optional argument from the CL.*/
if n=='' | n=="," then n= 9 /*Not specified? Then use the default.*/
numeric digits 20 /*ensure enough decimal digits, for n=9*/
do j=0 to n; f= 2** (2**j) + 1 /*calculate a series of Fermat numbers.*/
say right('F'j, length(n) + 1)': ' f /*display a particular " " */
end /*j*/
say
do k=0 to n; f= 2** (2**k) + 1; say /*calculate a series of Fermat numbers.*/
say center(' F'k": " f' ', 79, "") /*display a particular " " */
p= factr(f) /*factor a Fermat number, given time. */
if words(p)==1 then say f ' is prime.'
else say 'factors: ' p
end /*k*/
exit 0 /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
factr: procedure; parse arg x 1 z,,?
do k=1 to 11 by 2; j= k; if j==1 then j= 2; if j==9 then iterate
call build /*add J to the factors list. */
end /*k*/ /* [↑] factor X with some low primes*/
do y=0 by 2; j= j + 2 + y // 4 /*ensure not ÷ by three. */
parse var j '' -1 _; if _==5 then iterate /*last digit a "5"? Skip it.*/
if j*j>x | j>z then leave
call build /*add Y to the factors list. */
end /*y*/ /* [↑] factor X with other higher #s*/
j= z
if z\==1 then ?= build()
if ?='' then do; @.1= x; ?= x; #= 1; end
return ?
/*──────────────────────────────────────────────────────────────────────────────────────*/
build: do while z//j==0; z= z % j; ?= ? j; end; return strip(?)

View file

@ -0,0 +1,36 @@
/*REXX program to find and display Fermat numbers, and show factors of Fermat numbers.*/
parse arg n . /*obtain optional argument from the CL.*/
if n=='' | n=="," then n= 9 /*Not specified? Then use the default.*/
numeric digits 200 /*ensure enough decimal digits, for n=9*/
do j=0 to n; f= 2** (2**j) + 1 /*calculate a series of Fermat numbers.*/
say right('F'j, length(n) + 1)': ' f /*display a particular " " */
end /*j*/
say
do k=5 to n; f= 2** (2**k) + 1; say /*calculate a series of Fermat numbers.*/
say center(' F'k": " f' ', 79, "") /*display a particular " " */
a= rho(f) /*factor a Fermat number, given time. */
b= f % a
if a==b then say f ' is prime.'
else say 'factors: ' commas(a) " " commas(b)
end /*k*/
exit 0 /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
commas: parse arg _; do ?=length(_)-3 to 1 by -3; _=insert(',', _, ?); end; return _
/*──────────────────────────────────────────────────────────────────────────────────────*/
rho: procedure; parse arg n; y= 2; d= 1 /*initialize X, Y, and D variables.*/
do x=2 until d==n /*try rho method with X=2 for 1st time.*/
do while d==1
x= (x*x + 1) // n
v= (y*y + 1) // n
y= (v*v + 1) // n
parse value x-y with xy 1 sig 2 /*obtain sign of the x-y difference. */
if sig=='-' then parse var xy 2 xy /*Negative? Then use absolute value. */
nn= n
do until nn==0
parse value xy//nn nn with nn xy /*assign two variables: NN and XY */
end /*until*/ /*this is an in-line GCD function. */
d= xy /*assign variable D with a new XY */
end /*while*/
end /*x*/
return d /*found a factor of N. Return it.*/

View file

@ -0,0 +1,13 @@
use ntheory:from<Perl5> <factor>;
my @Fermats = (^Inf).map: 2 ** 2 ** * + 1;
my $sub = '';
say "First 10 Fermat numbers:";
printf "F%s = %s\n", $sub++, $_ for @Fermats[^10];
$sub = '';
say "\nFactors of first few Fermat numbers:";
for @Fermats[^9].map( {"$_".&factor} ) -> $f {
printf "Factors of F%s: %s %s\n", $sub++, $f.join(' '), $f.elems == 1 ?? '- prime' !! ''
}

View file

@ -0,0 +1,21 @@
decimals(0)
load "stdlib.ring"
see "working..." + nl
see "The first 10 Fermat numbers are:" + nl
num = 0
limit = 9
for n = 0 to limit
fermat = pow(2,pow(2,n)) + 1
mod = fermat%2
if n > 5
ferm = string(fermat)
tmp = number(right(ferm,1))+1
fermat = left(ferm,len(ferm)-1) + string(tmp)
ok
see "F(" + n + ") = " + fermat + nl
next
see "done..." + nl

View file

@ -0,0 +1,13 @@
def factors(n)
factors = `factor #{n}`.split(' ')[1..-1].map(&:to_i)
factors.group_by { _1 }.map { |prime, exp| [prime, exp.size] } # Ruby 2.7 or later
#factors.group_by { |prime| prime }.map { |prime, exp| [prime, exp.size] } # for all versions
end
def fermat(n); (1 << (1 << n)) | 1 end
puts "Value for each Fermat Number F0 .. F9."
(0..9).each { |n| puts "F#{n} = #{fermat(n)}" }
puts
puts "Factors for each Fermat Number F0 .. F8."
(0..8).each { |n| puts "F#{n} = #{factors fermat(n)}" }

View file

@ -0,0 +1,57 @@
struct DivisorGen {
curr: u64,
last: u64,
}
impl Iterator for DivisorGen {
type Item = u64;
fn next(&mut self) -> Option<u64> {
self.curr += 2u64;
if self.curr < self.last{
None
} else {
Some(self.curr)
}
}
}
fn divisor_gen(num : u64) -> DivisorGen {
DivisorGen { curr: 0u64, last: (num / 2u64) + 1u64 }
}
fn is_prime(num : u64) -> bool{
if num == 2 || num == 3 {
return true;
} else if num % 2 == 0 || num % 3 == 0 || num <= 1{
return false;
}else{
for i in divisor_gen(num){
if num % i == 0{
return false;
}
}
}
return true;
}
fn main() {
let fermat_closure = |i : u32| -> u64 {2u64.pow(2u32.pow(i + 1u32))};
let mut f_numbers : Vec<u64> = Vec::new();
println!("First 4 Fermat numbers:");
for i in 0..4 {
let f = fermat_closure(i) + 1u64;
f_numbers.push(f);
println!("F{}: {}", i, f);
}
println!("Factor of the first four numbers:");
for f in f_numbers.iter(){
let is_prime : bool = f % 4 == 1 && is_prime(*f);
let not_or_not = if is_prime {" "} else {" not "};
println!("{} is{}prime", f, not_or_not);
}
}

View file

@ -0,0 +1,78 @@
// [dependencies]
// rug = "1.9"
use rug::Integer;
fn fermat(n: u32) -> Integer {
Integer::from(Integer::u_pow_u(2, 2u32.pow(n))) + 1
}
fn g(x: Integer, n: &Integer) -> Integer {
(Integer::from(&x * &x) + 1) % n
}
fn pollard_rho(n: &Integer) -> Integer {
use rug::Assign;
let mut x = Integer::from(2);
let mut y = Integer::from(2);
let mut d = Integer::from(1);
let mut z = Integer::from(1);
let mut count = 0;
loop {
x = g(x, n);
y = g(g(y, n), n);
d.assign(&x - &y);
d = d.abs();
z *= &d;
z %= n;
count += 1;
if count == 100 {
d.assign(z.gcd_ref(n));
if d != 1 {
break;
}
z.assign(1);
count = 0;
}
}
if d == *n {
return Integer::from(0);
}
d
}
fn get_prime_factors(n: &Integer) -> Vec<Integer> {
use rug::integer::IsPrime;
let mut factors = Vec::new();
let mut m = Integer::from(n);
loop {
if m.is_probably_prime(25) != IsPrime::No {
factors.push(m);
break;
}
let f = pollard_rho(&m);
if f == 0 {
factors.push(m);
break;
}
factors.push(Integer::from(&f));
m = m / f;
}
factors
}
fn main() {
for i in 0..10 {
println!("F({}) = {}", i, fermat(i));
}
println!("\nPrime factors:");
for i in 0..9 {
let f = get_prime_factors(&fermat(i));
print!("F({}): {}", i, f[0]);
for j in 1..f.len() {
print!(", {}", f[j]);
}
println!();
}
}

View file

@ -0,0 +1,106 @@
import scala.collection.mutable
import scala.collection.mutable.ListBuffer
object FermatNumbers {
def main(args: Array[String]): Unit = {
println("First 10 Fermat numbers:")
for (i <- 0 to 9) {
println(f"F[$i] = ${fermat(i)}")
}
println()
println("First 12 Fermat numbers factored:")
for (i <- 0 to 12) {
println(f"F[$i] = ${getString(getFactors(i, fermat(i)))}")
}
}
private val TWO = BigInt(2)
def fermat(n: Int): BigInt = {
TWO.pow(math.pow(2.0, n).intValue()) + 1
}
def getString(factors: List[BigInt]): String = {
if (factors.size == 1) {
return s"${factors.head} (PRIME)"
}
factors.map(a => a.toString)
.map(a => if (a.startsWith("-")) "(C" + a.replace("-", "") + ")" else a)
.reduce((a, b) => a + " * " + b)
}
val COMPOSITE: mutable.Map[Int, String] = scala.collection.mutable.Map(
9 -> "5529",
10 -> "6078",
11 -> "1037",
12 -> "5488",
13 -> "2884"
)
def getFactors(fermatIndex: Int, n: BigInt): List[BigInt] = {
var n2 = n
var factors = new ListBuffer[BigInt]
var loop = true
while (loop) {
if (n2.isProbablePrime(100)) {
factors += n2
loop = false
} else {
if (COMPOSITE.contains(fermatIndex)) {
val stop = COMPOSITE(fermatIndex)
if (n2.toString.startsWith(stop)) {
factors += -n2.toString().length
loop = false
}
}
if (loop) {
val factor = pollardRhoFast(n2)
if (factor == 0) {
factors += n2
loop = false
} else {
factors += factor
n2 = n2 / factor
}
}
}
}
factors.toList
}
def pollardRhoFast(n: BigInt): BigInt = {
var x = BigInt(2)
var y = BigInt(2)
var z = BigInt(1)
var d = BigInt(1)
var count = 0
var loop = true
while (loop) {
x = pollardRhoG(x, n)
y = pollardRhoG(pollardRhoG(y, n), n)
d = (x - y).abs
z = (z * d) % n
count += 1
if (count == 100) {
d = z.gcd(n)
if (d != 1) {
loop = false
} else {
z = BigInt(1)
count = 0
}
}
}
println(s" Pollard rho try factor $n")
if (d == n) {
return 0
}
d
}
def pollardRhoG(x: BigInt, n: BigInt): BigInt = ((x * x) + 1) % n
}

View file

@ -0,0 +1,19 @@
func fermat_number(n) {
2**(2**n) + 1
}
func fermat_one_factor(n) {
fermat_number(n).ecm_factor
}
for n in (0..9) {
say "F_#{n} = #{fermat_number(n)}"
}
say ''
for n in (0..13) {
var f = fermat_one_factor(n)
say ("F_#{n} = ", join(' * ', f.shift,
f.map { <C P>[.is_prime] + .len }...))
}

View file

@ -0,0 +1,23 @@
namespace import ::tcl::mathop::*
package require math::numtheory 1.1.1; # Buggy before tcllib-1.20
proc fermat n {
+ [** 2 [** 2 $n]] 1
}
for {set i 0} {$i < 10} {incr i} {
puts "F$i = [fermat $i]"
}
for {set i 1} {1} {incr i} {
puts -nonewline "F$i... "
flush stdout
set F [fermat $i]
set factors [math::numtheory::primeFactors $F]
if {[llength $factors] == 1} {
puts "is prime"
} else {
puts "factors: $factors"
}
}

View file

@ -0,0 +1,24 @@
import "/big" for BigInt
var fermat = Fn.new { |n| BigInt.two.pow(2.pow(n)) + 1 }
var fns = List.filled(10, null)
System.print("The first 10 Fermat numbers are:")
for (i in 0..9) {
fns[i] = fermat.call(i)
System.print("F%(String.fromCodePoint(0x2080+i)) = %(fns[i])")
}
System.print("\nFactors of the first 7 Fermat numbers:")
for (i in 0..6) {
System.write("F%(String.fromCodePoint(0x2080+i)) = ")
var factors = BigInt.primeFactors(fns[i])
System.write("%(factors)")
if (factors.count == 1) {
System.print(" (prime)")
} else if (!factors[1].isProbablePrime(5)) {
System.print(" (second factor is composite)")
} else {
System.print()
}
}

View file

@ -0,0 +1,30 @@
/* fermat_numbers_gmp.wren */
import "./gmp" for Mpz
import "./ecm" for Ecm
import "random" for Random
var fermat = Fn.new { |n| Mpz.two.pow(2.pow(n)) + 1 }
var fns = List.filled(10, null)
System.print("The first 10 Fermat numbers are:")
for (i in 0..9) {
fns[i] = fermat.call(i)
System.print("F%(String.fromCodePoint(0x2080+i)) = %(fns[i])")
}
System.print("\nFactors of the first 8 Fermat numbers:")
for (i in 0..8) {
System.write("F%(String.fromCodePoint(0x2080+i)) = ")
var factors = (i != 7) ? Mpz.primeFactors(fns[i]) : Ecm.primeFactors(fns[i])
System.write("%(factors)")
if (factors.count == 1) {
System.print(" (prime)")
} else if (!factors[1].probPrime(15)) {
System.print(" (second factor is composite)")
} else {
System.print()
}
}
System.print("\nThe first factor of F₉ is %(Mpz.pollardRho(fns[9])).")

View file

@ -0,0 +1,3 @@
fermatsW:=[0..].tweak(fcn(n){ BI(2).pow(BI(2).pow(n)) + 1 });
println("First 10 Fermat numbers:");
foreach n in (10){ println("F",n,": ",fermatsW.next()) }

View file

@ -0,0 +1,13 @@
fcn primeFactorsBI(n){ // Return a list of the prime factors of n
acc:=fcn(n,k,acc,maxD){ // k is primes
if(n==1 or k>maxD) acc.close();
else{
q,r:=n.div2(k); // divr-->(quotient,remainder)
if(r==0) return(self.fcn(q,k,acc.write(k.copy()),q.root(2)));
return(self.fcn(n, k.nextPrime(), acc,maxD)) # both are tail recursion
}
}(n,BI(2),Sink(List),n.root(2));
m:=acc.reduce('*,BI(1)); // mulitply factors
if(n!=m) acc.append(n/m); // opps, missed last factor
else acc;
}

View file

@ -0,0 +1,5 @@
fermatsW:=[0..].tweak(fcn(n){ BI(2).pow(BI(2).pow(n)) + 1 });
println("Factors of first few Fermat numbers:");
foreach n in (7){
println("Factors of F",n,": ",factorsBI(fermatsW.next()).concat(" "));
}