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


 
/* Sierpinski carpet */
 
Sierpinski_carpet: procedure options (main); /* 28 January 2013 */
 
  call carpet(3);
 
In_carpet: procedure (a, b) returns (bit(1));
  declare (a, b) fixed binary nonassignable;
  declare (x, y) fixed binary;
  declare (true value ('1'b), false value ('0'b)) bit (1);
 
   x = a ; y = b;
   do forever; 
      if x = 0 | y = 0 then
         return (true);
      else if mod(x, 3) = 1 & mod(y, 3) = 1 then
         return (false);
      x = x / 3;
      y = y / 3;
   end;
end in_carpet;
 
Carpet: procedure (n);
  declare n fixed binary nonassignable;
  declare (i, j) fixed binary;
 
  do i = 0 to 3**n - 1;
     do j = 0 to 3**n - 1;
        if In_carpet(i, j) then
           put edit ('#') (a);
        else
           put edit (' ') (a);
     end;
     put skip;
  end;
end Carpet;
end Sierpinski_carpet;
 