Triángulos de hexágonos

20

Supongamos un mosaico infinito de hexágonos compuestos de |/\caracteres.

 / \ / \ / \ / \
|   |   |   |   |
 \ / \ / \ / \ /  etc.
  |   |   |   |
   \ / \ / \ /

Dada la entrada n > 0, emite una porción triangular de ese mosaico como se muestra en los ejemplos a continuación, anclado con un _en el medio de un hexágono:

n=1
\_/

n=2
\/ \/
 \_/

n=3
\  |  /
 \/ \/
  \_/

n=4
\/ \ / \/
 \  |  /
  \/ \/
   \_/

n=5
\  |   |  /
 \/ \ / \/
  \  |  /
   \/ \/
    \_/

n=6
\/ \ / \ / \/
 \  |   |  /
  \/ \ / \/
   \  |  /
    \/ \/
     \_/

n=7
\  |   |   |  /
 \/ \ / \ / \/
  \  |   |  /
   \/ \ / \/
    \  |  /
     \/ \/
      \_/

n=8
\/ \ / \ / \ / \/
 \  |   |   |  /
  \/ \ / \ / \/
   \  |   |  /
    \/ \ / \/
     \  |  /
      \/ \/
       \_/

and so on

Reglas

  • Las nuevas líneas iniciales / finales u otros espacios en blanco son opcionales, siempre que los caracteres se alineen adecuadamente.
  • Un programa completo o una función son aceptables. Si es una función, puede devolver el resultado en lugar de imprimirlo.
  • La salida puede ser a la consola, guardada como una imagen, devuelta como una lista de cadenas, etc.
  • 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
Si cuenta el número de puntos finales en la parte superior del resultado, obtendrá A029578 (los números naturales intercalados con los números pares) con un desplazamiento de 4. 2 , 4 , 3 , 6 , 4 , 8 , 5 , 10 , 6 , 12 , 7 , 14 , ...
Ingeniero Brindis
¿Qué significa "guardado como una imagen"? ¿está etiquetado ascii-art?
tsh
@tsh Para cosas como HyperCard o algo así, donde la salida a un lienzo es su equivalente a la salida "stdout". No soy exigente con la forma en que se muestra la salida.
AdmBorkBork

Respuestas:

8

Python 2 , 86 bytes

i=k=input()
while i:i-=1;print(" "*(k+~i)+"\\"+i*' /  |\  '[i%2::2])[:k-~i]+"_/"[i>0:]

Pruébalo en línea!

¡Uno de los trucos de Erik me permitió jugar 3 bytes! Guardado 3 bytes gracias a Jonathan Allan.

Como funciona esto

En primer lugar, esto obtiene información de STDIN y la asigna a dos variables separadas iy k. Luego, mientras la variable ies verdadera, la decrementamos y generamos las cadenas en consecuencia; Esta es una forma abreviada de bucle desde la entrada: 1 hasta 0.

Generando las cuerdas

Lo dividiré en más partes:

  • En primer lugar, se consigue el espacio inicial con " "*(k+~i). Dado que ise asigna a través del rango (entrada, 0] , debemos restarlo de k(nuestra entrada original almacenada de forma segura), disminuir y repetir un espacio tantas veces.

  • +"\\"- Agrega el personaje "\"a los espacios de arriba.

  • ' / |\ '[i%2::2]- Genera nuestras dos cadenas, a saber , "/ \ "y " | ", de la siguiente manera:

    • Si ies impar, i% 2 es 1 , por lo tanto, [i%2::2]devuelve cada 2 caracteres de nuestra cadena más grande, comenzando en el índice 1 (0 indexado).

    • Si ies par, i% 2 es 1 , por lo tanto, el mecanismo anterior hace lo mismo excepto que comienza en el índice 0 .

  • +~-i*- Repite la cadena generada arriba, ya sea "/ \ "o " | ", i-1 veces, y la agrega a las otras cadenas. El beneficio del operador bit a bit ( ~- Complemento a nivel de bit , equivalente a i restado de -1 ) es que no requiere paréntesis en este contexto.

  • [:k-~i]- Obtiene todos los caracteres de las cadenas concatenadas anteriormente hasta el índice k- ~ i = k - (-1 - i) = k + 1 + i .

  • +"_/"[i>0:]- Esto solo se agrega "/"si i ≥ 1 , de lo contrario, se agrega _/.

Ejemplo completo / detalles de ejecución

Tomemos un ejemplo de cómo funcionan las cosas para una entrada de 4 :

