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


;x86-64 assembly code for Microsoft Windows
;Tested in windows 7 Enterprise Service Pack 1 64 bit
;With the AMD FX(tm)-6300 processor
;Assembled with NASM version 2.11.06 
;Linked to C library with gcc version 4.9.2 (x86_64-win32-seh-rev1, Built by MinGW-W64 project)
 
;Assembled and linked with the following commands:
;nasm -f win64 <filename>.asm -o <filename>.obj
;gcc <filename>.obj -o <filename>
 
;Takes magnitude of Sierpinski Carpet as command line argument.
 
extern atoi,puts,putchar,exit
 
section .data
errmsg_noarg: db "Magnitude of Sierpinski Carpet was not specified.",0
errmsg_argnumber: db "There should be no more than one argument.",0
 
section .bss
 
section .text
global main
 
main:
 
;check for argument
cmp rcx,1
jle err_noarg
 
;ensure that only one argument was entered
cmp rcx,2
jg err_argnumber
 
;column in rsi
;row in rdi
;x in r8
;y in r9
;width in r13
;magic number in r14
 
mov r14,2863311531
 
;get magnitude in rbx from first arg
mov rcx,[rdx + 8]
call atoi
mov rbx,rax
 
cmp rbx,0
jz magnitude_zero 
 
 
;determine dimensions of square
mov rax,1
 
find_width:
 
lea rax,[rax * 3]
 
dec rbx
jg find_width
 
sub rax,1
 
mov r13,rax
mov rdi,rax
 
 
next_row:
 
mov rsi,r13
 
fill_row:
 
;x in r8, y in r9
mov r8,rsi
mov r9,rdi
 
is_filled:
 
;if(x%3==1 && y%3==1)
;x%3 in rbx
mov rax,r8
mov rbx,r8
mul r14
shr rax,33
mov r8,rax
lea rax,[rax * 3]
sub rbx,rax
 
;y%3 in rcx
mov rax,r9
mov rcx,r9
mul r14
shr rax,33
mov r9,rax
lea rax,[rax * 3]
sub rcx,rax
 
;x%3==1 && y%3==1
xor rbx,1
xor rcx,1
or rbx,rcx
mov rcx,' '
cmp rbx,0
jz dont_fill
 
;x>0 || y>0
mov rax,r8
or rax,r9
cmp rax,0
jg is_filled
 
mov rcx,'#'
dont_fill:
 
call putchar
 
dec rsi
jge fill_row
 
;put newline at the end of each row
mov rcx,0xa
call putchar
 
dec rdi
jge next_row
 
xor rcx,rcx
call exit
 
magnitude_zero:
 
mov rcx,'#'
call putchar
 
mov rcx,0xa
call putchar
 
xor rcx,rcx
call exit
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;error message
 
err_noarg:
 
mov rcx,errmsg_noarg
call puts
 
mov rcx,1
call exit
 
 
err_argnumber:
 
mov rcx,errmsg_argnumber
call puts
 
mov rcx,1
call exit