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
. Будет ли гольф больше со временем, где я могу.
Попробуйте онлайн! (Ideone)
Объяснение:
В целях этого объяснения предположим, что функция была выполнена с аргументами, (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
). Давайте назовем их list a
и list 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
в список добавляются пробелы, после которых следует символ «а», /
а затем все, что возвращается сжатым условным оператором. В этом условном выражении w-2
число пробелов возвращается, если i>1
. В противном случае -
возвращается такое же количество . Затем за ними следуют другие /
, а затем пробелы, где количество пробелов теперь зависит от того, стоит или нет i<=d-(d-h)-1
. Если это так, то i
пробелы добавляются. В противном случае h-1
пробелы добавляются. Наконец, все это завершается либо a, /
либо a |
, где |
добавляется if 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
если отрицательный или ноль. Чтобы начать этот список, сначала |
добавляется a, так как эти строки всегда начинаются с a |
. Затем либо пробел, -
либо _
добавляется в зависимости от того, или нет, 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
возвращает:
|-| /
|_|/
После того, как 2 списка были созданы, они, наконец, объединяются с помощью новых буквенных строк ( \n
) с помощью '\n'.join()
. Это ваша законченная призма, и в этом случае она будет выглядеть так:
/-/|
/ / |
/ / /
|-| /
|_|/