Faulhaber's triangle: Difference between revisions
Content added Content deleted
(→{{header|Python}}: pylinted for Python 3, updated output) |
|||
Line 1,945: | Line 1,945: | ||
=={{header|Python}}== |
=={{header|Python}}== |
||
{{trans|Haskell}} |
{{trans|Haskell}} |
||
{{Works with|Python|3.7}} |
|||
<lang python>from itertools import (accumulate, count, islice, starmap) |
|||
<lang python>'''Faulhaber's triangle''' |
|||
from itertools import (accumulate, count, islice, starmap) |
|||
from fractions import (Fraction) |
from fractions import (Fraction) |
||
# faulhaber :: Integer -> Integer -> Integer |
|||
def faulhaber(p, n): |
|||
"""Sum of the p-th powers of the first n positive integers""" |
|||
return sum( |
|||
list(starmap( |
|||
lambda x, y: y * (n ** x), |
|||
zip(count(1), faulhaberTriangle(p)[-1]) |
|||
)) |
|||
) |
|||
# faulhaberTriangle :: Int -> [[Fraction]] |
# faulhaberTriangle :: Int -> [[Fraction]] |
||
def faulhaberTriangle(m): |
def faulhaberTriangle(m): |
||
'''List of rows of Faulhaber fractions.''' |
|||
def go(rs, n): |
def go(rs, n): |
||
xs = list(starmap( |
xs = list(starmap( |
||
Line 1,967: | Line 1,960: | ||
zip(islice(count(2), m), rs) |
zip(islice(count(2), m), rs) |
||
)) |
)) |
||
return [1 - sum(xs)] + xs |
return [Fraction(1 - sum(xs), 1)] + xs |
||
return list(accumulate( |
return list(accumulate( |
||
[[]] + list(islice(count(0), 1 + m)), |
[[]] + list(islice(count(0), 1 + m)), |
||
go |
go |
||
))[1:] |
))[1:] |
||
# faulhaberSum :: Integer -> Integer -> Integer |
|||
def faulhaberSum(p, n): |
|||
'''Sum of the p-th powers of the first n |
|||
positive integers. |
|||
''' |
|||
return sum( |
|||
list(starmap( |
|||
lambda x, y: y * (n ** x), |
|||
zip(count(1), faulhaberTriangle(p)[-1]) |
|||
)) |
|||
) |
|||
# TEST ---------------------------------------------------- |
# TEST ---------------------------------------------------- |
||
def main(): |
|||
'''Tests''' |
|||
fs = ( |
|||
fmap(fmap(showRatio(4)(2)))( |
|||
lambda ln: list(map( |
|||
faulhaberTriangle(9) |
|||
lambda r: str(r.numerator).rjust(2, ' ') + ( |
|||
) |
|||
'/' + str(r.denominator).ljust(5, ' ') if ( |
|||
) |
|||
r.denominator > 1 |
|||
print( |
|||
) else ' ' |
|||
) |
fTable(__doc__ + ':\n')(str)(str)( |
||
lambda x: ''.join(fs[x]) |
|||
) |
)(range(0, len(fs))) |
||
) |
|||
print('') |
|||
) |
|||
print( |
|||
faulhaberSum(17, 1000) |
|||
) |
|||
for row in faulhabers: |
|||
# DISPLAY ------------------------------------------------- |
|||
print (''.join(row)) |
|||
print ('') |
|||
# fTable :: String -> (a -> String) -> |
|||
print ( |
|||
# (b -> String) -> (a -> b) -> [a] -> String |
|||
faulhaber(17, 1000) |
|||
def fTable(s): |
|||
)</lang> |
|||
'''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 ------------------------------------------------- |
|||
# showRatio :: Int -> Ratio -> String |
|||
def showRatio(m): |
|||
'''Aligned string representation |
|||
of the ratio r. |
|||
''' |
|||
def go(n, r): |
|||
d = r.denominator |
|||
return str(r.numerator).rjust(m, ' ') + ( |
|||
('/' + str(d).ljust(n, ' ')) if 1 != d else ( |
|||
' ' * (1 + n) |
|||
) |
|||
) |
|||
return lambda n: lambda r: go(n, r) |
|||
# fmap :: (a -> b) -> [a] -> [b] |
|||
def fmap(f): |
|||
'''fmap over a list. |
|||
f lifted to a function over a list. |
|||
''' |
|||
return lambda xs: list(map(f, xs)) |
|||
if __name__ == '__main__': |
|||
main()</lang> |
|||
{{Out}} |
{{Out}} |
||
<pre> |
<pre>Faulhaber's triangle: |
||
1/2 1/2 |
|||
0 -> 1 |
|||
1 -> 1/2 1/2 |
|||
- |
2 -> 1/6 1/2 1/3 |
||
3 -> 0 1/4 1/2 1/4 |
|||
4 -> -1/30 0 1/3 1/2 1/5 |
|||
5 -> 0 -1/12 0 5/12 1/2 1/6 |
|||
- |
6 -> 1/42 0 -1/6 0 1/2 1/2 1/7 |
||
7 -> 0 1/12 0 -7/24 0 7/12 1/2 1/8 |
|||
8 -> -1/30 0 2/9 0 -7/15 0 2/3 1/2 1/9 |
|||
9 -> 0 -3/20 0 1/2 0 -7/10 0 3/4 1/2 1/10 |
|||
56056972216555580111030077961944183400198333273050000</pre> |
56056972216555580111030077961944183400198333273050000</pre> |