Non riesco a vedere la foresta per gli alberi


29

Scrivi un programma o una funzione che disegna un albero di alberi, costruendo così una foresta.

Gli alberi sono disegnati come impilare una piramide. La prima riga (in alto) contiene un 1albero, la riga successiva in basso contiene 2(per un totale di 3), la successiva contiene 3(per un totale di 6) e così via. Se non ci sono abbastanza alberi per completare una fila intera, riempila a sinistra e lascia vuoti i punti a destra. Inoltre, gli alberi di livello inferiore si sovrappongono leggermente agli alberi di livello superiore a causa del loro posizionamento.

Questa è una foresta di dimensioni 1

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

Questa è una foresta di dimensioni 2

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

Questa è una foresta di dimensioni 3

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

Questa è una foresta di dimensioni 4

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

Questa è una foresta di dimensioni 5(nota che la parte superiore del quinto albero copre il tronco del primo albero)

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

(salta alcuni)
Questa è una foresta di dimensioni 8(che estende il modello)

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

e così via.

Ingresso

Un unico intero positivo in qualsiasi formato conveniente , n > 0.

Produzione

Una rappresentazione in arte ASCII della foresta, seguendo le regole precedenti. Le linee guida iniziali / finali o altri spazi bianchi sono opzionali, a condizione che tutti gli alberi siano allineati in modo appropriato.

Regole

  • È accettabile un programma completo o una funzione. Se una funzione, è possibile restituire l'output anziché stamparlo.
  • Sono vietate le scappatoie standard .
  • Si tratta di quindi si applicano tutte le normali regole del golf e vince il codice più breve (in byte).

Non sono sicuro di quale sia lo schema relativo all'ordine in cui gli alberi vengono disegnati. Cioè, dato n, quali sono le posizioni degli alberi?
Luis Mendo,

@LuisMendo Come ho capito, sono riempiti in ordine di lettura. Quindi, ogni riga viene riempita a turno, e se non ci sono abbastanza alberi per l'intera riga, il resto viene posizionato il più a sinistra possibile in quella riga.
xnor

@LuisMendo xnor ha ragione. Se riesco a riformularlo per renderlo più chiaro, per favore chiamami in chat.
AdmBorkBork,

@xnor Grazie, mi è del tutto chiaro ora
Luis Mendo il

@Adm In realtà è stato scritto proprio lì nella sfida. Apparentemente non riesco a leggere :-)
Luis Mendo il

Risposte:


5

Haskell 310 byte

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

Chiamalo con w 5, per esempio.

Ecco il codice non compresso:

-- 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

Benvenuti in PPCG!
AdmBorkBork,

4

JavaScript (ES6), 357 297 276 byte

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>

Modifica: salvato 21 byte grazie a @KritixiLithos.


Per la prima repeat, puoi cambiare blah.repeat(val)in blah[w="repeat"](val) e poi puoi cambiare le occorrenze successive di repeatin [w](val)invece di salvare byte
Kritixi Lithos,

@KritixiLithos Non riesco proprio a farlo perché il primo repeatè all'interno del forciclo e non funzionerà n=1, ma sono stato comunque in grado di salvare 21 byte.
Neil,

4

C ++ (su Windows), 330 312 308 304 303 byte

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

Chiama con:

int main()
{
    f(8);
}

0

C (su Windows), 297 295 294 byte

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

Simile alla mia risposta in C ++, ma l'ho pubblicato perché è leggermente più breve in C.


@DLosc It's C. #importè un'estensione GCC (obsoleta). Adatta per il golf, però.
Steadybox,

Eh, interessante. Ora vedo che c'è un suggerimento per quello. Potresti menzionarlo nella tua risposta.
DLosc,

@DLosc Forse, ma penso che sia abbastanza ampiamente usato nel golf, insieme ad altre estensioni GCC (anche se non limitate a GCC) come omettere <stdio.h>e assumere automaticamente una variabile globale come into una funzione da restituire int.
Steadybox,

0

Javascript 418 377 byte

Grazie a @Kritixi Lithos per l'aiuto nel golf con 39 byte

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

Provalo online


2
Per il primo repeat, puoi cambiareblah.repeat(val) a blah[w="repeat"](val)e quindi è possibile modificare le occorrenze successive di repeatsolo [w](val)invece di salvare byte
Kritixi Lithos
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.