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

75 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 separating model from display'''
from functools import (reduce)
import itertools
# cantor :: [(Bool, Int)] -> [(Bool, Int)]
def cantor(xs):
'''A Cantor segmentation step.'''
def go(tpl):
(bln, n) = tpl
m = n // 3
return [
(True, m), (False, m), (True, m)
] if bln and (1 < n) else [tpl]
return concatMap(go)(xs)
# cantorLines :: Int -> String
def cantorLines(n):
'''A text block display of n
Cantor-segmented lines.
'''
m = n - 1
repeat = itertools.repeat
return '\n'.join(
[showCantor(x) for x in (
reduce(
lambda a, f: a + [f(a[-1])],
repeat(cantor, m),
[[(True, 3 ** m)]]
)
)]
)
# showCantor :: [(Bool, Int)] -> String
def showCantor(xs):
'''A text block display of a list of
Cantor line segments.
'''
return ''.join(
concatMap(lambda tpl: tpl[1] * ('' if tpl[0] else ' '))(
xs
)
)
# main :: IO ()
def main():
'''Testing to depth 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).'''
chain = itertools.chain
return lambda xs: list(
chain.from_iterable(map(f, xs))
)
# MAIN ---
if __name__ == '__main__':
main()