How to resolve the algorithm Fermat numbers step by step in the Python programming language
How to resolve the algorithm Fermat numbers step by step in the Python programming language
Table of Contents
Problem Statement
In mathematics, a Fermat number, named after Pierre de Fermat who first studied them, is a positive integer of the form Fn = 22n + 1 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 (F0 through F4). Only the first twelve Fermat numbers have been completely factored, though many have been partially factored.
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Fermat numbers step by step in the Python programming language
The next Python code first defines two helper functions:
factors
: It takes a number as input and returns a list of all its factors (i.e., the numbers that can divide it without leaving a remainder).fermats
: It's a generator that yields the Fermat numbers sequentially, starting fromF0 = 3
.
The main block of code does the following:
-
It prints the first 10 Fermat numbers using a loop.
-
For each of the first 10 Fermat numbers, it computes its factors using the
factors
function. If the list of factors contains only one element, then the Fermat number is prime; otherwise, it prints the list of factors.
The code then defines a few more functions that are used for generating and displaying the results:
-
fermat
: This function calculates the nth Fermat number, which is given by2^(2^n) + 1
. -
fTable
: This is a higher-order function that takes three other functions as arguments: two display functions (xShow
andfxShow
) and a functionf
that takes an input and returns an output.fTable
returns a new function that, when given a list of inputs, displays the inputs usingxShow
and the outputs usingfxShow
, with the output for each input aligned under the corresponding input. -
enumFrom
: This is a generator that yields a sequence of values starting from a given starting value. -
enumFromTo
: This is a specialized version ofenumFrom
that yields a sequence of integers in the range [m, n]. -
primeFactors
: This function takes a number as input and returns a list of its prime factors. -
take
: This function takes a numbern
and a list or stringxs
as inputs and returns the firstn
elements ofxs
. -
until
: This function takes a predicate functionp
and a functionf
as inputs and repeatedly appliesf
to an initial value untilp
holds true. It then returns the final value.
The main function calls main()
, which prints the first 10 Fermat numbers and the factors of the first 7 Fermat numbers.
Source code in the python programming language
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))
'''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()
You may also check:How to resolve the algorithm Loops/Continue step by step in the PARI/GP programming language
You may also check:How to resolve the algorithm Random numbers step by step in the J programming language
You may also check:How to resolve the algorithm Classes step by step in the Arturo programming language
You may also check:How to resolve the algorithm Jump anywhere step by step in the Ring programming language
You may also check:How to resolve the algorithm Bell numbers step by step in the Racket programming language