Task
Produce a graphical or ASCII-art representation of a Sierpinski carpet of order   N.



For example, the Sierpinski carpet of order   3   should look like this:

###########################
# ## ## ## ## ## ## ## ## #
###########################
###   ######   ######   ###
# #   # ## #   # ## #   # #
###   ######   ######   ###
###########################
# ## ## ## ## ## ## ## ## #
###########################
#########         #########
# ## ## #         # ## ## #
#########         #########
###   ###         ###   ###
# #   # #         # #   # #
###   ###         ###   ###
#########         #########
# ## ## #         # ## ## #
#########         #########
###########################
# ## ## ## ## ## ## ## ## #
###########################
###   ######   ######   ###
# #   # ## #   # ## #   # #
###   ######   ######   ###
###########################
# ## ## ## ## ## ## ## ## #
###########################

The use of the   #   character is not rigidly required for ASCII art.

The important requirement is the placement of whitespace and non-whitespace characters.



Related task

   Sierpinski triangle


#include <order/interpreter.h>
 
#define ORDER_PP_DEF_8in_carpet ORDER_PP_FN( \
8fn(8X, 8Y, \
    8if(8or(8is_0(8X), 8is_0(8Y)), \
        8true, \
        8let((8Q, 8quotient(8X, 3)) \
             (8R, 8remainder(8X, 3)) \
             (8S, 8quotient(8Y, 3)) \
             (8T, 8remainder(8Y, 3)), \
             8and(8not(8and(8equal(8R, 1), 8equal(8T, 1))), \
                  8in_carpet(8Q, 8S))))) )
 
#define ORDER_PP_DEF_8carpet ORDER_PP_FN( \
8fn(8N, \
    8lets((8R, 8seq_iota(0, 8pow(3, 8N))) \
          (8G, 8seq_map(8fn(8Y, 8seq_map(8fn(8X, 8pair(8X, 8Y)), \
                                         8R)), \
                        8R)), \
           8seq_map(8fn(8S, 8seq_map(8fn(8P, 8apply(8in_carpet, 8P)), \
                                     8S)), \
                    8G))) )
 
#define ORDER_PP_DEF_8carpet_to_string ORDER_PP_FN( \
8fn(8C, \
    8seq_fold( \
      8fn(8R, 8S, \
          8adjoin(8R, \
                  8seq_fold(8fn(8P, 8B, 8adjoin(8P, 8if(8B, 8("#"), 8(" ")))), \
                            8nil, 8S), \
                  8("\n"))), \
      8nil, 8C)) )
 
#include <stdio.h>
 
int main(void) {
	printf(ORDER_PP( 8carpet_to_string(8carpet(3)) ));
	return 0;
}