RosettaCodeData/Task/Cantor-set/Python/cantor-set-3.py

72 lines
1.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'''Cantor set strings as both model and display.'''
from itertools import (chain, islice)
# cantorLines :: Int -> String
def cantorLines(n):
'''N levels of cantor segmentation,
obtained and displayed in the
form of lines of block characters.
'''
return '\n'.join(
[''.join(x) for x in islice(
iterate(cantor)(
[3 ** (n - 1) * '']
), n
)]
)
# cantor :: [String] -> [String]
def cantor(xs):
'''A cantor line derived from its predecessor.'''
def go(s):
m = len(s) // 3
blocks = s[0:m]
return [
blocks, m * ' ', blocks
] if '' == s[0] else [s]
return concatMap(go)(xs)
# MAIN ----------------------------------------------------
# main :: IO ()
def main():
'''Testing cantor line generation to level 5'''
print(
cantorLines(5)
)
# GENERIC -------------------------------------------------
# concatMap :: (a -> [b]) -> [a] -> [b]
def concatMap(f):
'''A concatenated list over which a function has been mapped.
The list monad can be derived by using a function f which
wraps its output in a list,
(using an empty list to represent computational failure).'''
return lambda xs: list(
chain.from_iterable(map(f, xs))
)
# iterate :: (a -> a) -> a -> Gen [a]
def iterate(f):
'''An infinite list of repeated
applications of f to x.
'''
def go(x):
v = x
while True:
yield v
v = f(v)
return lambda x: go(x)
# MAIN ---
if __name__ == '__main__':
main()