Harshad or Niven series: Difference between revisions

→‎Python: Functional: Added a functionally composed alternative to string coercion
(→‎Python: Functional: Added a functionally composed alternative to string coercion)
Line 2,466:
1002
>>> </lang>
 
And we can sum digits more directly (without string coercion) while still preserving functional composition:
 
{{Works with|Python|3.7}}
<lang python>'''Harshad or Niven series'''
 
from itertools import dropwhile, islice
 
 
# harshads :: () -> Gen [Int]
def harshads():
'''Harshad series.'''
x = 1
while True:
if 0 == (x % digitSum(x)):
yield x
x = 1 + x
 
 
# digitSum :: Int -> Int
def digitSum(n):
'''The sum of the decimal digits of n.'''
a = 0
r = n
while r:
a += (r % 10)
r //= 10
return a
 
 
# TEST ----------------------------------------------------
# main :: IO ()
def main():
'''First 20, and first above 1000.'''
 
def firstTwenty(xs):
return take(20)(xs)
 
def firstAbove1000(xs):
return take(1)(
dropwhile(lambda x: 1000 >= x, xs)
)
 
print(
fTable(__doc__ + ':\n')(
lambda x: x.__name__
)(str)(lambda f: f(harshads()))([
firstTwenty,
firstAbove1000
])
)
 
 
# GENERIC -------------------------------------------------
 
# 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))
)
 
 
# 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
)
 
 
# MAIN ---
if __name__ == '__main__':
main()</lang>
{{Out}}
<pre>Harshad or Niven series:
 
firstTwenty -> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 18, 20, 21, 24, 27, 30, 36, 40, 42]
firstAbove1000 -> [1002]</pre>
 
=={{header|Racket}}==
9,659

edits