Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
3
Task/Fermat-numbers/00-META.yaml
Normal file
3
Task/Fermat-numbers/00-META.yaml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
from: http://rosettacode.org/wiki/Fermat_numbers
|
||||
note: Prime Numbers
|
||||
24
Task/Fermat-numbers/00-TASK.txt
Normal file
24
Task/Fermat-numbers/00-TASK.txt
Normal 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>
|
||||
|
||||
10
Task/Fermat-numbers/Arturo/fermat-numbers.arturo
Normal file
10
Task/Fermat-numbers/Arturo/fermat-numbers.arturo
Normal 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]]
|
||||
83
Task/Fermat-numbers/C++/fermat-numbers.cpp
Normal file
83
Task/Fermat-numbers/C++/fermat-numbers.cpp
Normal 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;
|
||||
}
|
||||
41
Task/Fermat-numbers/C/fermat-numbers.c
Normal file
41
Task/Fermat-numbers/C/fermat-numbers.c
Normal 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;
|
||||
}
|
||||
16
Task/Fermat-numbers/Common-Lisp/fermat-numbers.lisp
Normal file
16
Task/Fermat-numbers/Common-Lisp/fermat-numbers.lisp
Normal 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)))))))))
|
||||
14
Task/Fermat-numbers/Crystal/fermat-numbers.crystal
Normal file
14
Task/Fermat-numbers/Crystal/fermat-numbers.crystal
Normal 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)}" }
|
||||
15
Task/Fermat-numbers/Factor/fermat-numbers.factor
Normal file
15
Task/Fermat-numbers/Factor/fermat-numbers.factor
Normal 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
|
||||
361
Task/Fermat-numbers/Go/fermat-numbers.go
Normal file
361
Task/Fermat-numbers/Go/fermat-numbers.go
Normal 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))
|
||||
}
|
||||
36
Task/Fermat-numbers/Haskell/fermat-numbers.hs
Normal file
36
Task/Fermat-numbers/Haskell/fermat-numbers.hs
Normal 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)"
|
||||
129
Task/Fermat-numbers/Java/fermat-numbers.java
Normal file
129
Task/Fermat-numbers/Java/fermat-numbers.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
32
Task/Fermat-numbers/Jq/fermat-numbers-1.jq
Normal file
32
Task/Fermat-numbers/Jq/fermat-numbers-1.jq
Normal 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;
|
||||
37
Task/Fermat-numbers/Jq/fermat-numbers-2.jq
Normal file
37
Task/Fermat-numbers/Jq/fermat-numbers-2.jq
Normal 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 )
|
||||
20
Task/Fermat-numbers/Julia/fermat-numbers.julia
Normal file
20
Task/Fermat-numbers/Julia/fermat-numbers.julia
Normal 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)
|
||||
122
Task/Fermat-numbers/Kotlin/fermat-numbers.kotlin
Normal file
122
Task/Fermat-numbers/Kotlin/fermat-numbers.kotlin
Normal 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)
|
||||
}
|
||||
28
Task/Fermat-numbers/Langur/fermat-numbers.langur
Normal file
28
Task/Fermat-numbers/Langur/fermat-numbers.langur
Normal 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
|
||||
}
|
||||
}
|
||||
4
Task/Fermat-numbers/Mathematica/fermat-numbers.math
Normal file
4
Task/Fermat-numbers/Mathematica/fermat-numbers.math
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
ClearAll[Fermat]
|
||||
Fermat[n_] := 2^(2^n) + 1
|
||||
Fermat /@ Range[0, 9]
|
||||
Scan[FactorInteger /* Print, %]
|
||||
112
Task/Fermat-numbers/Nim/fermat-numbers.nim
Normal file
112
Task/Fermat-numbers/Nim/fermat-numbers.nim
Normal 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))}"
|
||||
17
Task/Fermat-numbers/Perl/fermat-numbers.pl
Normal file
17
Task/Fermat-numbers/Perl/fermat-numbers.pl
Normal 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
|
||||
}
|
||||
51
Task/Fermat-numbers/Phix/fermat-numbers.phix
Normal file
51
Task/Fermat-numbers/Phix/fermat-numbers.phix
Normal 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>
|
||||
<!--
|
||||
100
Task/Fermat-numbers/PicoLisp/fermat-numbers.l
Normal file
100
Task/Fermat-numbers/PicoLisp/fermat-numbers.l
Normal 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)) ) ) )
|
||||
26
Task/Fermat-numbers/Python/fermat-numbers-1.py
Normal file
26
Task/Fermat-numbers/Python/fermat-numbers-1.py
Normal 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))
|
||||
137
Task/Fermat-numbers/Python/fermat-numbers-2.py
Normal file
137
Task/Fermat-numbers/Python/fermat-numbers-2.py
Normal 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()
|
||||
33
Task/Fermat-numbers/REXX/fermat-numbers-1.rexx
Normal file
33
Task/Fermat-numbers/REXX/fermat-numbers-1.rexx
Normal 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(?)
|
||||
36
Task/Fermat-numbers/REXX/fermat-numbers-2.rexx
Normal file
36
Task/Fermat-numbers/REXX/fermat-numbers-2.rexx
Normal 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.*/
|
||||
13
Task/Fermat-numbers/Raku/fermat-numbers.raku
Normal file
13
Task/Fermat-numbers/Raku/fermat-numbers.raku
Normal 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' !! ''
|
||||
}
|
||||
21
Task/Fermat-numbers/Ring/fermat-numbers.ring
Normal file
21
Task/Fermat-numbers/Ring/fermat-numbers.ring
Normal 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
|
||||
13
Task/Fermat-numbers/Ruby/fermat-numbers.rb
Normal file
13
Task/Fermat-numbers/Ruby/fermat-numbers.rb
Normal 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)}" }
|
||||
57
Task/Fermat-numbers/Rust/fermat-numbers-1.rust
Normal file
57
Task/Fermat-numbers/Rust/fermat-numbers-1.rust
Normal 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);
|
||||
}
|
||||
}
|
||||
78
Task/Fermat-numbers/Rust/fermat-numbers-2.rust
Normal file
78
Task/Fermat-numbers/Rust/fermat-numbers-2.rust
Normal 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!();
|
||||
}
|
||||
}
|
||||
106
Task/Fermat-numbers/Scala/fermat-numbers.scala
Normal file
106
Task/Fermat-numbers/Scala/fermat-numbers.scala
Normal 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
|
||||
}
|
||||
19
Task/Fermat-numbers/Sidef/fermat-numbers.sidef
Normal file
19
Task/Fermat-numbers/Sidef/fermat-numbers.sidef
Normal 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 }...))
|
||||
}
|
||||
23
Task/Fermat-numbers/Tcl/fermat-numbers.tcl
Normal file
23
Task/Fermat-numbers/Tcl/fermat-numbers.tcl
Normal 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"
|
||||
}
|
||||
}
|
||||
24
Task/Fermat-numbers/Wren/fermat-numbers-1.wren
Normal file
24
Task/Fermat-numbers/Wren/fermat-numbers-1.wren
Normal 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()
|
||||
}
|
||||
}
|
||||
30
Task/Fermat-numbers/Wren/fermat-numbers-2.wren
Normal file
30
Task/Fermat-numbers/Wren/fermat-numbers-2.wren
Normal 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])).")
|
||||
3
Task/Fermat-numbers/Zkl/fermat-numbers-1.zkl
Normal file
3
Task/Fermat-numbers/Zkl/fermat-numbers-1.zkl
Normal 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()) }
|
||||
13
Task/Fermat-numbers/Zkl/fermat-numbers-2.zkl
Normal file
13
Task/Fermat-numbers/Zkl/fermat-numbers-2.zkl
Normal 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;
|
||||
}
|
||||
5
Task/Fermat-numbers/Zkl/fermat-numbers-3.zkl
Normal file
5
Task/Fermat-numbers/Zkl/fermat-numbers-3.zkl
Normal 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(" "));
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue