ASCII Мистецтво дня №3 - Китайські святині


16

У сьогоднішньому епізоді AAOD ми збираємося побудувати китайську святиню різної висоти.

Розглянемо наступні приклади для висоти ( N) 1до6

N = 1:

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

N = 2:

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

N = 3:

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

N = 4:

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

N = 5:

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

N = 6:

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

і так далі.

Деталі будівництва

Я впевнений, що більшість деталей щодо візерунка зрозумілі. Ось кілька тонких деталей:

  • Двері в нижній частині святині можуть бути як мінімум 1 _шириною, а максимум - 5 _шириною.
  • Завжди завжди буде два .над стовпами навколо дверей (два вертикальних |).
  • Сходи починаються з тієї ж ширини, що і двері, і збільшуються, як показано на малюнку
  • Ці ]##..##[блоки над кожним рівнем даху збільшуються в розмірах 2від верхньої частини до нижньої частини .
  • Рівень \__...__/дахів збільшується в розмірі 4зверху вниз.
  • Блоки стін навколо дверей повинні як мінімум містити між собою 1 _і максимум3 _| . Пріоритет стосується зовнішніх стінових блоків, щоб той, який знаходиться найближче до дверей, набував різного розміру для кожного рівня.
  • Простір між .і ](або [) заповнюється #на даху безпосередньо над дверима.

Деталі виклику

  • Напишіть функцію або повну програму, яка зчитує позитивне ціле число більше, ніж 0через аргумент STDIN / ARGV / функції або найближчий еквівалент і виводить (до STDOUT або найближчий еквівалент) Nth Shrine of Chinese
  • Новий рядок не є обов'язковим.
  • Не повинно бути або пробілів, або достатньо пробілів, щоб розмістити висновок у мінімальному обмежувальному прямокутнику.
  • Не повинно бути провідних пробілів, які не входять до шаблону.

Таблиця лідерів

Перший пост серії генерує таблицю лідерів.

Щоб переконатися, що ваші відповіді відображаються, будь ласка, почніть кожну відповідь із заголовка, використовуючи такий шаблон Markdown:

# Language Name, N bytes

де Nрозмір вашого подання. Якщо ви покращите свій рахунок, ви можете зберегти старі бали у заголовку, прокресливши їх. Наприклад:

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

Ширина дверей здається мені досить довільною - чому вона 1 у N=1випадку? Чому б не 3 і мати менші бічні вікна, як у N=2випадку?
Матті

Крім того N=1, чи не є перша дах занадто довгою (широкою)?
Матті

@ Матін щодо дверей - якщо двері були шириною 3, то не було б #поруч із .опорою ]та [над нею. Про початковий розмір даху - такий розмір даху у верхній даху кожної висоти.
Оптимізатор

Я запитував про самий нижній дах, безпосередньо над вікнами. У всіх інших випадках це розмір даху над ним +4 (+2 з обох боків). Але ось це +8.
Матті

@ Матті ой, ти маєш рацію. Виправлено.
Оптимізатор

Відповіді:


2

CJam, 200 байт

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

Нові рядки додано, щоб уникнути прокрутки. Спробуйте в Інтернеті

Коротке пояснення:

Програма будує ліву половину святині (включаючи середину), потім перевертає її і замінює деякі символи, щоб отримати праву половину. Серія n пробілів представлена ​​у вигляді числа ~ n (порозрядно "не") під час побудови та замінена фактичними пробілами в кінці.

Програма починається з верхніх 2 рядків, потім для кожного рівня даху вона попередньо подає всі попередні рядки з 2 пробілами та додає новий дах (2 лінії). Остання покрівля модифікована, щоб додати частину "вище дверей".

Далі верхня стіна будується повторенням "| __" і обрізанням на потрібній довжині, а потім фіксованим "_ |" і пробіли. Потім стіна дублюється, а дверні проміжки замінюються підкресленнями. Нарешті, нижня частина будується за рядком.


5

Перл, 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)

Спробуй мене .

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

Спробуй мене .

JavaScript, 365

Вищезазначене можна перекласти майже з 1 по 1 на 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));}

Використання:

f(2);console.log(r)

Версія C випадає з розмірами вище 12. Оскільки, схоже, ви використовуєте рядок фіксованого розміру для отримання тимчасових результатів, я думаю, у вас завжди буде верхня межа, незалежно від того, як ви обираєте розмір s. Якщо, звичайно, не виділити його динамічно.
Рето Коради

@RetoKoradi, Так, ви праві, я помилково розмістив версію з невеликим буфером. Але врешті-решт, якщо це не буде розподілено динамічно, завжди буде межа.
nutki

4

Python 2, 356 352 347 344 байт

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)

Це в основному будує святиню по черзі. Функція pдрукує рядок з пробілами, необхідними для її центрування.

Я використовував python 2, щоб зберегти багато байт, тому що об'єкт карти python 3 не спрацьовує. Я думаю, я завжди повинен гольфувати в python 2 , просто економить ще кілька байтів (навіть якщо це просто не потрібно розбирати вхід до int). Хе-хе, в першу чергу це не схоже на код для гри в гольф.

Редагувати: і звичайно, мені зараз карта більше не потрібна ...

Ось код у безгольовому вигляді:

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) + '\\')

1
Так як ви використовуєте Python 2 ви можете змінити print(B*(5+2*n-len(s)//2)+s)в print B*(5+2*n-len(s)/2)+s(прибрати дужки і зміни //в /).
користувач12205

1
Дякую @ace, не знав, python2 проігнорував поплавковий поділ.
Матті

1
@Matty Він не ігнорує поплавковий поділ. Ви виконуєте ділення на цілі числа , тому результат є цілим числом. Він поділяє поплавок лише тоді, коли один або більше операндів є поплавком.
mbomb007

2
Якщо змінити порядок , print B*(5+2*n-len(s)/2)+sщоб print(5+2*n-len(s)/2)*B+s, ви можете видалити пробіл після print.
isaacg

4

JavaScript ( ES6 ), 440

Редагувати виправлену помилку з підводкою

Функція з висотою як параметр, вихід на консоль.

Використовуючи рядок шаблонів дуже багато , всі нові рядки є значущими і підраховуються.

Запустіть фрагмент для тестування в Firefox (з консольним виходом)

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

Невикористана версія для інтерактивного тесту:

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


2

Haskell, 473 байт

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])

Добре, дякую. Виглядає зараз правильно
Демієн

Я думаю, зараз це нормально. До речі, база у вашій святині N = 1 має ще один номер
Дамієн

Так, зараз працює. Виправлено те, що додатково ненавмисне#
Optimizer

0

C, 660 байт

Шаблон, здавалося, був надто нерегулярним, щоб придумати щось фантазійне, особливо мовою без обробки рядків. Тож ось мій грубий підхід:

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

Перед гольфом:

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

Тут не так багато пояснювати. Він просто йде по черзі і генерує необхідну кількість кожного символу. Я намагався тримати код компактним, але він все ще додається. d- ширина дверей, wширина кожної цегляної стіни.


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);}
користувач12205
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.