How to resolve the algorithm Amicable pairs step by step in the Python programming language
How to resolve the algorithm Amicable pairs step by step in the Python programming language
Table of Contents
Problem Statement
Two integers
N
{\displaystyle N}
and
M
{\displaystyle M}
are said to be amicable pairs if
N ≠ M
{\displaystyle N\neq M}
and the sum of the proper divisors of
N
{\displaystyle N}
(
s u m
(
p r o p D i v s
( N ) )
{\displaystyle \mathrm {sum} (\mathrm {propDivs} (N))}
)
= M
{\displaystyle =M}
as well as
s u m
(
p r o p D i v s
( M ) )
N
{\displaystyle \mathrm {sum} (\mathrm {propDivs} (M))=N}
.
1184 and 1210 are an amicable pair, with proper divisors:
Calculate and show here the Amicable pairs below 20,000; (there are eight).
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Amicable pairs step by step in the Python programming language
The first code snippet uses a dictionary to store the sum of the proper divisors of numbers up to a certain limit. The dictionary is then used to find amicable pairs, which are pairs of numbers where each number is the sum of the proper divisors of the other number.
The second code snippet uses a more functional approach to find amicable pairs. It defines a function properDivisors
that returns the proper divisors of a number, and a function sigma
that returns the sum of the proper divisors of a number. The function amicable
then returns a list of amicable pairs. The main function calls amicablePairsUpTo
with a limit of 20000 and prints the results.
Here is a more detailed explanation of the first code snippet:
from proper_divisors import proper_divs
def amicable(rangemax=20000):
n2divsum = {n: sum(proper_divs(n)) for n in range(1, rangemax + 1)}
for num, divsum in n2divsum.items():
if num < divsum and divsum <= rangemax and n2divsum[divsum] == num:
yield num, divsum
The amicable
function takes an optional argument rangemax
and returns a generator of amicable pairs. The function first creates a dictionary n2divsum
that stores the sum of the proper divisors of numbers up to rangemax
. The proper_divs
function is defined in a separate module and returns the proper divisors of a number.
The function then iterates over the items in the n2divsum
dictionary. For each item, the function checks if the number is less than the sum of its proper divisors, if the sum of its proper divisors is less than or equal to rangemax
, and if the sum of the proper divisors of the sum of its proper divisors is equal to the number. If all of these conditions are met, the function yields the number and the sum of its proper divisors.
The following code snippet prints the amicable pairs generated by the amicable
function:
if __name__ == '__main__':
for num, divsum in amicable():
print('Amicable pair: %i and %i With proper divisors:\n %r\n %r'
% (num, divsum, sorted(proper_divs(num)), sorted(proper_divs(divsum))))
The if __name__ == '__main__'
block ensures that the code is only executed when the script is run as the main program and not imported as a module. The for
loop iterates over the amicable pairs generated by the amicable
function and prints each pair along with the proper divisors of each number.
Source code in the python programming language
from proper_divisors import proper_divs
def amicable(rangemax=20000):
n2divsum = {n: sum(proper_divs(n)) for n in range(1, rangemax + 1)}
for num, divsum in n2divsum.items():
if num < divsum and divsum <= rangemax and n2divsum[divsum] == num:
yield num, divsum
if __name__ == '__main__':
for num, divsum in amicable():
print('Amicable pair: %i and %i With proper divisors:\n %r\n %r'
% (num, divsum, sorted(proper_divs(num)), sorted(proper_divs(divsum))))
'''Amicable pairs'''
from itertools import chain
from math import sqrt
# amicablePairsUpTo :: Int -> [(Int, Int)]
def amicablePairsUpTo(n):
'''List of all amicable pairs
of integers below n.
'''
sigma = compose(sum)(properDivisors)
def amicable(x):
y = sigma(x)
return [(x, y)] if (x < y and x == sigma(y)) else []
return concatMap(amicable)(
enumFromTo(1)(n)
)
# TEST ----------------------------------------------------
# main :: IO ()
def main():
'''Amicable pairs of integers up to 20000'''
for x in amicablePairsUpTo(20000):
print(x)
# GENERIC -------------------------------------------------
# compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
def compose(g):
'''Right to left function composition.'''
return lambda f: lambda x: g(f(x))
# concatMap :: (a -> [b]) -> [a] -> [b]
def concatMap(f):
'''A concatenated list or string over which a function f
has been mapped.
The list monad can be derived by using an (a -> [b])
function which wraps its output in a list (using an
empty list to represent computational failure).
'''
return lambda xs: (''.join if isinstance(xs, str) else list)(
chain.from_iterable(map(f, xs))
)
# 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)
# properDivisors :: Int -> [Int]
def properDivisors(n):
'''Positive divisors of n, excluding n itself'''
root_ = sqrt(n)
intRoot = int(root_)
blnSqr = root_ == intRoot
lows = [x for x in range(1, 1 + intRoot) if 0 == n % x]
return lows + [
n // x for x in reversed(
lows[1:-1] if blnSqr else lows[1:]
)
]
# MAIN ---
if __name__ == '__main__':
main()
You may also check:How to resolve the algorithm Loops/For step by step in the LC3 Assembly programming language
You may also check:How to resolve the algorithm Empty string step by step in the UNIX Shell programming language
You may also check:How to resolve the algorithm Split a character string based on change of character step by step in the FutureBasic programming language
You may also check:How to resolve the algorithm 99 bottles of beer step by step in the ProDOS programming language
You may also check:How to resolve the algorithm Kosaraju step by step in the zkl programming language