No puedo ver el bosque por los árboles.

29

Escriba un programa o función que dibuje un árbol de árboles, construyendo así un bosque.

Los árboles se dibujan como apilar una pirámide. La primera fila (superior) contiene 1árbol, la siguiente fila abajo contiene 2(para un total de 3), la siguiente contiene 3(para un total de 6), y así sucesivamente. Si no hay suficientes árboles para completar una fila completa, llénela a la izquierda y deje vacíos los puntos a la derecha. Además, los árboles de nivel inferior se superponen ligeramente a los árboles de nivel superior debido a su ubicación.

Este es un bosque de tamaño 1

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

Este es un bosque de tamaño 2

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

Este es un bosque de tamaño 3

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

Este es un bosque de tamaño 4

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

Este es un bosque de tamaño 5(tenga en cuenta que la parte superior del quinto árbol está cubriendo el tronco del primer árbol)

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

(omita algunos)
Este es un bosque de tamaño 8(que extiende el patrón)

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

y así.

Entrada

Un número entero positivo solo en cualquier formato conveniente , n > 0.

Salida

Una representación de arte ASCII del bosque, siguiendo las reglas anteriores. Las nuevas líneas iniciales / finales u otros espacios en blanco son opcionales, siempre que los árboles se alineen correctamente.

Reglas

  • Un programa completo o una función son aceptables. Si es una función, puede devolver el resultado en lugar de imprimirlo.
  • Las lagunas estándar están prohibidas.
  • Este es el por lo que se aplican todas las reglas habituales de golf, y gana el código más corto (en bytes).
AdmBorkBork
fuente
No estoy seguro de cuál es el patrón con respecto al orden en que se dibujan los árboles. Es decir, n¿cuáles son las posiciones de los árboles?
Luis Mendo
@LuisMendo Según tengo entendido, se completan en orden de lectura. Entonces, cada fila se llena a su vez, y si no hay suficientes árboles para toda la fila, el resto se coloca lo más a la izquierda posible en esa fila.
xnor
@LuisMendo xnor tiene razón. Si puedo volver a redactar eso para que quede más claro, hágame ping en el chat.
AdmBorkBork
@xnor Gracias, para mí es totalmente claro ahora
Luis Mendo
@Adm En realidad, fue escrito allí mismo en el desafío. Aparentemente no puedo leer :-)
Luis Mendo

Respuestas:

5

Haskell 310 bytes

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

Llámalo con w 5, por ejemplo.

Aquí el código sin comprimir:

-- 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
fuente
Bienvenido a PPCG!
AdmBorkBork
4

JavaScript (ES6), 357 297 276 bytes

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>

Editar: guardado 21 bytes gracias a @KritixiLithos.

Neil
fuente
Para el primero repeat, puede cambiar blah.repeat(val)a blah[w="repeat"](val) y luego puede cambiar las ocurrencias posteriores de repeata solo [w](val)para guardar bytes
Kritixi Lithos
@KritixiLithos No puedo hacer eso porque el primero repeatestá dentro del forbucle y no se ejecutará n=1, pero aún así pude guardar 21 bytes.
Neil
4

C ++ (en Windows), 330 312 308 304 303 bytes

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

Llamar con:

int main()
{
    f(8);
}
Steadybox
fuente
0

C (en Windows), 297 295 294 bytes

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

Similar a mi respuesta de C ++, pero publiqué esto porque es algo más corto en C.

Steadybox
fuente
@DLosc It's C. #importes una extensión (obsoleta) de GCC. Apto para jugar al golf, sin embargo.
Steadybox
Huh, interesante Ahora veo que hay un consejo para eso. Puede mencionar eso en su respuesta.
DLosc
@DLosc Quizás, pero creo que es bastante ampliamente utilizado en el golf, junto con algunas otras extensiones de GCC (aunque no se limitan a GCC) como omitir <stdio.h>y asumir automáticamente que una variable global sea into una función que regrese int.
Steadybox
0

Javascript 418 377 bytes

Gracias a @Kritixi Lithos por ayudar al golf con 39 bytes

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

Pruébalo en línea

fəˈnɛtɪk
fuente
2
Para el primero repeat, puede cambiar blah.repeat(val)a blah[w="repeat"](val)y luego puede cambiar las ocurrencias posteriores de repeata solo [w](val)para guardar bytes
Kritixi Lithos