Ondulação do triângulo ASCII

12

Ok, minha primeira pergunta de golfe. Por favor, seja gentil :) Eu sei que há muitos quebra-cabeças ASCII: P, mas aqui vamos nós.

A tarefa é simples, use sua linguagem de programação favorita para imprimir uma ondulação triangular. A entrada deve ser do tamanho da ondulação.

Cada triângulo é espaçado igualmente. Basicamente, você continua adicionando os triângulos até que não haja espaço suficiente para o menor triângulo.

Você tem espaços em branco em qualquer lugar que quiser, desde que as ondulações sejam iguais ao exemplo com o tamanho correto.

Exemplo

q)g 1
__
\/
q)g 2
____
\  /
 \/
q)g 3
______
\    /
 \  /
  \/
q)g 4
________
\  __  /
 \ \/ /
  \  /
   \/
q)g 5
__________
\  ____  /
 \ \  / /
  \ \/ /
   \  /
    \/
q)g 6
____________
\  ______  /
 \ \    / /
  \ \  / /
   \ \/ /
    \  /
     \/
q)g 7
______________
\  ________  /
 \ \  __  / /
  \ \ \/ / /
   \ \  / /
    \ \/ /
     \  /
      \/
q)g 8
________________
\  __________  /
 \ \  ____  / /
  \ \ \  / / /
   \ \ \/ / /
    \ \  / /
     \ \/ /
      \  /
       \/

Como sempre, o código mais curto vence :)

WooiKent Lee
fonte
2
Embora não seja uma duplicata exata dos hexágonos ASCII de desenho concêntrico , não tenho certeza de que isso acrescente muito sobre o outro.
Geobits
4
@Geobits IMO sua diferente o suficiente - a especificação de entrada é bastante diferente, o método de descobrir quantas formas para desenhar é diferente, e triângulos = hexágonos ;-)!
Trauma Digital
@WooiKent Agora estou duvidando se entendi a pergunta corretamente. O que é uma ondulação? É um conjunto concêntrico de triângulos ou outra coisa?
Digital Trauma
2
boa pergunta, mas é subespecificada. (1) Lendo o texto literalmente, quando a entrada é 1,2 ou 3, devemos sempre produzir três triângulos. (2) consideraria que cada conjunto de triângulos deveria ser concêntrico e (3) parece que eles também deveriam ter seus cantos inferiores na mesma linha. (4) A separação horizontal deve ter exatamente um espaço, como mostrado, ou são permitidas outras separações? (5) É permitido um espaço em branco desnecessário no (a, b, c, d) esquerdo, direito, acima, abaixo?
Level River St
Eu acho que é bastante claro, embora não explícito. Você sempre desenha um triângulo do tamanho especificado, com triângulos aninhados do tamanho n-3, n-6, n-9, etc.
Sparr

Respostas:

5

Pitão, 31 bytes

VhQ+J<t+++*Nd*N"\ "d*Q\_Q_XJ"\/

Demonstração.

Explicação:

VhQ+J<t+++*Nd*N"\ "d*Q\_Q_XJ"\/
                                   Implicit: Q = eval(input()), d = ' '
VhQ                                for N in range(Q + 1):
                                   Concatenate:
          *Nd                      N spaces
         +   *N"\ "                N of the string "\ "
        +          d               another space
       +            *Q\_           Q of the string "_"
                                   If N = 2 and Q = 7, the string so far is:
                                   "  \ \  _______" and we want
                                   " \ \  _" as the left half.
      t                            Remove the first character.
     <                  Q          Take the first Q characters remaining.
                                   This is the left half of the triangle ripple.
    J                              Store it in J.
                          XJ"\/    Translate \ to / in J.
                         _         Reverse it.
   +                               Concatenate the left and right halves and print.
isaacg
fonte
7

GNU sed -nr, 210

Um começo:

