Pascal's triangle: Difference between revisions
→{{header|Python}}: Added a non-finite generator version
(→JS ES6: Updated primitives and approach (drawing n lines from a non-finite generator)) |
(→{{header|Python}}: Added a non-finite generator version) |
||
Line 4,008:
return n>=1</lang>
<lang
a = []
result = it
Line 4,026:
for row in pascal(4):
print(row)</lang>
or drawing n lines from a non-finite generator:
<lang python>from itertools import (islice)
# main :: IO ()
def main():
print (
showPascal(
take(7)(
pascal() # generator
)
)
)
# pascal :: Generator [[Int]]
def pascal():
return iterate(
lambda xs: zipWith(plus)([0] + xs)(xs + [0])
)([1])
# showPascal :: [[Int]] -> String
def showPascal(xs):
w = len(' '.join((map(str, xs[-1]))))
def align(ns):
return center(w)(
' '
)(' '.join(map(str, ns)))
return '\n'.join(map(align, xs))
# GENERIC -------------------------------------------------
# center :: Int -> Char -> String -> String
def center(n):
def go(c, s):
qr = divmod(n - len(s), 2)
q = qr[0]
return (q * c) + s + ((q + qr[1]) * c)
return lambda c: lambda s: go(c, s)
# iterate :: (a -> a) -> a -> Generator [a]
def iterate(f):
def go(x):
v = x
while True:
yield(v)
v = f(v)
return lambda x: go(x)
# plus :: Num -> Num -> Num
def plus(a):
return lambda b: a + b
# take :: Int -> [a] -> [a]
# take :: Int -> String -> String
def take(n):
return lambda xs: (
xs[0:n]
if isinstance(xs, list)
else list(islice(xs, n))
)
# zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
def zipWith(f):
return (
lambda xs: lambda ys:
[f(a)(b) for (a, b) in zip(xs, ys)]
)
main()</lang>
{{Out}}
<pre> 1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1</pre>
=={{header|q}}==
|