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


var inCarpet = Fn.new { |x, y|
    while (true) {
        if (x == 0 || y == 0) return true
        if (x%3 == 1 && y%3 == 1) return false
        x = (x/3).floor
        y = (y/3).floor
    }
}
 
var carpet = Fn.new { |n|
    var power = 3.pow(n)
    for (i in 0...power) {
        for (j in 0...power) {
            System.write(inCarpet.call(i, j) ? "#" : " ")
        }
        System.print()
    }
}
 
carpet.call(3)