Не можна побачити ліс для ключів


16

Напишіть програму або функцію, яка містить непорожній список цілих чисел у будь-якому розумному зручному форматі, наприклад, 4, 0, -1, -6, 2або [4 0 -1 -6 2].

Роздрукуйте або поверніть рядок, який зображує список як ліс мистецтва ASCII, де кожне число стає деревом пропорційної висоти. Кожне дерево займає чотири стовпці тексту у висновку таким чином:

  • Позитивне ціле число N стає деревом, основою якого є __|_і верх ^ , з N шарами / \між ними.

    Наприклад, коли N = 1 дерево

      ^
     / \
    __|_
    

    коли N = 2 дерево

      ^
     / \
     / \
    __|_
    

    коли N = 3 дерево

      ^
     / \
     / \
     / \
    __|_
    

    і так далі.

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

    Наприклад, коли N = -1 дерево

      ^
     /|\
    __|_
    

    коли N = -2 дерево

      ^
     /|\
     /|\
    __|_
    

    коли N = -3 дерево

      ^
     /|\
     /|\
     /|\
    __|_
    

    і так далі.

  • Коли ціле число 0, технічно немає дерева, просто порожній пробіл у чотири підкреслення:

    ____
    

Підкреслення в основі кожного дерева повинні вирівнюватися у висновку, тобто всі дерева повинні мати свої основи на одному рівні. Крім того, в кінці рядка підкреслення після останнього дерева додається єдине підкреслення. Це робить його таким, що кожне дерево має порожній стовпчик "повітря" по обидва боки від нього.

В якості прикладу, вихід для 4 0 -1 -6 2буде

              ^
             /|\
  ^          /|\
 / \         /|\
 / \         /|\  ^
 / \      ^  /|\ / \
 / \     /|\ /|\ / \
__|_______|___|___|__

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

Також:

  • Пробіли на будь-яких лініях є нормальними, але не повинно бути зайвих провідних пробілів.
  • Провідні нові рядки заборонені (найвище дерево повинно торкатися вершини вихідної текстової сітки), і допускається лише до одного зворотного нового рядка.
  • Список може містити будь-які цілі числа від -250 до 250 включно. Поводження з високими деревами не потрібно.

Виграє найкоротший код у байтах.

Більше прикладів

3:

  ^
 / \
 / \
 / \
__|__

-2:

  ^
 /|\
 /|\
__|__

0:

_____

0, 0:

_________

0, 1, 0:

      ^
     / \
______|______

0, -1, 2, -3, 4:

                  ^
              ^  / \
          ^  /|\ / \
      ^  / \ /|\ / \
     /|\ / \ /|\ / \
______|___|___|___|__

Відповіді:


6

Pyth, 48 байт

j_.t+sm.i,J\_?d++\|sm?>d0\ \|d\^Jms+Jmkd"/\\"QJd

Спробуйте в Інтернеті: Демонстрація або Тестовий набір

Занадто лінивий для повного пояснення. Ось лише короткий огляд:

Я генерую спочатку стовпці. Отже, зображення:

      ^ 
  ^  /|\
 / \ /|\
__|___|__

отримується як:

["_", "_/", "| ^", "_\", "_", "_//", "|||^", "_\\", "_"]

Зауважте, що я генерую лише нижню частину (все без пробілів). І я також генерую їх знизу вгору. Це робиться досить просто.

Тоді я можу використовувати .tметод для додавання пробілів до рядків, щоб кожна струна мала однакову довжину. А згодом я скасовую замовлення та друкую.


Як зауваження: Якщо це фактичний вихід, ви, можливо, забули додати трейлінг _(підкреслення) після останнього дерева.
вставитикористувач туди

1
@insertusernamehere Спасибі, повністю проігнорував трейлінг _.
Якубе

7

Python 2, 165 байт

a=input()
l=max(map(abs,a))
while l+2:s=' _'[l<0];print(s+s.join((([' ^ ','//| \\\\'[x>0::2],'   '][cmp(abs(x),l)],'_|_')[l<0],s*3)[x==0]for x in a)+s).rstrip();l-=1

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


4

PHP, 231 277 байт

Це завдання має прекрасний результат.

$x=fgetcsv(STDIN);for(;$i<2+max(array_map(abs,$x));$i++)for($j=0;$j<count($x);){$_=$x[$j++];$o[$i].=!$i?$_?'__|_':____:(abs($_)>=$i?0>$_?' /|\\':' / \\':($i-1&&abs($_)==$i-1?'  ^ ':'    '));}echo implode("
",array_reverse($o))."_";

Читає розділений комою список (пробіли не є обов’язковими) з STDIN:

$ php trees.php
> 1, 2, 0, -4, 6

Безумовно

$x=fgetcsv(STDIN);
for(;$i<2+max(array_map(abs,$x));$i++)
    for($j=0;$j<count($x);){
        $_=$x[$j++];
        $o[$i] .= !$i ? $_?'__|_':____
                      : (abs($_)>=$i ? 0>$_?' /|\\':' / \\'
                                     : ($i-1&&abs($_)==$i-1 ? '  ^ ' : '    '));
    }
echo implode("\n",array_reverse($o))."_";

Правки

  • Збережено 46 байт . Відхилено ініціалізацію масиву, замінено if/elseна потрійні оператори та перемістило деякі змінні навколо, щоб зберегти кілька байт.

2

Рубі, 157 156 153 символів

->h{r=[]
h.map{|i|j=i.abs
r+=[s=?_,?/*j+s,i==0?s:?^+(i>0?' ':?|)*j+?|,?\\*j+s].map{|l|l.rjust(h.map(&:abs).max+2).chars}}
r.transpose.map{|l|l*''}*$/+?_}

Написана лише тому, що спочатку Array.transposeвиглядала гарна ідея. Більше не.

Проба зразка:

2.1.5 :001 > puts ->h{r=[];h.map{|i|j=i.abs;r+=[s=?_,?/*j+s,i==0?s:?^+(i>0?' ':?|)*j+?|,?\\*j+s].map{|l|l.rjust(h.map(&:abs).max+2).chars}};r.transpose.map{|l|l*''}*$/+?_}[[4, 0, -1, -6, 2]]
              ^     
             /|\    
  ^          /|\    
 / \         /|\    
 / \         /|\  ^ 
 / \      ^  /|\ / \
 / \     /|\ /|\ / \
__|_______|___|___|__

Збір фрагментів в окремий масив замість повернення їх з першої карти повинен дозволяти уникати використання скорочення.
манастирство

0

C #, 318 байт

Я спробував перемістити масив. Я не впевнений, чи було це найкращим рішенням.

string F(int[]a){int i=a.Length,j,w=i*4+1,h=0;string f="",o=f;for(;i-->0;){j=a[i];f+=","+" _,".PadLeft(j=j>0?j+3:-j+3,'\\')+(j>3?"^"+"|_,".PadLeft(j,a[i]<0?'|':' '):"_,")+" _,_".PadLeft(j+1,'/');h=h<j?j:h;}f="_".PadLeft(h=h>3?h:2,'\n')+f;for(i+=h<3?1:0;++i<h;)for(j=w;j-->0;)o+=f.Split(',')[j].PadLeft(h)[i];return o;}

Відступ та нові рядки для наочності:

string F(int[]a)
{
    int i=a.Length,
        j,
        w=i*4+1,
        h=0;
    string f="",o=f;
    for(;i-->0;){
        j=a[i];
        f+=","+" _,".PadLeft(j=j>0?j+3:-j+3,'\\')+(j>3?"^"+"|_,".PadLeft(j,a[i]<0?'|':' '):"_,")+" _,_".PadLeft(j+1,'/');
        h=h<j?j:h;
    }
    f="_".PadLeft(h=h>3?h:2,'\n')+f;
    for(i+=h<3?1:0;++i<h;)
        for(j=w;j-->0;)
            o+=f.Split(',')[j].PadLeft(h)[i];
    return o;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.