Je ne vois pas la forêt pour les arbres

29

Écrivez un programme ou une fonction qui dessine un arbre d'arbres, construisant ainsi une forêt.

Les arbres sont dessinés comme empilant une pyramide. La première ligne (en haut) contient l' 1arborescence, la ligne suivante vers le bas contient 2(pour un total de 3), la suivante contient 3(pour un total de 6), etc. S'il n'y a pas assez d'arbres pour terminer une rangée complète, remplissez-la vers la gauche et laissez les emplacements à droite vides. De plus, les arbres de niveau inférieur chevauchent légèrement les arbres de niveau supérieur en raison de leur emplacement.

Ceci est une forêt de taille 1

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

Ceci est une forêt de taille 2

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

Ceci est une forêt de taille 3

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

Ceci est une forêt de taille 4

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

Ceci est une forêt de taille 5(notez que le sommet du cinquième arbre recouvre le tronc du premier arbre)

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

(sauter quelques-uns)
Ceci est une forêt de taille 8(étendant le motif)

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

etc.

Contribution

Un entier positif unique dans un format pratique , n > 0.

Sortie

Une représentation ASCII de la forêt, en suivant les règles ci-dessus. Les sauts de ligne de début / fin ou d'autres espaces sont facultatifs, à condition que tous les arbres s'alignent correctement.

Règles

  • Un programme complet ou une fonction sont acceptables. S'il s'agit d'une fonction, vous pouvez renvoyer la sortie plutôt que de l'imprimer.
  • Les failles standard sont interdites.
  • Il s'agit de donc toutes les règles de golf habituelles s'appliquent et le code le plus court (en octets) l'emporte.
AdmBorkBork
la source
Je ne sais pas quel est le motif concernant l'ordre dans lequel les arbres sont dessinés. Autrement dit, étant donné n, quelles sont les positions des arbres?
Luis Mendo
@LuisMendo Si je comprends bien, ils sont remplis dans l'ordre de lecture. Ainsi, chaque ligne est remplie à son tour, et s'il n'y a pas assez d'arbres pour toute la ligne, les autres sont placés le plus à gauche possible dans cette ligne.
xnor
@LuisMendo xnor a raison. Si je peux reformuler cela pour le rendre plus clair, veuillez me cingler dans le chat.
AdmBorkBork
@xnor Merci, c'est totalement clair pour moi maintenant
Luis Mendo
@Adm En fait, il a été écrit juste là dans le défi. Apparemment, je ne peux pas lire :-)
Luis Mendo

Réponses:

5

Haskell 310 octets

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

Appelez-le avec w 5, par exemple.

Voici le code non compressé:

-- 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
Gerhard
la source
Bienvenue chez PPCG!
AdmBorkBork
4

JavaScript (ES6), 357 297 276 octets

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>

Edit: sauvé 21 octets grâce à @KritixiLithos.

Neil
la source
Pour le premier repeat, vous pouvez passer blah.repeat(val)à blah[w="repeat"](val), puis vous pouvez modifier les occurrences suivantes de repeatjuste [w](val)pour enregistrer des octets
Kritixi Lithos
@KritixiLithos Je ne peux pas faire ça parce que le premier repeatest dans la forboucle et ne fonctionnera pas n=1, mais j'ai quand même pu économiser 21 octets.
Neil
4

C ++ (sous Windows), 330 312 308 304 303 octets

#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;}}

Appeler avec:

int main()
{
    f(8);
}
Steadybox
la source
0

C (sous Windows), 297 295 294 octets

#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);}}

Semblable à ma réponse C ++, mais j'ai posté cela parce qu'il est un peu plus court en C.

Steadybox
la source
@DLosc It's C. #importest une extension (obsolète) de GCC. Idéal pour le golf, cependant.
Steadybox
Huh, intéressant. Maintenant, je vois qu'il y a une astuce pour cela. Vous pourriez mentionner cela dans votre réponse.
DLosc
@DLosc Peut-être, mais je pense qu'il est assez largement utilisé dans le golf, avec quelques autres extensions GCC (mais non limitées à GCC) comme omettre <stdio.h>et supposer automatiquement une variable globale à être intou une fonction à retourner int.
Steadybox
0

Javascript 418 377 octets

Merci à @Kritixi Lithos d'avoir aidé le golf sur 39 octets

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):''}

Essayez-le en ligne

fəˈnɛtɪk
la source
2
Pour le premier repeat, vous pouvez passer blah.repeat(val)à blah[w="repeat"](val)puis vous pouvez modifier les occurrences suivantes de repeatjuste [w](val)pour enregistrer des octets
Kritixi Lithos