Автоматичний будинок-будівельник


15

Виготовлені автоматичні нанороботи для будівництва будинків, і ваше завдання їх кодувати.

Ось будинок, створений за допомогою введення 7 4 2

  /-----/|
 /     / |
|-----|  |
|     |  |
|     | /
|_____|/

Вхід - це рядок, що містить розміри будинку.

7 - ширина.

|_____|

---7---

4 - це висота.

|
|
|
|

2 - це глибина

 / 
/

З огляду на цей вклад, чи можете ви створити будинок?

Ваш код повинен бути якомога меншим, щоб він міг поміститися в роботах.

Примітки

Найменші розміри, які ви отримаєте як вхідні дані 3 2 2. Ваша програма може робити що завгодно з розмірами, меншими за 3 2 2.

Тестові шафи

3 2 10

          /-/|
         / / |
        / / /
       / / /
      / / /
     / / /
    / / /
   / / /
  / / /
 / / /
|-| /
|_|/


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

2
Більше тестів, будь ласка?
Лина монашка

1
Також це приємне питання. Я не думаю, що у нас ще є.
Rɪᴋᴇʀ

1
Для чого був би результат 3 2 10?
Пуховик

Відповіді:


3

Python 2, 128 байт

w,h,d=input();i=d
while-i<h:c='|/'[i>0];print' '*i+c+'- _'[(d>i!=0)+(h+i<2)]*(w-2)+c+' '*min(d-i,h-1,w+1,h-1+i)+'/|'[d-i<h];i-=1

Друкує рядок за рядком. Індекси рядків iвідлічуються від dдо -h+1.


Ви можете обрізати 3 байти, замінивши ' '*min(d-i,h-1,w+1,h-1+i)на(' '*d)[max(0,i):h-1+i]
RootTwo

1

Рубін, 145 байт

Повертає список рядків. Кожному елементу у списку відповідає рядок. Якщо потрібно повернути багаторядковий рядок, додайте 3 байти *$/безпосередньо перед останнім дужкою.

->w,h,d{s=' ';(0..m=d+h-1).map{|i|(i<d ?s*(d-i)+?/:?|)+(i<1||i==d ??-:i==m ??_ :s)*(w-2)+(i<d ? ?/:?|)+(i<h ?s*[i,d].min+?|:s*[m-i,h-1].min+?/)}}

1

JavaScript (ES6), 169 байт

(w,h,d)=>[...Array(d+h--)].map((_,i)=>` `[r=`repeat`](i<d&&d-i)+(c=`|/`[+(i<d)])+` _-`[i&&i-d?h+d-i?0:1:2][r](w-2)+c+` `[r]((i<d?i:d)-(i>h&&i-h))+`|/`[+(i>h)]).join`\n`

Де \nпредставляє буквальний символ нового рядка. Пояснення:

(w,h,d,)=>                          Parameters
[...Array(d+h--)].map((_,i)=>       Loop over total height = d + h
 ` `[r=`repeat`](i<d&&d-i)+         Space before roof (if applicable)
 (c=`|/`[+(i<d)])+                  Left wall/roof edge
 ` _-`[i&&i-d?h+d-i?0:1:2][r](w-2)+ Space, floor or eaves between walls
 c+                                 Right wall/roof edge (same as left)
 ` `[r]((i<d?i:d)-(i>h&&i-h))+      Right wall
 `|/`[+(i>h)]                       Back wall/floor edge
).join`                             Join everything together
`

Редагувати: збережено 2 байти завдяки @jrich.


Спробуйте зняти ,r='repeat'фронт і замініть перший [r]на[r='repeat']
jrich

@jrich Спасибі, я спочатку мав, ,r=(n,c=` `)=>c.repeat(n)і коли змінив такт, я не помітив можливості перестановки.
Ніл

1

Пітон 224 301 297 байт

(Зараз працює для всіх коробок, включаючи 1x1x1)

l,w,h=input()
s,r,d,v,R,x=" "," - ","/","|",range,(l*3-1)
print s*(w+1)+r*l
for n in R(w):
    if n<h:e,c=v,n
    else:e,c=d,h
    print s*(w-n)+d+s*x+d+s*c+e
if h-w>=1:e,c=v,w
elif w>h:e,c=d,h
else:e,c=d,w
print s+r*l+s*c+e
for n in R(h):
    if h>w+n:e,c=v,w
    else:e,c=d,h-n-1
    print v+s*x+v+s*c+e
print r*l

Пояснення:

Бере в три константи: l (довжина), h (висота), w (ширина).

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

Для вікна розміром 3 x 4 x 3 ми будемо використовувати цифри для представлення проміжків між секціями.

1234 -  -  - 
123/12345678/|
12/12345678/1|
1/12345678/12|
1 -  -  - 123|
|12345678|123/
|       8|12/
|       8|1/
|       8|/
 -  -  - 

У верхньому рядку є 4 пробіли, або що w + 1. Наступні три рядки мають w - (1 * x). X - лінія.

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

Ось зразок для коробки розміром 5 x 5 x2.

 123 -  -  -  -  -
 12/12345678912345/|
 1/              /1|
 1 -  -  -  -  - 12|
 |              |12|
 |              |12|
 |              |12|
 |              |1/
 |12345678912345|/
  -  -  -  -  -

Вам, мабуть, варто продовжити гольф.
Rɪᴋᴇʀ

Також вам потрібно призначити w,h,l=input()або зробити цю функцію.
Rɪᴋᴇʀ

Ласкаво просимо до головоломки програмування та коду для гольфу! Ми вимагаємо, щоб усі подання були або повноцінними програмами, які читають зі STDIN і записують у STDOUT, або функціями, які приймають аргументи та повертають значення. Ми також вимагаємо, щоб подання було серйозним претендентом на перемогу під час публікації, а це означає, що ми не допускаємо рішення, що не мають гольфу або частково не готуються для коду.
Олексій А.

Коли я запускаю цей код тут , у виході є додаткові пробіли.
Джеймс

@DrGreenEggsandHamDJ виправлено! Він не враховував певну схему h, w, l, тому я додав деякі if заяви.
JoshK

0

Python 3.5, 328 326 313 305 295 248 байт

( Дякую Кевіну Лау за пораду щодо зменшення розміру потрійних заяв! )

def s(w,h,d):R,M=range,max;S,V,L=' |/';O=w-2;D=d-M(0,d-h);Q=h-M(0,h-d);print('\n'.join([S*(d-i)+L+' -'[i<1]*O+L+S*[h-1,i][i<=D-1]+'/|'[i<=D-1]for i in R(D+M(0,d-h))]+[V+[' -'[i==h],'_'][i<2]*O+V+S*[i-1,d][i>Q]+'/|'[i>Q]for i in R(Q+M(0,h-d),0,-1)]))

Вводить введення у вигляді 3 цілих чисел у порядку width, height, depth. Буде гольф більше з часом, де б я міг.

Спробуйте в Інтернеті! (Ідеон)

Пояснення:

Для цілей цього пояснення припустимо, що функція виконувалася аргументами, (3,2,3)де 3 - ширина ( w), 2 - висота ( h), а 3 - глибина ( d). З цього приводу, дозвольте почати з показу основної частини всієї функції:

'\n'.join([S*(d-i)+L+' -'[i<1]*O+L+S*[h-1,i][i<=D-1]+'/|'[i<=D-1]for i in R(D+M(0,d-h))]+[V+[' -'[i==h],'_'][i<2]*O+V+S*[i-1,d][i>Q]+'/|'[i>Q]for i in R(Q+M(0,h-d),0,-1)])

Тут два списки, що складають весь "будинок", створюються, а потім об'єднуються буквально новими рядками ( \n). Давайте назвемо їх відповідно списком aта списком bта проаналізуємо кожен із них:

  • Ось де aстворено список :

    [S*(d-i)+L+' -'[i<1]*O+L+S*[h-1,i][i<=D-1]+'/|'[i<=D-1]for i in R(D+M(0,d-h))]
    

    У цьому списку містяться перші dрядки будинку. Ось, iкожне число в діапазоні, 0=>(d-(d-h))+d-hде d-h=0якщо мінус або нуль. Для початку d-iпробіли додаються до списку, а потім a, /а потім все, що повертається стислим умовним твердженням. У цьому умовному заяві w-2кількість пробілів повертається, якщо i>1. В іншому випадку -повертається така ж кількість . Потім за ними слідує інший /, а потім пробіли, де кількість пробілів зараз залежить від того, чи ні i<=d-(d-h)-1. Якщо це так, то iдодаються пробіли. В іншому випадку h-1пробіли додаються. Нарешті, це все доповнюється або a, /або a |, де |додається, якщо в i<=d-(d-h)-1іншому випадку a/додається. У разі 3x2x3призми це повернеться за списком a:

          /-/|
         / / |
        / / /
    
  • Ось де bстворено список :

    [V+[' -'[i==h],'_'][i<2]*O+V+S*[i-1,d][i>Q]+'/|'[i>Q]for i in R(Q+M(0,h-d),0,-1)]`
    

    Цей перелік містить решту рядків призми. У цьому списку i- кожне ціле число в діапазоні, (h-(h-d))+h-d=>0де - h-d=0мінус або нуль. Щоб розпочати цей список, спочатку |додається а, оскільки ці рядки завжди починаються з а |. Потім, або простір, -або _додається в залежності від того чи ні , i=hабо i<2. Якщо i<2, тоді _додається а. В іншому випадку, -додається чи i=h, або пробіл додається , якщо i>hабо i<hабо i>2. Після прийняття цього рішення w-2додається номер обраного символу. Після цього |додається інше , а потім додається i-1або dчисло, або кількість пробілів. Якщо i>h-(h-d), то аdкількість пробілів додано. В іншому випадку i-1додається кількість пробілів. Нарешті, це все доповнено або a, |або a /, в якому a |додається if i>h-(h-d), або a /додається if i<=h-(h-d). У разі 3x2x3призми список bповертає:

        |-| /
        |_|/
    

Після створення двох списків вони, нарешті, з'єднуються буквально новими рядками ( \n) '\n'.join(). Це ваша завершена призма, і в цьому випадку вийшло б так:

       /-/|
      / / |
     / / /
    |-| /
    |_|/

1
Бутові програми Python оцінюють до цілих чисел, а значить, більшість ваших тернарів може бути стиснуто до таких речей '-_'[f<2]. Нарешті, R=range;S,V,L=' |/'працює над призначенням ваших початкових змінних, оскільки рядки з радістю розпакують себе за вас у цій ситуації.
Значення чорнила

Неважливо, я забув, що оператора в Python не існує ... Але решта має працювати!
Значення чорнила

@ KevinLau-notKenny Вау, дякую за поради! :) Я не знав, що потрійні вирази можна висловити таким чином!
Р. Кап

Ви можете використовувати цей трюк для тернаріїв до тих пір, поки не зміните змінні всередині нього. Наприклад, a=1 if b<9 else c=5не можна виразити як, [a=1,c=5][b<9]тому що ви в остаточному підсумку видозмініть і aта, і c. Ось сторінка підказок для гольфу PPCG Python: codegolf.stackexchange.com/questions/54/…
Чорнило про вартість

У вас ще є одне потрійне , що по - , як і раніше існує, '_'if f<2else' -'[f==h]. Пам’ятайте, булеви оцінюють як цілі числа, щоб ви могли «ланцюжок» цього потрійника до іншого, який ви зафіксували [' -'[f==h],'_'][f<2]. Також ви ще не використовували мою пораду S,V,L=' |/'.
Значення чорнила
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.