import { corner, heart, stack, turn_upside_down, beside, flip_vert, flip_horiz, show } from 'rune';

def square_of_four(tl, tr, bl, br):
    return lambda painter: stack(beside(tl(painter), tr(painter)),
                            beside(bl(painter), br(painter)))
def identity(x):
    return x
def right_split(painter, n):
    if n == 0:
        return painter
    else:
        smaller = right_split(painter, n - 1)
        return beside(painter, stack(smaller, smaller))
def up_split(painter, n):
    if n == 0:
        return painter
    else:
        smaller = up_split(painter, n - 1)
        return stack(beside(smaller, smaller), painter)
def corner_split(painter, n):
    if n == 0:
        return painter
    else:
        up = up_split(painter, n - 1)
        right = right_split(painter, n - 1)
        top_left = beside(up, up)
        bottom_right = stack(right, right)
        corner = corner_split(painter, n - 1)
        return stack(beside(top_left, corner),
                     beside(painter, bottom_right))
def square_limit(painter, n):
    combine4 = square_of_four(flip_horiz, identity, 
                                    turn_upside_down, flip_vert)
    return combine4(corner_split(painter, n))
# Click here to play with any abstraction
# used for square_limit

print(show(square_limit(heart, 4)))