i=k=input()        # i and k are assigned to 4.
while i:           # Starts the loop. The initial value of i is 4.
i-=1;              # Decrement i. i is now 3.
" "*(k+~i)         # A space repeated k - 1 - i = 4 - 1 - 3 = 0 times.
+"\\"              # Plus the character "\". CS (Current string): "\".
' /  |\  '[i%2::2] # The string ' /  |\  '[3%2::2] = ' /  |\  '[1::2] = "/ \ ".
i*                 # ^ repeated i = 3 times: "/ \ / \ / \ ".
+                  # And concatenate. CS: "\/ \ / \ / \ "
[:k-~i]            # Get the characters of ^ up to index k + 1 + i = 4 + 1 + 3 = 8.
                   # CS: "\/ \ / \".
+"_/"[i>0:]        # Append "_/"[i>0:] = "_/"[3>0:] = "_/"[1:] = "/".
                   # CS: "\/ \ / \/".
print              # Output the result "\/ \ / \/".
while i:           # i is truthy (> 0), thus we loop again.
i-=1;              # Decrement i. i becomes 2.
" "*(k+~i)         # " " repeated 4 - 2 - 1 = 1 time. 
+"\\"              # Plus "\". CS: " \".
' /  |\  '[i%2::2] # ' /  |\  '[2%2::2] = ' /  |\  '[::2] = "  | ".
+i*                # Repeat i = 2 times and append: "  | ". CS: " \  |  |".
[:k-~i]            # CS up until k + 1 + i = 4 + 2 + 1 = 7. CS: " \  |  ".
+"_/"[i>0:]        # Append "/". CS: " \  |  /".
print              # Outputs the CS: " \  |  /".
while i:           # i is truthy (> 0), thus we loop again.
i-=1;              # Decrement i. i is now 1.
" "*(k+~i)         # " " repeated 4 - 1 - 1 = 2 times. 
+"\\"              # Plus "\". CS: "  \".
' /  |\  '[i%2::2] # ' /  |\  '[2%2::2] = ' /  |\  '[::2] = "/ \ ".
+i*                # Repeat i = 1 time and append: "/ \ ". CS: "  \/ \ ".
[:k-~i]            # CS up until k + i + 1 = 4 + 2 = 6. CS: "  \/ \".
+"_/"[i>0:]        # Append "/". CS: "  \/ \/".
print              # Outputs the CS: "  \/ \/".
while i:           # i is truthy (> 0), thus we loop again.
i-=1;              # Decrement i. i is now 0.
" "*(k+~i)         # " " repeated 4 - 1 - 0 = 3 times. 
+"\\"              # Plus "\". CS: "   \".
' /  |\  '[i%2::2] # ' /  |\  '[1%2::2] = ' /  |\  '[1::2] = "  | ".
+i*                # Repeat i = 0 times and append: "   \". CS: "   \".
[:k-~i]            # CS up until k + i + 1 = 4 + 0 + 1 = 5. CS: "   \".
+"_/"[i>0:]        # Append "_/" (because i > 0 is False since i == 0). CS: "  \_/".
print              # Outputs the CS: "  \_/".
while i:           # i == 0, hence the condition is falsy and the loop ends. 
                   # Program terminates.
Sr. Xcoder
fuente
Mueva el i-=1al inicio del bucle y use una formación del lado derecho ligeramente diferente para bajarlo a 87 bytes .
Jonathan Allan
... de hecho, incluso mejor a 86 bytes usando algo como su formación del lado derecho :)
Jonathan Allan
@JonathanAllan ... ¡Gracias! (¡Aunque rehacer la explicación será ... difícil! ... suspiro )
Sr. Xcoder
@ JonathanAllan Encontré una alternativa que no invierte el orden de la declaración de decremento.
Sr. Xcoder
2

05AB1E , 33 bytes

1ŸεÐi'_ë"/ \   | "4ôsès∍}'\ì.∞}.c

Pruébalo en línea!

Erik el Outgolfer
fuente
Pruébalo en línea! - Intenté explotar el patrón "0300" y "2010", no fue tan bueno.
Urna de pulpo mágico
@MagicOctopusUrn Eso tampoco imprime un guión bajo: p
Erik the Outgolfer
2

Mathematica, 131 bytes

