Pascal's triangle: Difference between revisions
Content added Content deleted
m (Updated description and link for Fōrmulæ solution) |
m (→Functional Python: Tidied) |
||
Line 4,774: | Line 4,774: | ||
===Functional=== |
===Functional=== |
||
⚫ | |||
The itertools module yields a simple functional definition of '''scanl''' in terms of '''accumulate''', and '''zipWith''' can be defined in terms either of '''itertools.starmap''', or the base '''map'''. |
|||
⚫ | |||
{{Works with|Python|3.7}} |
{{Works with|Python|3.7}} |
||
Line 4,789: | Line 4,787: | ||
'''A row of Pascal's triangle |
'''A row of Pascal's triangle |
||
derived from a preceding row.''' |
derived from a preceding row.''' |
||
return |
return list( |
||
⚫ | |||
⚫ | |||
Line 4,804: | Line 4,804: | ||
def go(a, _): |
def go(a, _): |
||
return nextPascal(a) |
return nextPascal(a) |
||
return scanl(go)([1])( |
|||
return accumulate( |
|||
⚫ | |||
⚫ | |||
) |
) |
||
# |
# ------------------------ TESTS ------------------------- |
||
# main :: IO () |
# main :: IO () |
||
def main(): |
def main(): |
||
Line 4,815: | Line 4,817: | ||
- taking from a non-finite stream of rows, |
- taking from a non-finite stream of rows, |
||
- or constructing a finite list of rows.''' |
- or constructing a finite list of rows.''' |
||
print( |
print('\n'.join(map( |
||
showPascal, |
showPascal, |
||
[ |
[ |
||
islice( |
|||
pascalTriangle() |
pascalTriangle(), # Non finite, |
||
7 |
|||
), |
), |
||
finitePascalRows(7) # finite. |
finitePascalRows(7) # finite. |
||
Line 4,840: | Line 4,843: | ||
# |
# ----------------------- GENERIC ------------------------ |
||
# center :: Int -> Char -> String -> String |
# center :: Int -> Char -> String -> String |
||
Line 4,856: | Line 4,858: | ||
# iterate :: (a -> a) -> a -> Gen [a] |
# iterate :: (a -> a) -> a -> Gen [a] |
||
def iterate(f): |
def iterate(f): |
||
'''An infinite list of repeated |
'''An infinite list of repeated |
||
applications of f to x. |
|||
⚫ | |||
def go(x): |
def go(x): |
||
v = x |
v = x |
||
Line 4,862: | Line 4,866: | ||
yield v |
yield v |
||
v = f(v) |
v = f(v) |
||
return |
return go |
||
# scanl :: (b -> a -> b) -> b -> [a] -> [b] |
|||
def scanl(f): |
|||
'''scanl is like reduce, but returns a succession of |
|||
intermediate values, building from the left.''' |
|||
return lambda a: lambda xs: ( |
|||
⚫ | |||
⚫ | |||
# 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: ( |
|||
⚫ | |||
if isinstance(xs, list) |
|||
else list(islice(xs, n)) |
|||
⚫ | |||
# unlines :: [String] -> String |
|||
def unlines(xs): |
|||
'''A single string derived by the intercalation |
|||
of a list of strings with the newline character.''' |
|||
return '\n'.join(xs) |
|||
# zipWith :: (a -> b -> c) -> [a] -> [b] -> [c] |
|||
def zipWith(f): |
|||
'''A list constructed by zipping with a |
|||
custom function, rather than with the |
|||
default tuple constructor.''' |
|||
return lambda xs: lambda ys: ( |
|||
⚫ | |||
) |
|||