Art ASCII du jour # 3 - Sanctuaires chinois

16

Dans l'épisode d'aujourd'hui de l'AAOD, nous allons construire un sanctuaire chinois de différentes hauteurs.

Considérez les exemples suivants pour height ( N) 1to6

N = 1:

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

N = 2:

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

N = 3:

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

N = 4:

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

N = 5:

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

N = 6:

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

etc.

Détails de construction

Je suis sûr que la plupart des détails sur le motif sont clairs. Voici quelques détails plus fins:

  • La porte au bas du sanctuaire peut être au minimum de 1 _largeur et au maximum être de 5 _largeur.
  • Il y en aura toujours deux .directement au-dessus des piliers autour de la porte (deux verticaux |).
  • Les escaliers commencent avec la même largeur que la porte et augmentent comme indiqué dans le motif
  • Les ]##..##[blocs au-dessus de chaque niveau de toit augmentent en taille de 2haut en bas.
  • Les \__...__/niveaux des toits augmentent en taille de 4haut en bas.
  • Les blocs de murs autour de la porte doivent au minimum contenir 1 _et au maximum 3 _entre les deux |. La priorité va aux blocs muraux extérieurs afin que celui le plus proche de la porte ait une taille variable pour chaque niveau.
  • L'espace entre le .et le ](ou [) est rempli par #le toit juste au-dessus des portes.

Détails du défi

  • Écrire une fonction ou un programme complet qui lit un entier positif supérieur à 0via STDIN / ARGV / argument de fonction ou l'équivalent le plus proche et affiche (vers STDOUT ou l'équivalent le plus proche) le Ne sanctuaire chinois
  • Le retour à la ligne est facultatif.
  • Il ne doit pas y avoir d'espaces de fin ou suffisamment d'espaces de fin pour remplir la sortie dans le rectangle de délimitation minimum.
  • Il ne doit pas y avoir d'espaces de début qui ne font pas partie du motif.

Classement

Le premier post de la série génère un classement.

Pour vous assurer que vos réponses s'affichent, veuillez commencer chaque réponse par un titre, en utilisant le modèle Markdown suivant:

# Language Name, N bytes

Nest la taille de votre soumission. Si vous améliorez votre score, vous pouvez conserver les anciens scores dans le titre, en les rayant. Par exemple:

# Ruby, <s>104</s> <s>101</s> 96 bytes
Optimiseur
la source
La largeur de la porte me semble plutôt arbitraire - pourquoi est-ce 1 dans le N=1cas? Pourquoi pas 3 et avoir des fenêtres latérales plus petites comme dans le N=2cas?
Matty
De plus, dans le N=1cas, le premier toit n'est-il pas trop long (large)?
Matty
@Matty concernant la porte - si la porte était de largeur 3, alors il n'y aurait pas à #côté du .pour soutenir le ]et [au - dessus. À propos de la taille de toit de départ - C'est la taille du toit dans le toit supérieur de chaque hauteur.
Optimizer
Je posais des questions sur le toit le plus bas juste au-dessus des fenêtres. Dans tous les autres cas, c'est la taille du toit au-dessus de lui +4 (+2 de chaque côté). Mais ici, c'est +8.
Matty
@Matty oh, tu as raison. Fixé.
Optimizer

Réponses:

2

CJam, 200 octets

-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}%

Ajout de nouvelles lignes pour éviter le défilement. Essayez-le en ligne

Brève explication:

Le programme construit la moitié gauche du sanctuaire (y compris le milieu), puis l'inverse et remplace certains personnages pour obtenir la moitié droite. Une série de n espaces est représentée par le nombre ~ n (au niveau du bit "non") pendant la construction, et remplacée par les espaces réels à la fin.

Le programme commence par les 2 premières lignes, puis pour chaque niveau de toit, il ajoute toutes les lignes précédentes avec 2 espaces et ajoute le nouveau toit (2 lignes). Le dernier toit est modifié pour ajouter la partie "au dessus de la porte".

