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


$define FILLER "*"  # the filler character
 
procedure main(A)
 
   width := 3 ^ ( order := (0 < \A[1]) | 3 )
   write("Carpet order= ",order)
 
   every !(canvas := list(width)) := list(width," ")        # prime the canvas
 
   every y := 1 to width & x := 1 to width do               # traverse it
      if IsFilled(x-1,y-1) then canvas[x,y] := FILLER       # fill
 
   every x := 1 to width & y := 1 to width do 
      writes((y=1,"\n")|"",canvas[x,y]," ")                 # print
end
 
procedure IsFilled(x,y)                      #  succeed if x,y should be filled
   while  x ~= 0 & y ~= 0 do {
      if x % 3 = y %3 = 1 then fail
      x /:= 3
      y /:=3
      }
   return
end