Triângulos de hexágonos

20

Suponha um mosaico infinito de hexágonos compostos por |/\caracteres.

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

Dada a entrada n > 0, produza uma parte triangular desse lado a lado, conforme ilustrado nos exemplos abaixo, ancorada com a _no meio de um hexágono:

n=1
\_/

n=2
\/ \/
 \_/

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

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

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

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

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

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

and so on

Regras

  • Novas linhas à esquerda / à direita ou outro espaço em branco são opcionais, desde que os caracteres sejam alinhados adequadamente.
  • Um programa completo ou uma função são aceitáveis. Se uma função, você pode retornar a saída em vez de imprimi-la.
  • A saída pode ser no console, salva como uma imagem, retornada como uma lista de strings, etc.
  • As brechas padrão são proibidas.
  • Isso é portanto todas as regras usuais de golfe se aplicam e o código mais curto (em bytes) vence.
AdmBorkBork
fonte
Se você contar o número de pontos finais na parte superior do resultado, obterá A029578 (os números naturais intercalados com os números pares) com um deslocamento de 4. 2 , 4 , 3 , 6 , 4 , 8 , 5 , 10 , 6 , 12 , 7 , 14 , ...
Engineer Toast
O que significa "salvo como imagem"? está etiquetado como ascii-art?
tsh
@tsh Para coisas como HyperCard ou algo assim, onde a saída para uma tela é equivalente à saída "stdout". Não sou exigente em como a saída é exibida.
AdmBorkBork

Respostas:

8

Python 2 , 86 bytes

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

Experimente online!

Um dos truques de Erik me permitiu jogar 3 bytes! Economizou 3 bytes graças a Jonathan Allan.

Como isso funciona

Primeiro, isso obtém a entrada do STDIN e a atribui a duas variáveis ​​separadas ie k. Então, enquanto a variável ié verdadeira, nós a diminuímos e geramos as seqüências de acordo; este é um atalho para fazer um loop da entrada - 1 até 0.

Gerando as cordas

Vou dividir isso em mais partes:

  • Primeiro, obter o espaçamento inicial é obtido com " "*(k+~i). Como ié mapeado através do intervalo (entrada 0) , devemos subtraí-lo de k(nossa entrada original armazenada com segurança), diminuir e repetir um espaço tantas vezes.

  • +"\\"- Adiciona o caractere "\"aos espaços acima.

  • ' / |\ '[i%2::2]- Gera nossas duas strings, a saber , "/ \ "e " | "da seguinte maneira:

    • Se ifor ímpar, i% 2 é 1 , portanto, [i%2::2]retorna cada 2 caracteres de nossa cadeia maior, começando no índice 1 (indexado 0).

    • Se ifor par, i% 2 é 1 , portanto, o mecanismo acima faz o mesmo, exceto que inicia no índice 0 .

  • +~-i*- Repete-se a sequência gerada acima, seja "/ \ "ou " | ", I-1 vezes, e acrescenta-lo a outras cadeias. O benefício do operador bit a bit ( ~- Bitwise Complement, equivalente a i subtraído de -1 ) é que ele não requer parênteses nesse contexto.

  • [:k-~i]- Obtém todos os caracteres das seqüências de caracteres concatenadas acima até o índice k- ~ i = k - (-1 - i) = k + 1 + i .

  • +"_/"[i>0:]- Isso adiciona apenas "/"se i ≥ 1 , caso contrário ele é anexado _/.

Exemplo completo / detalhes de execução

Vamos pegar um exemplo de como as coisas funcionam para uma entrada 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.
Mr. Xcoder
fonte
Mova i-=1para o início do loop e use uma formação do lado direito ligeiramente diferente para reduzi-lo a 87 bytes .
Jonathan Allan
... na verdade ainda melhor em 86 bytes usando algo como a sua formação-lado direito :)
Jonathan Allan
@JonathanAllan ... Thanks! (! Embora refazer a explicação vai ser ... difícil ... suspiro )
Mr. Xcoder
@ JonathanAllan Encontrei uma alternativa que não inverte a ordem da declaração de decremento.
Sr. Xcoder 30/10
4

Python 2 , 90 bytes

n=N=input()
while N:print' '*(n-N)+'\\'+(('/   \|  '[N%2::2]*n)[:N*2-1],'_')[N<2]+'/';N-=1

Experimente online!

Erik, o Outgolfer
fonte
2

05AB1E , 33 bytes

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

Experimente online!

Erik, o Outgolfer
fonte
Experimente online! - Tentei explorar o padrão "0300" e "2010", não ficou tão quente.
Magic Octopus Urn
@MagicOctopusUrn Isso também não imprime um sublinhado: 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}],{"\_/"}]&   


retorna uma lista de strings

Experimente online!

J42161217
fonte
2

Retina , 129 119 112 bytes

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

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

Experimente online!

ovs
fonte
2

Carvão , 26 bytes

NθG↖→↓θ“ ″✂=AL«Q"η\`”←_↖θ‖B

Experimente online! Link é a versão detalhada do código.

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

Experimente online!

  • Economizou um monte de bytes usando a formatação de entrada e string, como na resposta de Rod
  • Economizou 2 bytes graças ao Sr. Xcoder
TFeld
fonte
1
Você pode salvar 2 bytes substituindo -1-apor ~a(como fiz na minha resposta).
Xcoder 30/10/19
@ Mr.Xcoder Obrigado :) #
TFeld 30/10
1

Python 2 , 103 bytes

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

Experimente online!

Cajado
fonte
1

APL (Dyalog) , 97 93 bytes

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

Experimente online!

Uriel
fonte
1

Haskell , 96 95 bytes

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

Experimente online!

Indexado em 0 e retorna uma lista de linhas.

Laikoni
fonte
0

Haskell, 101 99 bytes

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

Retorna uma lista de linhas.

Experimente online!

Como 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

Edit: @Laikoni salvou dois bytes. Obrigado!

nimi
fonte
([1,3..n-1]>>)pode ser usado em vez de ([1..div n 2]>>).
Laikoni 30/10
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;}

Experimente online!

Roberto Graham
fonte
0

Java (OpenJDK 8) , 198 bytes

Finalmente consegui abaixo de 200 bytes. Provavelmente postará uma explicação mais 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?"_/":"/")));}

Experimente online!

Luke Stevens
fonte
0

JavaScript (ES6), 89 85 bytes

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

Demo

Arnauld
fonte
0

CJam, 43

ri_{S*'\@(:X"  | / \ "4/=X*X2*)<'_e|'/NX}/;

Experimente online

aditsu
fonte
0

PHP, 89 + 1 bytes

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

Execute como pipe -nRou experimente online .

Titus
fonte
0

Pitão ,  46  44 bytes

j_m+<++*;t-Qd\\*d%2>" /  |\  "%d2h+Qd>"_/"._

Experimente aqui!

Mr. Xcoder
fonte