Join[Table[s=StringRiffle@Table[If[OddQ@i,"/ \\"," | "],⌈i/2⌉];""<>{"\\",If[!OddQ@i,{" ",s," "},s],"/"},{i,#-1,1,-1}],{"\_/"}]&   


devuelve una lista de cadenas

Pruébalo en línea!

J42161217
fuente
2

Retina , 129 119 112 bytes

\d+
$* 
 
¶$`a $'$' 
m`$
/
  /$
_/
^.¶

a(    )*/
a$#1/
\d+
$*
1
/ a  
 (    )*/
$#1/
\d+
$*
1
 |  
a /¶
a/¶
a
\

Pruébalo en línea!

ovs
fuente
2

Python 2 , 123 112 110 109 100 98 96 bytes

i=n=input()
while i:a=i%2;print' '*(n-i)+'\%s/'%['_',((-~i/2)*'/   \  |'[a::2])[a:~a]][i>1];i-=1

Pruébalo en línea!

  • Ahorré un montón de bytes usando el formato de entrada y cadena como en la respuesta de Rod
  • Guardado 2 bytes gracias al Sr. Xcoder
TFeld
fuente
1
Puede guardar 2 bytes reemplazándolos -1-acon ~a(como hice en mi respuesta).
Sr. Xcoder
@ Mr.Xcoder Gracias :)
TFeld
1

APL (Dyalog) , 97 93 bytes

{⍵=1:1 3'\_/'x' ',' ',⍨∇⍵-1y1+2×⍵-12|⍵:x⍪⍨'\','/',⍨y⍴'  | '⋄x⍪⍨'\/','\/',⍨(y-2)⍴' \ /'}

Pruébalo en línea!

Uriel
fuente
1

Haskell , 96 95 bytes

f n=[([1..n-x]>>" ")++'\\':take(2*x+1)(cycle$("_":a)!!x)++"/"|x<-[n,n-1..0]]
a="/ \\ ":"  | ":a

Pruébalo en línea!

0 indexado y devuelve una lista de líneas.

Laikoni
fuente
0

Haskell, 101 99 bytes

j 1=["\\_/"]
j n|r<-([1,3..n-1]>>)=('\\':cycle[init$r"/ \\ ",' ':r" |  "]!!n++"/"):map(' ':)(j$n-1)

Devuelve una lista de líneas.

Pruébalo en línea!

Cómo funciona:

j 1=["\\_/"]               -- base case, n=1

j n                        -- for all other n
   |r<-([1,3..n-1]>>)      -- let r be the function that makes n/2 copies of
                           -- it's argument
   =                       -- the result is
      '\\':                --  a backslash, followed by
      cycle[  ]!!n         --  the inner part, which is
          init$r"/ \\ "    --    all but the last char of some copies of
                           --    "/ \ " for even line numbers, or
          ' ':r" |  "      --    some copies of " |  " prepended by a space
                           --    for odd line numbers
                           --    (chosen by indexing an infinite list of
                           --     both values alternating)   
      ++"/"                --  followed by a slash
    :                      --  and append a
               j$n-1        --  recursive call with n-1
      map(' ':)            --  where each line is prepended by a space

Editar: @Laikoni guardó dos bytes. ¡Gracias!

nimi
fuente
([1,3..n-1]>>)se puede usar en lugar de ([1..div n 2]>>).
Laikoni
0

Java (OpenJDK 8) , 315 306 bytes

i->{String r="";int j=0,k,u=i*2;char[][]c=new char[i][u+1];c[i-1][i]=95;for(;j<i;r+="".valueOf(c[j++]).replace('\0',' ')+"\n")for(k=0;k<u+1;k++){if(k==j)c[j][k]=92;if(k==u-j)c[j][k]=47;if(k>j&k<u-j)if((i-j)%2<1)c[j][k]=(k-j-1)%2<1?(char)(47+((k-j-1)/2)%2*45):32;else if((k-j-1)%4==2)c[j][k]='|';}return r;}

Pruébalo en línea!

Roberto Graham
fuente
0

Java (OpenJDK 8) , 198 bytes

Finalmente lo conseguí por debajo de 200 bytes. Probablemente publicará una explicación más tarde.

i->{for(int k=i+1;i>0;System.out.println(("".format("%"+(k-i)+"s","")+"\\"+(i<2?"":"".format("%"+(i-1)+"s","")).replace(" ","/ \\ ,  | ".split(",")[i%2])).substring(0,i<2?k:k+i)+(--i<1?"_/":"/")));}

Pruébalo en línea!

Luke Stevens
fuente
0

JavaScript (ES6), 89 85 bytes

f=(y,s='\\')=>--y?s+(y&1?' / \\':' |  ').repeat(y).slice(~y-y)+`/
`+f(y,' '+s):s+'_/'

Manifestación

Arnauld
fuente
0

PHP, 89 + 1 bytes

while($k=$argn-$n)echo($p=str_pad)("",$n++),$p("\\",2*$k,$k>1?$k&1?"  | ":"/ \ ":_),"/
";

Ejecutar como tubería -nRo probarlo en línea .

Titus
fuente