75 lines
1.6 KiB
Python
75 lines
1.6 KiB
Python
|
|
'''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()
|