s/1/__/g
p
s#_(.*)_#\\\1/#
s#\\__#\\  #
s#__/#  /#
ta
:a
p
s#(.*) _{6}(_*) # \1\\  \2  /#;ta
s#(.*)  (  )# \1\2#;
s#(.*) _(_*)_ # \1\\\2/#
y/_/ /
Tc
:b
p
:c
s#(.*)((\\)  ( *)(/)|()()()\\/)# \1\3\4\5#;tb

A entrada é um número inteiro unário positivo via STDIN, conforme esta meta-pergunta .

Resultado:

$ for i in 1 11 111 1111 11111 111111 1111111; do sed -rnf triripple.sed <<< $i; done
__
\/

____
\  /
 \/

______
\    /
 \  /
  \/

________
\  __  /
 \ \/ /
  \  /
   \/

__________
\  ____  /
 \ \  / /
  \ \/ /
   \  /
    \/

____________
\  ______  /
 \ \    / /
  \ \  / /
   \ \/ /
    \  /
     \/

______________
\  ________  /
 \ \  __  / /
  \ \ \/ / /
   \ \  / /
    \ \/ /
     \  /
      \/

$ 
Trauma Digital
fonte
5

C, 165 bytes

n,x,y,b,c;main(c,v)char**v;{for(n=atoi(v[1]);y<=n;++y){for(x=-n;x<n;++x){b=2*n-abs(2*x+1);c=b-2*y+2;b-=6*y;putchar(b>0?95:b<-4&c>0&c%4==1?"/\\"[x<0]:32);}puts("");}}

Antes das etapas do golfe que destroem a legibilidade:

#include <stdio.h>
#include <stdlib.h>

int main(int c, char** v) {
    int n = atoi(v[1]);
    for (int y = 0; y <= n; ++y) {
        for (int x = -n; x < n; ++x) {
            int b = 2 * n - abs(2 * x + 1);
            int c = b - 2 * y + 2;
            b -= 6 * y;
            putchar(b > 0 ? 95 : 
                    b < -4 && c > 0 && c % 4 == 1 ? "/\\"[x<0] : 32);
        }
        puts("");
    }
}

Isso faz um loop sobre todos os caracteres no retângulo que contém a figura e avalia as equações de linha que separam o interior do triângulo da parte externa, bem como as que separam as diferentes partes do triângulo.

Reto Koradi
fonte
Bom trabalho com matemática. Você deve tentar um presente: codegolf.stackexchange.com/q/51396/21348
edc65
156:n,x,y,b,c;main(c,v)char**v;{for(n=atoi(v[1]);y<=n;++y)for(x=-n;x<=n;putchar(x++-n?b>6*y?95:b<6*y-4&c>0&c%4==1?"/\\"[x<1]:32:10))c=(b=2*n-abs(2*x+1))-2*y+2;}
edc65
4

Retina , 182 bytes

