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 "seed7_05.s7i";
 
const func boolean: inCarpet (in var integer: x, in var integer: y) is func
  result
    var boolean: result is TRUE;
  begin
    while result and x <> 0 and y <> 0 do
      if x rem 3 = 1 and y rem 3 = 1 then
        result := FALSE;
      else
        x := x div 3;
        y := y div 3;
      end if;
    end while;
  end func;
 
const proc: carpet (in integer: n) is func
  local
    var integer: i is 0;
    var integer: j is 0;
  begin
    for i range 0 to pred(3 ** n) do
      for j range 0 to pred(3 ** n) do
        if inCarpet(i, j) then
          write("#");
        else
          write(" ");
        end if;
      end for;
      writeln;
    end for;
  end func;
 
const proc: main is func
  begin
    carpet(3);
  end func;