Largest proper divisor of n: Difference between revisions
Content added Content deleted
(→{{header|Python}}: Added a functional variant which reduces the search space and formats more flexibly.) |
|||
Line 518: | Line 518: | ||
print("{:3}".format(lpd(i)), end=i%10==0 and '\n' or '')</lang> |
print("{:3}".format(lpd(i)), end=i%10==0 and '\n' or '')</lang> |
||
{{out}} |
{{out}} |
||
<pre> 1 1 1 2 1 3 1 4 3 5 |
|||
1 6 1 7 5 8 1 9 1 10 |
|||
7 11 1 12 5 13 9 14 1 15 |
|||
1 16 11 17 7 18 1 19 13 20 |
|||
1 21 1 22 15 23 1 24 7 25 |
|||
17 26 1 27 11 28 19 29 1 30 |
|||
1 31 21 32 13 33 1 34 23 35 |
|||
1 36 1 37 25 38 11 39 1 40 |
|||
27 41 1 42 17 43 29 44 1 45 |
|||
13 46 31 47 19 48 1 49 33 50</pre> |
|||
Or, reducing the search space, formatting more flexibly (to allow for experiments with larger ranges) and composing functionally: |
|||
<lang python>'''Largest proper divisor of''' |
|||
from math import isqrt |
|||
# maxProperDivisors :: Int -> Int |
|||
def maxProperDivisors(n): |
|||
'''The largest proper divisor of n. |
|||
''' |
|||
secondDivisor = find( |
|||
lambda x: 0 == (n % x) |
|||
)( |
|||
range(2, 1 + isqrt(n)) |
|||
) |
|||
return 1 if None is secondDivisor else ( |
|||
n // secondDivisor |
|||
) |
|||
# ------------------------- TEST ------------------------- |
|||
# main :: IO () |
|||
def main(): |
|||
'''Test for values of n in [1..100]''' |
|||
xs = [ |
|||
maxProperDivisors(n) for n |
|||
in range(1, 1 + 100) |
|||
] |
|||
colWidth = 1 + len(str(max(xs))) |
|||
print( |
|||
'\n'.join([ |
|||
''.join(row) for row in |
|||
chunksOf(10)([ |
|||
str(x).rjust(colWidth, " ") for x in xs |
|||
]) |
|||
]) |
|||
) |
|||
# ----------------------- GENERIC ------------------------ |
|||
# chunksOf :: Int -> [a] -> [[a]] |
|||
def chunksOf(n): |
|||
'''A series of lists of length n, subdividing the |
|||
contents of xs. Where the length of xs is not evenly |
|||
divisible, the final list will be shorter than n. |
|||
''' |
|||
def go(xs): |
|||
return ( |
|||
xs[i:n + i] for i in range(0, len(xs), n) |
|||
) if 0 < n else None |
|||
return go |
|||
# find :: (a -> Bool) -> [a] -> (a | None) |
|||
def find(p): |
|||
'''Just the first element in the list that matches p, |
|||
or None if no elements match. |
|||
''' |
|||
def go(xs): |
|||
try: |
|||
return next(x for x in xs if p(x)) |
|||
except StopIteration: |
|||
return None |
|||
return go |
|||
# MAIN --- |
|||
if __name__ == '__main__': |
|||
main()</lang> |
|||
{{Out}} |
|||
<pre> 1 1 1 2 1 3 1 4 3 5 |
<pre> 1 1 1 2 1 3 1 4 3 5 |
||
1 6 1 7 5 8 1 9 1 10 |
1 6 1 7 5 8 1 9 1 10 |