How to resolve the algorithm Farey sequence step by step in the Python programming language
How to resolve the algorithm Farey sequence step by step in the Python programming language
Table of Contents
Problem Statement
The Farey sequence Fn of order n is the sequence of completely reduced fractions between 0 and 1 which, when in lowest terms, have denominators less than or equal to n, arranged in order of increasing size. The Farey sequence is sometimes incorrectly called a Farey series.
Each Farey sequence:
The Farey sequences of orders 1 to 5 are:
The length (the number of fractions) of a Farey sequence asymptotically approaches:
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Farey sequence step by step in the Python programming language
Farey Sequence
The Farey sequence is a sequence of rational numbers between 0 and 1, where each number is unique and no two consecutive numbers have the same denominator.
Code Overview
1. Fraction Class:
- The
Fr
class extends theFraction
class from thefractions
module. - It overrides the
__repr__
method to provide a custom string representation of the fraction in the form'(numerator/denominator)'
.
2. farey
Function:
- The
farey
function generates the Farey sequence for a given ordern
. - For orders where
length
isFalse
, it returns a list ofFr
objects representing the sequence. - For orders where
length
isTrue
, it returns the number of terms in the sequence. - The sequence is calculated by recursively finding the Farey sequence for smaller orders and combining the results.
3. fareyLength
Function (Optional):
- The
fareyLength
function computes the number of terms in the Farey sequence of a given ordern
using a recursive formula.
4. Example Usage:
- The
main
function demonstrates the usage of thefarey
function by printing the Farey sequences for orders 1 to 11 and the number of fractions in sequences for orders 100 to 1,000.
5. Helper Functions (Optional):
enumFromTo
: Generates a list of integers fromm
ton
.enumFromThenTo
: Generates a list of integers fromm
ton
with a step defined bynxt-m
.bind
: Sequentially composes two computations, passing the output of the first as an argument to the second.fromRatio
: Converts aRatio
object to a floating-point number.nubBy
: Removes duplicate elements from a list based on a given equality predicate.on
: Creates a function that applies a binary function to the result of applying two other functions to its arguments.ratio
: Constructs aRatio
object from numerator and denominator.showRatio
: Converts aRatio
object to a string.signum
: Returns the sign of a number.fTable
: Generates a tabular string with two columns, where the left column shows values from a list and the right column shows transformed values.unlines
: Concatenates a list of strings into a single string with newlines.
Source code in the python programming language
from fractions import Fraction
class Fr(Fraction):
def __repr__(self):
return '(%s/%s)' % (self.numerator, self.denominator)
def farey(n, length=False):
if not length:
return [Fr(0, 1)] + sorted({Fr(m, k) for k in range(1, n+1) for m in range(1, k+1)})
else:
#return 1 + len({Fr(m, k) for k in range(1, n+1) for m in range(1, k+1)})
return (n*(n+3))//2 - sum(farey(n//k, True) for k in range(2, n+1))
if __name__ == '__main__':
print('Farey sequence for order 1 through 11 (inclusive):')
for n in range(1, 12):
print(farey(n))
print('Number of fractions in the Farey sequence for order 100 through 1,000 (inclusive) by hundreds:')
print([farey(i, length=True) for i in range(100, 1001, 100)])
'''Farey sequence'''
from itertools import (chain, count, islice)
from math import gcd
# farey :: Int -> [Ratio Int]
def farey(n):
'''Farey sequence of order n.'''
return sorted(
nubBy(on(eq)(fromRatio))(
bind(enumFromTo(1)(n))(
lambda k: bind(enumFromTo(0)(k))(
lambda m: [ratio(m)(k)]
)
)
),
key=fromRatio
) + [ratio(1)(1)]
# fareyLength :: Int -> Int
def fareyLength(n):
'''Number of terms in a Farey sequence
of order n.'''
def go(x):
return (x * (x + 3)) // 2 - sum(
go(x // k) for k in enumFromTo(2)(x)
)
return go(n)
# showFarey :: [Ratio Int] -> String
def showFarey(xs):
'''Stringification of a Farey sequence.'''
return '(' + ', '.join(map(showRatio, xs)) + ')'
# TEST ----------------------------------------------------
# main :: IO ()
def main():
'''Tests'''
print(
fTable(
'Farey sequence for orders 1-11 (inclusive):\n'
)(str)(showFarey)(
farey
)(enumFromTo(1)(11))
)
print(
fTable(
'\n\nNumber of fractions in the Farey sequence ' +
'for order 100 through 1,000 (inclusive) by hundreds:\n'
)(str)(str)(
fareyLength
)(enumFromThenTo(100)(200)(1000))
)
# GENERIC -------------------------------------------------
# bind(>>=) :: [a] -> (a -> [b]) -> [b]
def bind(xs):
'''List monad injection operator.
Two computations sequentially composed,
with any value produced by the first
passed as an argument to the second.'''
return lambda f: list(
chain.from_iterable(
map(f, xs)
)
)
# compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
def compose(g):
'''Right to left function composition.'''
return lambda f: lambda x: g(f(x))
# enumFromThenTo :: Int -> Int -> Int -> [Int]
def enumFromThenTo(m):
'''Integer values enumerated from m to n
with a step defined by nxt-m.
'''
def go(nxt, n):
d = nxt - m
return islice(count(0), m, d + n, d)
return lambda nxt: lambda n: (
list(go(nxt, n))
)
# enumFromTo :: (Int, Int) -> [Int]
def enumFromTo(m):
'''Integer enumeration from m to n.'''
return lambda n: list(range(m, 1 + n))
# eq (==) :: Eq a => a -> a -> Bool
def eq(a):
'''Simple equality of a and b.'''
return lambda b: a == b
# fromRatio :: Ratio Int -> Float
def fromRatio(r):
'''A floating point value derived from a
a rational value.
'''
return r.get('numerator') / r.get('denominator')
# nubBy :: (a -> a -> Bool) -> [a] -> [a]
def nubBy(p):
'''A sublist of xs from which all duplicates,
(as defined by the equality predicate p)
are excluded.
'''
def go(xs):
if not xs:
return []
x = xs[0]
return [x] + go(
list(filter(
lambda y: not p(x)(y),
xs[1:]
))
)
return lambda xs: go(xs)
# on :: (b -> b -> c) -> (a -> b) -> a -> a -> c
def on(f):
'''A function returning the value of applying
the binary f to g(a) g(b)
'''
return lambda g: lambda a: lambda b: f(g(a))(g(b))
# ratio :: Int -> Int -> Ratio Int
def ratio(n):
'''Rational value constructed
from a numerator and a denominator.
'''
def go(n, d):
g = gcd(n, d)
return {
'type': 'Ratio',
'numerator': n // g, 'denominator': d // g
}
return lambda d: go(n * signum(d), abs(d))
# showRatio :: Ratio -> String
def showRatio(r):
'''String representation of the ratio r.'''
d = r.get('denominator')
return str(r.get('numerator')) + (
'/' + str(d) if 1 != d else ''
)
# signum :: Num -> Num
def signum(n):
'''The sign of n.'''
return -1 if 0 > n else (1 if 0 < n else 0)
# 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
)
# unlines :: [String] -> String
def unlines(xs):
'''A single string derived by the intercalation
of a list of strings with the newline character.
'''
return '\n'.join(xs)
if __name__ == '__main__':
main()
You may also check:How to resolve the algorithm Hello world/Standard error step by step in the Oberon-2 programming language
You may also check:How to resolve the algorithm String matching step by step in the Kotlin programming language
You may also check:How to resolve the algorithm Hamming numbers step by step in the Rust programming language
You may also check:How to resolve the algorithm Logistic curve fitting in epidemiology step by step in the Kotlin programming language
You may also check:How to resolve the algorithm Symmetric difference step by step in the Racket programming language