1
_
^
#$_
((`#([^#]*?)( ?)_(_*)_( ?)([^#]*?)$
$0# $1\$3/$5
+)`\\( ?)_(_*)_( ?)/(?=[^#]*$)
\ $1$2$3 /
#( *(\\ )*\\ *)  ( *(/ )*/)$
$0# $1$3
)`#( *(\\ )*)\\/(( /)*)$
$0# $1$3
# 
#
^#
<empty line>

Toma a entrada como unária.

Cada linha deve ir para seu próprio arquivo e #deve ser alterada para nova linha nos arquivos. Isso é impraticável, mas você pode executar o código como um arquivo com a -sbandeira, mantendo os #marcadores. Você pode alterar as #linhas para novas linhas na saída para facilitar a leitura, se desejar. Por exemplo:

> echo -n 1111|retina -s triangle|tr # '\n'
________
\  __  /
 \ \/ /
  \  /
   \/

O código ainda não está muito bom.

randomra
fonte
2

C - 206 bytes

i,j,m,k,a,b;main(i,v)char**v;{m=atoi(v[1])*2;while(k<m*(m/2+1)){i=k/m;j=k%m;a=i*3,b=(i+j)%2;putchar("_\\/ "[j>=a&&j<m-a?0:j>i-2&&b&&j<i*3-1&&j<m/2?1:j<=m-i&&!b&&j>m-a&&j>=m/2?2:3]);if(j==m-1)puts("");k++;};}

 x,m,i,j,a,b;
int main(x,v)char**v;{
    m=atoi(v[1])*2;
    for(i=0;i<m/2+1;i++){
        for(j=0;j<m;j++){
            a=i*3,b=(i+j)%2;
            j>=a&&j<m-a?a=0:j>=i-1&&b&&j<i*3-1&&j<m/2?a=1:j<=m-i&&!b&&j>m-a&&j>=m/2?a=2:(a=3);putchar("_\\/ \n"[a]);
        }
        puts("");
    }
}

Saída de exemplo

Pauls-iMac:ppcg pvons$ for i in $(seq 1 7); do ./a.out $i; done
__
\/
____
\  /
 \/ 
______
\    /
 \  / 
  \/  
________
\  __  /
 \ \/ / 
  \  /  
   \/   
__________
\  ____  /
 \ \  / / 
  \ \/ /  
   \  /   
    \/    
____________
\  ______  /
 \ \    / / 
  \ \  / /  
   \ \/ /   
    \  /    
     \/     
______________
\  ________  /
 \ \  __  / / 
  \ \ \/ / /  
   \ \  / /   
    \ \/ /    
     \  /     
      \/      
paulvs
fonte
1
Você pode cortar isso um pouco. Aproveitando o estilo antigo C, você pode declarar variáveis ​​sem um tipo, se houver int. Além disso, se você as declarar no escopo global, elas serão inicializadas automaticamente como 0. Em vez de ter putchar()várias chamadas em ramificações diferentes, você poderá usar uma única chamada e substituir as ifinstruções por operadores ternários. É claro que fica difícil ler dessa maneira, mas é completamente dentro do espírito deste site escrever código feio se for mais curto. :)
Reto Koradi
Obrigado @RetoKoradi, reduzi de 279 para 214 implementando suas sugestões :) Acho que precisaria melhorar meu algoritmo para obter mais melhorias.
paulvs
Sim, uma vez que você vá além da mecânica, a chave é encontrar regras que simplifiquem a lógica o máximo possível. Se você olhar para a minha solução, que é fundamentalmente muito semelhante, descobri que a lógica simplificou bastante colocando a origem da coordenada horizontal no centro do triângulo. Dessa forma, eu poderia aproveitar a simetria. E outros provavelmente encontraram abordagens ainda melhores. É realmente interessante o quanto pode ser feito em um problema que parece tão enganosamente simples.
precisa saber é o seguinte
1

JavaScript ( ES6 ) 165 180 204

Execute o snippet no Firefox para testar. Se retornar a string não for suficiente, usar alerta para saída é 2 caracteres a mais.

// 165 - return the string
F=n=>
  (i=>{
    for(r='__'[R='repeat'](m=n);i<n;)
      r+=`\n`+' '[R](i)
       +('\\ '[R](t=-~(m>3?i:~-n/3))+' ').slice(0,n-i)
       +'__'[R](m>3?m-=3:0)
       +(' '+' /'[R](t)).slice(i++-n)
  })(0)||r


// 167 - output the string
A=n=>{
  for(i=0,r='__'[R='repeat'](m=n);i<n;)
    r+=`\n`+' '[R](i)
     +('\\ '[R](t=-~(m>3?i:~-n/3))+' ').slice(0,n-i)
     +'__'[R](m>3?m-=3:0)
     +(' '+' /'[R](t)).slice(i++-n);
  alert(r)
}

// TEST
out=x=>O.innerHTML += x+'\n' 

for(k=1;k<13;k++)out(k+'\n'+F(k))
<pre id=O></pre>

edc65
fonte