Не видно лісу за деревами


29

Напишіть програму або функцію, яка малює дерево дерев, будуючи таким чином ліс.

Дерева намальовані як укладання піраміди. Перший (верхній) рядок містить 1дерево, наступний рядок вниз містить 2(для загальної кількості 3), наступний містить 3(для загальної кількості 6) тощо. Якщо дерев не вистачає, щоб заповнити повний ряд, заповніть його зліва і залиште плями праворуч порожніми. Крім того, дерева нижнього рівня дещо перекривають дерева верхнього рівня завдяки їх розміщенню.

Це ліс розміром 1

  /\
 //\\
///\\\
  ||
  ||

Це ліс розміром 2

      /\
     //\\
  /\///\\\
 //\\ ||
///\\\||
  ||
  ||

Це ліс розміром 3

      /\
     //\\
  /\///\\\/\
 //\\ || //\\
///\\\||///\\\
  ||      ||
  ||      ||

Це ліс розміром 4

          /\
         //\\
      /\///\\\/\
     //\\ || //\\
  /\///\\\||///\\\
 //\\ ||      ||
///\\\||      ||
  ||
  ||

Це ліс розміром 5(зверніть увагу, що верхівка п’ятого дерева покриває стовбур першого дерева)

          /\
         //\\
      /\///\\\/\
     //\\ || //\\
  /\///\\\/\///\\\
 //\\ || //\\ ||
///\\\||///\\\||
  ||      ||
  ||      ||

(пропустити декілька)
Це ліс розміром 8(розширення шаблону)

              /\
             //\\
          /\///\\\/\
         //\\ || //\\
      /\///\\\/\///\\\/\
     //\\ || //\\ || //\\
  /\///\\\/\///\\\||///\\\
 //\\ || //\\ ||      ||
///\\\||///\\\||      ||
  ||      ||
  ||      ||

і так далі.

Вхідні дані

Один натуральне число в будь-якому зручному форматі , n > 0.

Вихід

ASCII-мистецтво представлення лісу, дотримуючись вищезазначених правил. Провідні / кінцеві нові рядки або інші пробіли необов’язкові, за умови, що дерева всі розташовуються належним чином.

Правила

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

Я не впевнений, яка картина стосується порядку, в якому намальовані дерева. Тобто, враховуючи n, які положення дерев?
Луїс Мендо

@LuisMendo Як я розумію, вони заповнюються в порядку читання. Отже, кожен рядок заповнюється по черзі, і якщо не вистачає дерев на весь ряд, решту розміщують якомога лівіше в цьому ряду.
xnor

@LuisMendo xnor має це право. Якщо я можу це повторити, щоб зробити це більш зрозумілим, будь ласка, напишіть мені в чаті.
AdmBorkBork

@xnor Спасибі, зараз мені цілком зрозуміло
Луїс Мендо

@Adm Насправді це було написано прямо у виклику. Мабуть, я не можу читати :-)
Луїс Мендо

Відповіді:


5

Хаскелл 310 байт

w i=putStr$unlines$reverse$b i 0 0[][]
b 0 _ _ w r=e w r
b c l 0 w r=b c(l+1)l(e w r)[]
b c l p w r=b(c-1)l(p-1)w(n(++)["  ||    ","  ||    ","///\\\\\\  "," //\\\\   ","  /\\    "]r)
e w r=t++n(n d)(map(\t->"    "++t)w)c where(t,c)=splitAt 2 r
n f(a:c)(b:d)=f a b:n f c d
n _ a[]=a
n _ _ a=a
d d ' '=d
d _ d=d

w 5Наприклад, подзвоніть це .

Тут нестиснений код:

-- TreeTree
-- by Gerhard
-- 12 February 2017

module TreeTree (wood,test) where

type Tree = [String]

-- Test cases
test = do
 wood 0
 wood 1
 wood 2
 wood 3
 wood 4
 wood 5

-- build wood
wood :: Int -> IO ()
wood i = printTree $ buildWood i 0 0 [] []

-- Prints the trees
printTree :: Tree -> IO ()
printTree = putStr . unlines . reverse

-- build wood
buildWood :: Int -> Int -> Int -> Tree -> Tree -> Tree
buildWood 0 _ _ w r = concatTree w r 
buildWood c l 0 w r = buildWood c (l+1) l (concatTree w r) []
buildWood c l p w r = buildWood (c-1) l (p-1) w (addTree r)

-- indent definition
space :: String
space = "    "

-- tree definition
tree :: Tree
tree = reverse [
 "  /\\    ",
 " //\\\\   ",
 "///\\\\\\  ",
 "  ||    ",
 "  ||    "]

-- Add a Tree on the left side
addTree :: Tree -> Tree
addTree = match (++) tree

-- add tree row at the bottom of the wood
concatTree :: Tree -> Tree -> Tree
concatTree w r = trunk ++ matched
 where
  wood = grow w
  (trunk, crown) = splitAt 2 r 
  matched = matchTree wood crown

-- elnarge forrest on the left side to match next tree line
grow :: Tree -> Tree
grow = map (\t -> space ++ t)

-- match
match :: (a -> a -> a) -> [a] -> [a] -> [a]
match f (a:az) (b:bz) = f a b : match f az bz
match _ a [] = a
match _ _ a  = a

-- match trees
matchTree :: Tree -> Tree -> Tree
matchTree = match matchLine

-- match lines
matchLine :: String -> String -> String
matchLine = match matchChar

-- match chars
matchChar :: Char -> Char -> Char
matchChar c ' ' = c
matchChar _ c   = c

-- End

Ласкаво просимо до PPCG!
AdmBorkBork

4

JavaScript (ES6), 357 297 276 байт

f=
n=>{a=`  /\\`;d=`///\\\\\\`;b=d+`/\\`;c=` //\\\\ ||`;d+=`||`;e=`
`;r=`repeat`;s=``;for(i=1;n>i;n-=i++)s=(s+a+b[r](i-1)+e+c[r](i)).replace(/^/gm,`    `)+e;return(s+a+b[r](n-1)+d[r](i-=n)+e+c[r](n)+(s=`      ||`[r](i))+e+d[r](n)+s+(s=e+`  ||    `[r](n))+s).replace(/\|.$/gm,``)}
<input type=number min=1 oninput=o.textContent=f(this.value)><pre id=o>

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


По-перше repeat, ви можете змінити blah.repeat(val)на blah[w="repeat"](val), а потім можете змінити наступні випадки, repeatщоб просто [w](val)замість них зберегти байти
Kritixi Lithos,

@KritixiLithos Я не можу цього зробити, тому що перший repeatзнаходиться в forциклі і не працюватиме n=1, але мені все ж вдалося зберегти 21 байт.
Ніл

4

C ++ (у Windows), 330 312 308 304 303 байт

#import<cstdio>
#import<windows.h>
#define P(x,y,s)SetConsoleCursorPosition(GetStdHandle(-11),{X+x,Y+y});puts(s);
int X,Y,R,r,c;t(){P(2,-2,"/\\")P(1,-1,"//\\\\")P(0,0,"///\\\\\\")P(2,1,"||")P(2,2,"||")}f(int n){for(c=R=r=1;c<n;c+=++R);for(;r;r++)for(c=0;++c<r+1;){X=(R-r-2)*4+c*8;Y=r*2;t();r=--n?r:-1;}}

Телефонуйте за допомогою:

int main()
{
    f(8);
}

0

C (у Windows), 297 295 294 байт

#import<windows.h>
#define P(x,y,s)C.X=X+x;C.Y=Y+y;SetConsoleCursorPosition(GetStdHandle(-11),C);puts(s);
COORD C;X,Y,R,r,c;t(){P(2,-2,"/\\")P(1,-1,"//\\\\")P(0,0,"///\\\\\\")P(2,1,"||")P(2,2,"||")}f(n){for(c=R=r=1;c<n;c+=++R);for(;r;r++)for(c=0;++c<r+1;){X=(R-r-2)*4+c*8;Y=r*2;t(r=--n?r:-1);}}

Аналогічно моїй відповіді на C ++, але я розмістив це, оскільки це дещо коротше у C.


@DLosc It C. #importє (застарілим) розширенням GCC. Хоча підходить для гольфу.
Steadybox

Так, цікаво. Тепер я бачу, що для цього є порада . Ви можете згадати це у своїй відповіді.
DLosc

@DLosc Можливо, але я думаю, що це досить широко використовується в гольфі, поряд з деякими іншими розширеннями GCC (хоча вони не обмежуються лише GCC), такими як опущення <stdio.h>та автоматичне прийняття глобальної змінної intабо функція для повернення int.
Steadybox

0

Javascript 418 377 байт

Завдяки @Kritixi Lithos за те, що він допомагає гольфу на 39 байтах

x=>{s='';for(t=0;++t<x;x-=t);q='//\\\\';z="///\\\\\\";h="/\\";t--;for(i=0;i<t;i++){a=4*(t-i)+1;s+=" "[w="repeat"](a+1)+h+(z+h)[w](i)+`
`+" "[w](a)+q+(" || "+q)[w](i)+`
`}c=t-x+1>0?t-x+1:0;return x?s+"  "+(h+z)[w](--x)+h+(c?(z+"||")[w](c-1)+z:'')+`
 `+q+(" || "+q)[w](x)+" ||     "[w](c)+`
`+(z+"||")[w](x)+z+(c?"||"+"      ||"[w](c-1):'')+`
`+("  ||    "[w](x+1)+`
`)[w](2):''}

Спробуйте в Інтернеті


2
По-перше repeat, ви можете перейти blah.repeat(val)на blah[w="repeat"](val)наступні випадки, repeatщоб просто [w](val)замість них зберегти байти
Kritixi Lithos
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.