Не вижу леса за деревьями


29

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

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

Это лес размером 1

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

Это лес размером 2

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

Это лес размером 3

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

Это лес размером 4

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

Это лес размером 5(обратите внимание, что верхушка пятого дерева покрывает ствол первого дерева)

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

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

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

и так далее.

вход

Один положительное целое число в любом удобном формате , n > 0.

Выход

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

правила

  • Допустимы либо полная программа, либо функция. Если функция, вы можете вернуть вывод, а не распечатать его.
  • Стандартные лазейки запрещены.
  • Это поэтому применяются все обычные правила игры в гольф, и выигрывает самый короткий код (в байтах).

Я не уверен, что образец относительно порядка, в котором нарисованы деревья. То есть, учитывая n, каковы положения деревьев?
Луис Мендо

@ LuisMendo Как я понимаю, они заполнены в порядке чтения. Таким образом, каждая строка заполняется по очереди, и если для всей строки не хватает деревьев, остальные располагаются как можно левее в этой строке.
xnor

@ LuisMendo xnor это правильно. Если я могу перефразировать это, чтобы сделать это более ясным, пожалуйста, пингуйте меня в чате.
AdmBorkBork

@xnor Спасибо, теперь мне все ясно
Луис Мендо

@ Adm На самом деле это было написано прямо в вызове. Видимо, я не могу читать :-)
Луис Мендо

Ответы:


5

Haskell 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 Это 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.