# ASCII Art of the Day #3 - Chinese Shrines

In today's episode of AAOD, we are going to construct a Chinese Shrine of varying heights.

Consider the following examples for height (N) 1 to 6

N = 1:

       .
|
.   ]#[   .
\_______/
.    ]###[    .
\__]#.-.#[__/
|___| |___|
|___|_|___|
####/_\####
|___|
/_____\


N = 2:

         .
|
.   ]#[   .
\_______/
.    ]###[    .
\___________/
.     ]#####[     .
\___]#.---.#[___/
|__|_|   |_|__|
|__|_|___|_|__|
#####/___\#####
|_____|
/_______\


N = 3:

           .
|
.   ]#[   .
\_______/
.    ]###[    .
\___________/
.     ]#####[     .
\_______________/
.      ]#######[      .
\____]#.-----.#[____/
|__|__|     |__|__|
|__|__|_____|__|__|
######/_____\######
|_______|
/_________\


N = 4:

             .
|
.   ]#[   .
\_______/
.    ]###[    .
\___________/
.     ]#####[     .
\_______________/
.      ]#######[      .
\___________________/
.       ]#########[       .
\_____]##.-----.##[_____/
|__|__|_|     |_|__|__|
|__|__|_|_____|_|__|__|
########/_____\########
|_______|
/_________\


N = 5:

               .
|
.   ]#[   .
\_______/
.    ]###[    .
\___________/
.     ]#####[     .
\_______________/
.      ]#######[      .
\___________________/
.       ]#########[       .
\_______________________/
.        ]###########[        .
\______]###.-----.###[______/
|__|__|___|     |___|__|__|
|__|__|___|_____|___|__|__|
##########/_____\##########
|_______|
/_________\


N = 6:

                 .
|
.   ]#[   .
\_______/
.    ]###[    .
\___________/
.     ]#####[     .
\_______________/
.      ]#######[      .
\___________________/
.       ]#########[       .
\_______________________/
.        ]###########[        .
\___________________________/
.         ]#############[         .
\_______]####.-----.####[_______/
|__|__|__|__|     |__|__|__|__|
|__|__|__|__|_____|__|__|__|__|
############/_____\############
|_______|
/_________\


and so on.

# Construction Details

I am sure most of the details about the pattern are clear. Here are some finer details:

• The door at the bottom of the shrine can at minimum be of 1 _ width and at maximum be of 5 _ width.
• There will always be two . directly above the pillars around the door (two vertical |).
• The stairs start with the same width as the door and increase like show in the pattern
• The ]##..##[ blocks above each roof level increase in size of 2 from top to bottom.
• The \__...__/ roofs levels increase in size of 4 from top to bottom.
• The walls blocks around the door should at minimum contain 1 _ and at maximum, 3 _ between the two |. Priority goes to the outer wall blocks so that the one closest to the door gets a varying size for each level.
• The space between the . and the ] (or [) is filled by # in the roof just above the doors.

# Challenge Details

• Write a function or full program that reads a positive integer greater than 0 via STDIN/ARGV/function argument or closest equivalent and outputs (to STDOUT or closest equivalent) the Nth Chinese Shrine
• Trailing newline is optional.
• There should either be no trailing spaces or enough trailing spaces to pad the output in the minimum bounding rectangle.
• There should not be any leading spaces that are not part of the pattern.

The first post of the series generates a leaderboard.

# Language Name, N bytes


where N is the size of your submission. If you improve your score, you can keep old scores in the headline, by striking them through. For instance:

# Ruby, <s>104</s> <s>101</s> 96 bytes

• The door width seems rather arbitrary to me - why is it 1 in the N=1 case? Why not 3 and have smaller side windows like in the N=2 case? May 22, 2015 at 13:49
• Also, in the N=1 case, isn't the first rooftop too long (wide)? May 22, 2015 at 13:58
• @Matty regarding door - if door was of width 3, then there would be no # beside the . to support the ] and [ above it. About the starting roof size - That is the roof size in each height's top roof. May 22, 2015 at 14:00
• I was asking about the bottom most roof just above the windows. In all other cases it is the size of the roof above it +4 (+2 on either sides). But here it is +8. May 22, 2015 at 14:18
• @Matty oh, you are right. Fixed. May 22, 2015 at 14:21

# Perl, 332 316 294

$:=($w=<>)*2+6;$r=2x($m=$w>3?3:$w);$k=1x($w-3).b.4x$m; y!a-f1-4!/.|\$,#_ -!,/,/,s/(.*),(.*).{@{-}}/21/,printf"%:s%s ",y!/\\[!\\/]!r,(reverse=~s/.//r)for@x=(b,c, (map{b33.3x_.e.1x_,"[#k,"x/w/.a__.22x_}1..++w), _c.3xm.f.(z=substr"|__"x:,0,2*++w),"_|r,z","dr,".11xw,c_.r,d__.r)  Try me. # C, 371 d,i,w;char s[1<<24];m(){v(w,13);}p(){puts(s+1);} v(i,j){s[w-i]=".|]\\#/"[j%7];s[w+i]=".|[/#\\"[j%7]; while(i--)s[w-i]=s[w+i]="# _-"[j/7];} main(l){scanf("%d",&l);d=l>3?3:l;m(w=l*2+6);p(v(0,0)); for(v(0,1);i++<=l;v(i*2+2,17))p(),v(i*2+3,7),m(p(v(i,2)));v(l+2,2);p(v(d,21)); for(m(i=w-3);i>d+1;i-=3)v(i,15);p(v(d,8));p(v(d,15)); v(w-3,4);m(p(v(d,19)));p(v(d+1,15));p(v(d+2,19));}  Try me. # JavaScript, 365 The above can be translated almost 1 to 1 into JavaScript: s=[];r="";i=0;m=()=>v(w,13);p=()=>r+=s.join('')+"\n"; v=(i,j)=>{s[w-i]=".|]\\#/"[j%7];s[w+i]=".|[/#\\"[j%7]; while(i--)s[w-i]=s[w+i]="# _-"[j/7|0];}; f=l=>{d=l>3?3:l;m(w=l*2+6);p(v(0,0)); for(v(0,1);i++<=l;v(i*2+2,17))p(),v(i*2+3,7),m(p(v(i,2)));v(l+2,2);p(v(d,21)); for(m(i=w-3);i>d+1;i-=3)v(i,15);p(v(d,8));p(v(d,15)); v(w-3,4);m(p(v(d,19)));p(v(d+1,15));p(v(d+2,19));}  Use: f(2);console.log(r)  • The C version crashes for sizes above 12. Since it looks like you're using a fixed size string to hold temporary results, I think you'll always have an upper limit, no matter how you choose the size of s. Unless you allocate it dynamically, of course. May 24, 2015 at 15:44 • @RetoKoradi, Yes you are right, I posted version with a small buffer by mistake. But in the end, unless it is dynamically allocated there always will be a limit. May 24, 2015 at 15:56 # Python 2, 356352347 344 bytes n=input() A,B,C,D,E,F,G,H,I='_ |\/#.][' def p(*S): for s in S:print(5+2*n-len(s)/2)*B+s p(G,C,'. ]#[ .') for i in range(n):b=B*(4+i);p(D+A*(7+4*i)+E,G+b+H+F*(3+2*i)+I+b+G) d=2*min(3,n)-1 a=A*(2+i) f=F*(1+i-d/2) j=4+2*i-d/2 w=('|__'*n)[:j-1]+A+C v=w[::-1] p(D+a+H+f+G+'-'*d+G+f+I+a+E,w+B*d+v,w+A*d+v,F*j+E+A*d+D+F*j,C+A*(d+2)+C,E+A*(d+4)+D)  This basically builds the shrine line by line. The function p prints a string with the spaces needed to center it. I used python 2 to save lots of bytes, because the python 3 map object doesn't trigger. I guess I should always golf in python 2, just saves a few more bytes (even if it's just to not have to parse the input to int). Hehehe, it's not like code's pretty for golfing in the first place. Edit: and of course, I now don't need the map anymore... Here's the code in ungolfed form: n = int(input()) # A function to print strings centered half_width = 5 + 2*n def p(string): spaces = ' ' * (half_width - len(string) // 2) print(spaces + string) # The rooftops p('.') p('|') p('. ]#[ .') for i in range(n): p('\\' + '_'*(7 + 4*i) + '/') p('.{0}]{1}[{0}.'.format(' '*(i + 4), '#'*(3 + 2*i))) # The bottom rooftop door_width = 2 * min(3, n) - 1 # (11+4i - (3+2i) - 4) / 2 = (4 + 2i) / 2 = 2 + i p('\{0}]{1}.{2}.{1}[{0}/'.format('_'*(2 + i), '#'*(1 + i - door_width // 2), '-'*door_width)) # The windows w = '|__'*n w = w[:4 + 2*i - door_width // 2] if w[-1] == '|': w = w[:-1] + '_' w += '|' p(w + ' '*door_width + w[::-1]) p(w + '_'*door_width + w[::-1]) # The foundation and the stairs w = '#'*(4 + 2*i - door_width // 2) p(w + '/' + '_'*(door_width) + '\\' + w) # The remaining stairs p('|' + '_'*(door_width + 2) + '|') p('/' + '_'*(door_width + 4) + '\\')  • Since you're using Python 2 you can change print(B*(5+2*n-len(s)//2)+s) into print B*(5+2*n-len(s)/2)+s (remove parentheses and change // into /). May 22, 2015 at 19:22 • Thanks @ace, didn't know python2 ignored float division. May 22, 2015 at 19:38 • @Matty It doesn't ignore float division. You're performing division on integers, so the result is an integer. It only does float division if one or more operands is a float. May 22, 2015 at 21:58 • If you rearrange the order of print B*(5+2*n-len(s)/2)+s to print(5+2*n-len(s)/2)*B+s, you can remove the space after print. May 22, 2015 at 23:51 # JavaScript (ES6), 440 Edit Fixed lintel bug A function whith height as a parameter, output to console. Using template string a lot, all newlines are significant and counted. Run snippet to test in Firefox (with console output) f=x=>{R=(n,s=0)=>' #_-'[s][Z='repeat'](n),M=c=>R(2)+'|__'[Z](z+1).slice(0,z-1)+'_|'+R(y,c)+'|_'+'__|'[Z](z+1).slice(1-z) for(z=x+x+(x<2)+(x<3),y=x>2?5:x>1?3:1,l=-1,o={t=R(x+x+5)}. {t}| ;l++<x;)o+={t=R(x+x-l-l)}.{u=R(l+3)}]{R(l*2+1,1)}[{u}. {t}\\{l-x?R(7+l*4,2):{t=R(x+1,2)}]{u=R(x<3||x-2,1)}.{R(y,3)}.{u}[{t}}/ ;console.log({o+M(0)} {M(2)} {R(2)}{t=R(z,1)}/{u=R(y,2)}\\{t} {R(1+z)}|__{u}| {R(z)}/____{u}\\)} // TEST f(1),f(2),f(3),f(4),f(5),f(6) Output 1 to 6 in console Ungolfed version for interactive test: // Not so golfed f=x=>{ R=(n,s=0)=>' #_-'[s].repeat(n); // base building blocks M=c=>R(2)+'|__'.repeat(z+1).slice(0,z-1)+'_|'+R(y,c)+'|_'+'__|'.repeat(z+1).slice(1-z); // manage door level z=x+x+(x<2)+(x<3); // door and stairs surroundings y=x>2?5:x>1?3:1; // door and stairs width o = {R(x+x+5)}.\n{R(x+x+5)}|\n; // top for(l=-1;l++<x;) o += { // even row t=R(x+x-l-l) // left padding }.{ u=R(l+3) }]{ R(l*2+1,1) }[{ u }.\n { // end even row, start odd row t // left padding }\\{ l-x?R(7+l*4,2) :{t=R(x+1,2)}]{u=R(x<3||x-2,1)}.{R(y,3)}.{u}[{t} // if last row before the door, insert lintel }/\n; o += { M(0) // door level row 1 }\n{ M(2) // door level row 2 }\n{ R(2)}{t=R(z,1)}/{u=R(y,2)}\\{t // stairs row 1 }\n{ R(1+z)}|__{u // stairs row 2 }|\n{ R(z)}/____{u // stairs row 3 }\\; out(o) } out=x=>O.innerHTML=x f(3) <input id=I value=3><button onclick='f(+I.value)'>-></button><br> <pre id=O></pre> # Vyxal, 280 bytes d5+\.꘍,d5+\|꘍,(n-d:£\.꘍3n+$꘍\#nd›*$3n+\.꘍Ṡ,¥›\\꘍ndd7+\_*\/Ṡ,)\.?3+꘍$\#?d›*$?3+\.꘍Ṡ,ð\\?›\_*$?2-1∴\#*\.?d‹5∵-\.?2-1∴\#*$?›\_*\/Ṡ,3<[⟨0|⟨3⟩|⟨2|1⟩⟩i|3/⌊d2wẋf013?3%iIJ';]\_*Ṅðpð+ð\|Vðdp:£3?∵꘍øm,¥3?∵\_*+øm,4<[3+|d]\#*:£ðdp\/\_?d‹5∵*\\¥Ṡ,¥L›\|꘍\_?d‹5∵⇧*\|Ṡ,¥L\/꘍\_?d‹5∵4+*\\Ṡ,  Try it Online! No, I'm not explaining this. # Charcoal, 404 bytes ≔Ｎν≔⁺⁵×²νη≔× ⁻η⁻∕¹¦²¦¹τ⁺⁺⁺⁺⁺τ.¶τ|¶× ⁻η⁻∕¹²¦²¦¹“±∨N"G:Ｗ⮌+”Ｆν«≔⁺⁺\×_⁺⁷×⁴ι/ε≔× ⁻η⁻∕Ｌε²¦¹τ⁺⁺τε¶≔⁺⁺⁺⁺.× ⁺ι⁴]×#⁺³×²ι⁺⁺[× ⁺ι⁴.ε≔× ⁻η⁻∕Ｌε²¦¹τ⁺⁺τε¶»≔⁻×²⌊⟦³ν⟧¹δ≔∕δ²ζ≔×#⁺¹⁻νζσ≔⁺⁺⁺⁺⁺\×_⁺ν¹]σ.⁺×-δ⁺.⁺σ⁺[⁺×_⁺ν¹/ε≔× ⁻η⁻∕Ｌε²¦¹τ⁺⁺τε¶≔×|__νε≔⁻⁻⁺⁴×²νζ¹τ≔✂ε⁰τ¦¦ε≔Ｌεα≔⁻Ｌε¹β¿⁼✂εβα¦¦|«≔⁺✂ε⁰β¦¦_ε»≔⁺✂ε⁰α¦¦|ε≔⁺⁺ε× δ⮌εα≔⁺⁺ε×_δ⮌εβＭ⁼ν¹¦⁰⁺⁺⁺⁺ α¶¦ βＭ±⁼ν¹¦⁰Ｍ±Ｌα⁰≔×#⁻⁺⁴×²⁻ν·⁵ζε⁺¶⁺⁺ε⁺/⁺⁺×_δ\ε¶≔⁻⁻⁺⁴×²⁻ν·⁵ζ¹ψ⁺× ψ⁺|⁺×_⁺δ²|¶⁺× ⁻ψ¹⁺/⁺×_⁺δ⁴\  Try it online! # CJam, 200 bytes -4'.-4'|]2/ri:M),{2af.-~[W'.I3+~']'#I)*][-2'\'_I2*4+*]]}fI~[~M)<'] M2m1e>'#*'.'-M3e<:D*][-3"|__"M*M2+M2*(e>:L<"_|"D~][_~~'_*][-3'#L)* '/'_D*][L2+~'|'_D)*][L)~'/'_D2+*]]{{_0<{~S*}&}%s_W%1>"\/]""/\["erN}%  Newlines added to avoid scrolling. Try it online Brief explanation: The program builds the left half of the shrine (including the middle), then reverses it and replaces some characters to get the right half. A series of n spaces is represented as the number ~n (bitwise "not") during construction, and replaced with the actual spaces at the end. The program starts with the top 2 lines, then for each roof level, it prepends all the previous lines with 2 spaces and adds the new roof (2 lines). The last roof is modified to add the "above door" part. Next, the upper wall is built by repeating "|__" and truncating at the right length, followed by a fixed "_|" and spaces. The wall is then duplicated and the door spaces are replaced with underscores. Finally, the lower part is constructed line by line. # Haskell, 473 bytes g '\\'='/' g '/'='\\' g '['=']' g ']'='[' g x=x z=reverse d=min 3 m n s=putStrLn(6+2*n+1-length s)#' '++map g(z s)++tail s n#c=replicate n c t 0=".";t n=n#'#'++"["++(2+n)#' '++"." r 0="|";r n=(2+2*n)#'_'++"/" q n=d n#'-'++"."++max(n-2)1#'#'++"["++(n+1)#'_'++"/" e i n=d n#i++"|_"++z(take(max(n+2)(2*n-1))(cycle"|__")) b n=d n#'_'++"\\"++max(2*n)(3+n)#'#' w i n=(d n+1+i)#'_'++["|","\\"]!!i f n=mapM_(m n)[u k|k<-[0..n],u<-[t,r]]++(t(n+1):map(n)[q,e ' ',e '_',b,w 0,w 1])  • OK thanks. Looks correct now May 23, 2015 at 13:22 • I think it's OK now. btw, the base in your N=1 shrine has one more # May 23, 2015 at 13:38 • Yup, works now. Fixed that extra unintended # May 23, 2015 at 13:52 # Vyxal, 120 113 bytes 3∵£\.\|?›ƛ⇧\.꘍\[+\#n*+\\\_n›d*+";f÷?⇧Ẏ$+?⇩1∴\#*+\.+¥-|__?:3>[d‹|⇧]Ẏ‛_|+¥꘍:ð\_VȮȧL‹\#*\/+‛|/fJ2ʀ¥+\_*+÷WvøMøĊ⁋  Try it Online! Posting this as a separate answer because it's so golfed, and uses the latest version of Vyxal. ## Explanation ----------------- TOP ------------ 3∵£ # Store min(input, 3) into the register for later use \.\| # Push a . and a | ?›ƛ ; # Map 1...input+1 to ⇧\.$꘍                      # That+2 spaces after a dot
$+ # Append a [ \#n*+ # Append that many # \_n›d* # That+1 underscores \\ +" # Appended to a \ and paired with the previous f÷ # All of that flattened and each pushed to the stack ------------------- Doorway ------------------ ?⇧Ẏ # To the last of what was pushed in the previous, take the first input+2 characters$+                                         # Append a ]
?⇩1∴\#*+                                 # Append min(input-2,1) hashes
\.+                              # Append a .
¥-                            # Append min(input,3) -
?:3>[d‹|⇧]             # Input*2-1 if input>3 else input+2
|__          Ẏ            # Repeat '|__' to that length
‛_|+        # Append '_|'
¥꘍      # Append min(input,3) spaces
:ð\_V # Make a copy, and replace spaces with underscores

---------- Entrance ------------
ȮȧL‹\#*\/+
ȮȧL                      # Length of top part of doorway with whitespace removed
‹\#*\/+               # That-1 #, plus a /
‛|/fJ          # Append ['|','/']
2ʀ¥+      # [a,a+a,a+2] where a = min(3,input)
\_*+  # That many underscores appended to each of previous
÷ # Iterate out those on the stack

- Final magic bit -
W       # Get the stack
vøM    # Palindromise each, mirroring brackets
øĊ  # Center each
⁋ # Join on newlines


## C, 660 bytes

The pattern just seemed to be too irregular to come up with anything fancy, particularly in a language without string processing. So here is my brute force approach:

m,d,w,k,j;r(n,c){for(j=0;j++<n;)putchar(c);}c(char*s){for(;*s;)putchar(*s++);}f(n){m=n*2;d=n<3?m-1:5;w=m-d/2+2;r(m+5,32);c(".\n");r(m+5,32);c("|\n");for(;;){r(m-k*2,32);c(".");r(k+3,32);c("]");r(k*2+1,35);c("[");r(k+3,32);c(".\n");if(k==n)break;r(m-k*2+1,32);c("\\");r(k++*4+7,95);c("/\n");}c(" \\");r(n+1,95);c("]");r(n-d/2,35);c(".");r(d,45);c(".");r(n-d/2,35);c("[");r(n+1,95);c("/\n");for(k=0;k<2;){c("  ");for(j=0;j<w/3;++j)c("|__");c("|_|"-w%3+2);r(d,k++?95:32);c(!w%3?"|":w%3<2?"|_":"|_|");for(j=0;j<w/3;++j)c("__|");c("\n");}c("  ");r(w,35);c("/");r(d,95);c("\\");r(w,35);c("\n");r(w+1,32);c("|");r(d+2,95);c("|\n");r(w,32);c("/");r(d+4,95);c("\\\n");}


Before golfing:

#include <stdio.h>

void r(int n, int c) {
for (int i = 0; i++ < n; )
putchar(c);
}

void c(char* s) {
for (; *s; ++s) putchar(*s);
}

int f(int n) {
int m = n * 2;
int d = n < 3 ? m - 1 : 5;
int w = m - d / 2 + 2;

r(m + 5, 32);
c(".\n");

r(m + 5, 32);
c("|\n");

for (int k = 0; ; ++k) {
r(m - k * 2, 32);
c(".");
r(k + 3, 32);
c("]");
r(k * 2 + 1, 35);
c("[");
r(k + 3, 32);
c(".\n");

if (k == n) break;

r(m - k * 2 + 1, 32);
c("\\");
r(k * 4 + 7, 95);
c("/\n");
}

c(" \\");
r(n + 1, 95);
c("]");
r(n - d / 2 , 35);
c(".");
r(d, 45);
c(".");
r(n - d / 2 , 35);
c("[");
r(n + 1, 95);
c("/\n");

for (int k = 0; k < 2; ++k) {
c("  ");
for (int j = 0; j < w / 3; ++j)
c("|__");
c("|_|" - w % 3 + 2);
r(d, k ? 95 : 32);
c(!w % 3 ? "|" : w % 3 < 2 ? "|_" : "|_|");
for (int j = 0; j < w / 3; ++j)
c("__|");
c("\n");
}

c("  ");
r(w, 35);
c("/");
r(d, 95);
c("\\");
r(w, 35);
c("\n");

r(w + 1, 32);
c("|");
r(d + 2, 95);
c("|\n");

r(w, 32);
c("/");
r(d + 4, 95);
c("\\\n");

return 0;
}


Not much to explain here. It just goes line by line, and generates the necessary count of each character. I tried to keep the code itself compact, but it still adds up. d is the width of the door, w the width of each brick wall.

• c(char*s){for(;*s;)putchar(*s++);} ==> #define c printf; r(n,c){for(j=0;j++<n;)putchar(c);} ==> r(n,C){while(n--)putchar(C);} May 23, 2015 at 22:47