Ensuite, le mur supérieur est construit en répétant "| __" et en tronquant à la bonne longueur, suivi d'un "_ |" fixe et les espaces. Le mur est ensuite dupliqué et les espaces de porte sont remplacés par des soulignements. Enfin, la partie inférieure est construite ligne par ligne.

aditsu
la source
5

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/(.*),(.*).{@{-}}/$2$1/,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.3x$m.f.($z=substr"|__"x$:,0,2*++$w),"_|$r,$z","d$r,".11x$w,c_.$r,d__.$r)

Essayez- moi .

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));}

Essayez- moi .

JavaScript, 365

Ce qui précède peut être traduit presque 1 à 1 en 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));}

Utilisation:

f(2);console.log(r)
nutki
la source
La version C se bloque pour les tailles supérieures à 12. Comme il semble que vous utilisez une chaîne de taille fixe pour contenir des résultats temporaires, je pense que vous aurez toujours une limite supérieure, peu importe comment vous choisissez la taille de s. À moins que vous ne l'allouiez dynamiquement, bien sûr.
Reto Koradi
@RetoKoradi, Oui vous avez raison, j'ai posté une version avec un petit tampon par erreur. Mais au final, à moins qu'il ne soit alloué dynamiquement, il y aura toujours une limite.
nutki
4

Python 2, 356 352 347 344 octets

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)

Cela construit essentiellement le sanctuaire ligne par ligne. La fonction pimprime une chaîne avec les espaces nécessaires pour la centrer.

J'ai utilisé python 2 pour enregistrer de nombreux octets, car l' objet de carte python 3 ne se déclenche pas. Je suppose que je devrais toujours jouer au golf python 2 , économise juste quelques octets de plus (même si c'est juste pour ne pas avoir à analyser l'entrée dans int). Hehehe, ce n'est pas comme si le code était joli pour jouer au golf en premier lieu.

Edit: et bien sûr, je n'ai plus besoin de la carte maintenant ...

Voici le code sous forme non golfée:

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) + '\\')
Matty
la source
1
Puisque vous utilisez Python 2, vous pouvez le remplacer print(B*(5+2*n-len(s)//2)+s)par print B*(5+2*n-len(s)/2)+s(supprimer les parenthèses et le remplacer //par /).
user12205
1
Merci @ace, je ne savais pas que python2 ignorait la division flottante.
Matty
1
@Matty Il n'ignore pas la division flottante. Vous effectuez une division sur des entiers , donc le résultat est un entier. Il ne fait de division flottante que si un ou plusieurs opérandes sont un flottant.
mbomb007
2
Si vous réorganisez l'ordre de print B*(5+2*n-len(s)/2)+sà print(5+2*n-len(s)/2)*B+s, vous pouvez supprimer l'espace après print.
isaacg
4

JavaScript ( ES6 ), 440

Éditer bug du linteau fixe

Une fonction avec hauteur comme paramètre, sortie vers la console.

Beaucoup utiliser la chaîne de modèle , toutes les nouvelles lignes sont significatives et comptées.

Exécutez un extrait pour tester dans Firefox (avec sortie console)

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

Version non golfée pour test interactif:

// 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>

edc65
la source
2

Haskell, 473 octets

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])
Damien
la source
OK merci. Ça a l'air correct maintenant
Damien
Je pense que ça va maintenant. btw, la base de votre sanctuaire N = 1 a encore un #
Damien
Oui, ça marche maintenant. Correction de ce problème supplémentaire#
Optimiseur
0

C, 660 octets

Le modèle semblait juste trop irrégulier pour proposer quelque chose de fantaisiste, en particulier dans une langue sans traitement de chaîne. Voici donc mon approche par force brute:

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");}

Avant de jouer au golf:

#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;
}

Pas grand chose à expliquer ici. Il va juste ligne par ligne et génère le nombre nécessaire de chaque caractère. J'ai essayé de garder le code lui-même compact, mais il s'additionne toujours. dest la largeur de la porte, wla largeur de chaque mur de briques.

Reto Koradi
la source
1
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);}
user12205