Faça de mim uma árvore de Natal de cabeça para baixo!

15

Desafio

Todos sabemos sobre árvores de Natal normais - mas que tal uma árvore de Natal de cabeça para baixo ! Este é um desafio bastante fácil para o Natal. O objetivo deste desafio é me tornar uma árvore de Natal de cabeça para baixo ASCII. Aqui estão as regras para este desafio:

  1. Aceite um número inteiro ímpar positivo. Você pode assumir que sempre estará entre 7e 51.
  2. A base da árvore será composta pelos caracteres:

    ___
    \ /
     |
    
  3. O topo da árvore (a estrela) será constituído por uma única *.

  4. Cada linha da árvore será construída usando o formato <?>onde ?houver qualquer número de -s. Por exemplo, se estiver fazendo uma linha de comprimento 5, a linha deve ser <--->. Ou, se estiver fazendo uma linha de comprimento 8, a linha deve ser <------>.

  5. Aqui está como o corpo da árvore deve ser construído:

    1. Pegue o número ímpar ndado como entrada e crie uma linha da árvore desse tamanho.

    2. Subtrair 4a partir ne criar uma linha da árvore que comprimento.

    3. Subtrair 2a partir ne criar uma linha da árvore que comprimento.

    4. Decrementar npor 2. Depois disso, a menos que seja nigual5 , volte para a etapa 2.

  6. A base (consulte a etapa 2.) a estrela (consulte a etapa 3.) e cada linha da árvore (consulte as etapas 4. e 5.) devem ser centralizadas usando a entrada do número ímpar original (consulte a etapa 1.) como o valor máximo largura.

Exemplos / Casos de Teste

odd number inputed: 7
  ___
  \ /
   |
<----->      line length -> 7
  <->        line length -> 7 - 4 = 3
 <--->       line length -> 7 - 2 = 5
   *


odd number inputed: 13
     ___
     \ /
      |
<----------->      line length -> 13
  <------->        line length -> 13 - 4 = 9
 <--------->       line length -> 13 - 2 = 11
   <----->         line length -> 11 - 4 = 7
  <------->        line length -> 11 - 2 = 9
    <--->          line length -> 9 - 4 = 5
   <----->         line length -> 9 - 2 = 7
     <->           line length -> 7 - 4 = 3 
    <--->          line length -> 7 - 2 = 5
      *


odd number inputed: 9
   ___
   \ /
    |
<------->      line length -> 9
  <--->        line length -> 9 - 4 = 5
 <----->       line length -> 9 - 2 = 7
   <->         line length -> 7 - 4 = 3
  <--->        line length -> 7 - 2 = 5
    *


odd number inputed: 17
       ___
       \ /
        |
<--------------->      line length -> 17
  <----------->        line length -> 17 - 4 = 13
 <------------->       line length -> 17 - 2 = 15
   <--------->         line length -> 15 - 4 = 11
  <----------->        line length -> 15 - 2 = 13
    <------->          line length -> 13 - 4 = 9
   <--------->         line length -> 13 - 2 = 11
     <----->           line length -> 11 - 4 = 7
    <------->          line length -> 11 - 2 = 9
      <--->            line length -> 9 - 4 = 5
     <----->           line length -> 9 - 2 = 7
       <->             line length -> 7 - 4 = 3
      <--->            line length -> 7 - 2 = 5
        *    

Regras

Christian Dean
fonte
3
Como a entrada é garantida como um número ímpar, podemos pegar seu índice na sequência de números ímpares?
FlipTack
Também - repeat the above steps until the odd number minus 2 equals 5- na primeira entrada, o número ímpar é 7, e 7-2 = 5, portanto, a árvore deve terminar instantaneamente (eu sei que você quer dizer, mas precisa reformular)
FlipTack
@FlipTack Não sei exatamente o que você quer dizer. Se o número ímpar é 7, a entrada mínima, você primeiro criar as três linhas de árvores (sub-etapas .1.1, .1.2, .1.3), em seguida, subtrair 2do número ímpar e testar se ele é igual 5. A instrução para verificar se o "número ímpar menos 2 é igual a 5" está no final, os outros três passos devem ser executados primeiro. Mas, para responder seu primeiro comentário, tudo bem.
Christian Dean
1
@FlipTack Acho que ele está perguntando se você precisa aceitar 7como entrada ou se pode aceitar 4, como no quarto número ímpar (ou 3se é 0).
DonielF
4
Do título: "Ok, agora você é uma árvore de Natal de cabeça para baixo".
Dkudriavtsev 27/12/2017

Respostas:

10

Python 3 , 127 121 105 103 100 98 bytes

Esta é uma função lambda sem nome que retorna uma lista de linhas:

lambda o:[s.center(o)for s in['___','\ /','|',*[f'<{"-"*(o-i+2-i%2*3)}>'for i in range(4,o)],'*']]

Experimente online!

A parte principal desta resposta é (o-i+2-i%2*3) , que calcula o número de traços a ter em uma linha. O restante da resposta está simplesmente convertendo isso na arte ASCII desejada.

Muito obrigado ao Sr. Xcoder , por barbear 6 bytes e discutir comigo sobre o golfe no chat.

Agradecemos também a Lynn por perceber que 3*(i%2)pode ser i%2*3, 2 bytes mais curto!

FlipTack
fonte
2
Sempre que eu postar uma resposta em Python, não importa a hora do dia ou sua localização atual, o @ Mr.Xcoder tem um campo de golfe para dar :)
FlipTack
Bem , isso supera facilmente a minha solução de 250 bytes + Python. Bom trabalho! +1
Christian Dean
o-i+2-i%2*3salva dois bytes.
Lynn
@ Lynn Bom local, atualizado.
FlipTack
7

C, 163 bytes

#define P;printf(
i;g(l){P"%*c",1+i-l--/2,60);for(;--l P"-"))P">\n");}f(n){i=n/2 P"%*c__\n%*c /\n%*c|\n",i,95,i,92,i,32);for(g(n);n>5;g(n-=2))g(n-4)P" %*c",i,42);}

Experimente online!

Desenrolado:

#define P;printf(

i;
g(l)
{
    P"%*c", 1+i-l--/2, 60);
    for (; --l P"-"))
    P">\n");
}

f(n)
{
    i=n/2
    P"%*c__\n%*c /\n%*c|\n", i, 95, i, 92, i, 32);

    for(g(n); n>5; g(n-=2))
        g(n-4)

    P" %*c", i, 42);
}
Steadybox
fonte
6

Próton , 83 bytes

Agradecemos ao FlipTack por economizar 4 bytes e por colaborar no chat (na verdade, formamos uma ótima equipe). Economizou indiretamente 2 bytes graças a Lynn .

o=>[s.center(o)for s:['___','\ /','|']+['<'+"-"*(o-i+2-i%2*3)+'>'for i:4..o]+['*']]

Experimente online!

Mr. Xcoder
fonte
5

Carvão , 28 bytes

__⸿ /⸿|F⮌…¹⊘N«⸿⊕ι>⸿⊖ι>»‖B← *

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

__⸿ /⸿|

Imprima a base.

F⮌…¹⊘N«

Faça um loop da metade do número de entrada para 1.

⸿⊕ι>⸿⊖ι>»

Imprima duas linhas, a primeira com uma a mais -que o índice do loop, a segunda com uma a menos.

‖B←

Espelho para completar a árvore.

 *

Coloque a estrela.

Neil
fonte
3

Retina , 89 bytes

.+
$*->
^--
<
+`( *<)----(-+>)$
$&¶  $1$2¶ $1--$2
s`.*¶( +)<->.*
$1___¶$1\ /¶$1 |¶$&¶$1 *

Experimente online! Explicação: O primeiro estágio converte a entrada em unário e anexa a >. O segundo estágio substitui dois -s por a <para corrigir o comprimento da linha. O terceiro estágio replica a ramificação, mas um pouco menor a cada vez, até que a ramificação não possa mais ser reduzida. A etapa final adiciona a base e a estrela.

Neil
fonte
2

Javascript 506 bytes

Versão Golf:

function tree(i){const mid=(i+1)/2;const leg1=' '.repeat((mid-2))+`___
`;const leg2=' '.repeat((mid-2))+`\\ \/
`;const leg3=' '.repeat((mid-1))+`|
`;let xmasTree=leg1+leg2+leg3;for(let j=0;j<(i-4);j++){if(j%2===0){let v=j/2;let t=i-2*v-2;let body1=" ".repeat(j/2)+"<"+"-".repeat(t)+">"+`
`;xmasTree=xmasTree+body1}else{let k=1+Math.ceil(j/2);let h=i-2*k-2;let body2=' '.repeat(k)+'<'+'-'.repeat(h)+">"+`
`;xmasTree=xmasTree+body2}}
const head=' '.repeat((mid-1))+'*'
xmasTree=xmasTree+head;return xmasTree}

Ungolf-version:

function tree(i){
  const mid = (i+1)/2;
  const leg1 = ' '.repeat((mid-2)) + `___
`;
  const leg2 = ' '.repeat((mid-2)) + `\\ \/
`;
  const leg3 = ' '.repeat((mid-1)) + `|
`;
  let xmasTree = leg1 + leg2 + leg3;
  for (let j = 0; j<(i-4); j++) {
    if (j%2===0) {
      let v = j/2;
      let t = i-2*v-2;
      let body1 = " ".repeat(j/2)+"<"+"-".repeat(t) +">"+`
`;
      xmasTree = xmasTree + body1;
    } else {
      let k = 1 + Math.ceil(j/2);
      let h = i-2*k-2;
      let body2 = ' '.repeat(k)+ '<'+ '-'.repeat(h) + ">"+`
`;
      xmasTree = xmasTree + body2;
    }
  }
  const head = ' '.repeat((mid-1)) + '*'
  xmasTree = xmasTree + head;
  return xmasTree;
}

Uso: console.log(tree(13)), console.log(tree(17)),

ES6 165 bytes (do meu amigo)

Versão Golf:

p=n=>{l=_=>console.log(`${' '.repeat((n-_.length)/2)}${_}`);t=_=>_==1?'*':'<'+'-'.repeat(_-2)+'>';x=n;l('___');l('\\ /');l('|');for(;x!==3;){l(t(x));l(t(x-4));x-=2}}

Ungolf-version:

p = n => {
  l = _ => console.log(`${' '.repeat((n-_.length)/2)}${_}`);
  t = _ => _ == 1 ? '*' : '<' + '-'.repeat(_-2)+'>';
  x = n;
  l('___');l('\\ /');l('|');
  for(;x!==3;) {
    l(t(x)); l(t(x-4));x-=2;
  }
}

Uso: p(31); p(17);

NTCG
fonte
1
Você pode jogar muito isso usando apenas nomes de variáveis ​​de uma letra, removendo constpalavras-chave etc.
FlipTack
1

PowerShell , 131 bytes

$i=2;$x="$args"..5|%{' '*($j=if($_%2){$i-2}else{($i++)})+'<'+'-'*($_-(5,2)[$_%2])+'>'};($y=' '*++$j)+"___";"$y\ /";"$y |";$x;"$y *"

Experimente online!

Bem, essa é uma bagunça certa para quem não conhece o PowerShell ... então, vamos ver o quanto eu posso explicar como funciona.

Para a explicação, eu vou estar usando input = 17.

Começamos de maneira bastante simples, com a configuração da variável auxiliar $i=2e a configuração $xpara <something>, com o <something>início como um intervalo da entrada $argsaté a 5, então 17,16,15,...,6,5. Esse intervalo é bombeado para um loop for.

A cada iteração, começamos com a configuração da variável auxiliar $jcomo o resultado de uma ifinstrução if($_%2){$i-2}else{($i++)},. Se for estranho $j=$i-2, caso contrário $j=($i++). Isso, juntamente com $i=2o começo, nos dá a sequência 0, 2, 1, 3, 2, 4, 3, 5...que corresponde exatamente a quantos espaços precisamos anexar à nossa linha de árvores. ;-) Nós levamos' ' e multiplicamos por esse número.

Em seguida, precisamos de nossas filiais. Isso é feito com '<'mais a parte do meio '-'multiplicada, mais o final '>'. A multiplicação é feita reconhecendo que a -alternativa se alterna em um 2, 5, 2, 5, 2...padrão com base no número de entrada $_; portanto, estamos selecionando um pseudo-ternário com base nesse padrão.

Para maiores esclarecimentos, eis os dois primeiros termos de cada seção:

$_ = 17 16 15 14 13 12 11 10
$j =  0  2  1  3  2  4  3  5
mid=  2  5  2  5  2  5  2  5
'-'= 15 11 13  9 11  7  9  5

Então agora definimos $xcomo uma matriz de ramificações (ou seja, strings). Fora do loop, agora construímos nossa árvore "em cima" com o número apropriado de espaços salvos $y, depois exibimos nossos galhos $xe depois a árvore "em baixo" com o *. Cada um deles é deixado no pipeline e a saída está implícita em uma nova linha entre os itens.

AdmBorkBork
fonte
1

JavaScript (ES6), 150 147 bytes

N=>{for(s=' '[r='repeat'](N/2-1),s+=`___
${s}\\ /
${s} |
`,n=N,l=n=>' '[r](N/2-n/2)+(n-1?`<${'-'[r](n-2)}>
`:'*');n-3;n-=2)s+=l(n)+l(n-4)
return s}

darrylyeo
fonte
1

Tela , 28 bytes

-×>+∔
__¶ /¶|╶┤r⇵{├⁸¹⁸}k*∔↔│

Experimente aqui!

Uma porta da minha resposta SOGL que é uma porta da resposta do Neil's Charcoal.

dzaima
fonte
0
N=>{for(s=' '[r='repeat'](N/2-1),s+=`___
${s}\\ /
${s} |
`,l=n=>' '[r](N/2-n/2)+n-1?`<${'-'[r](n-2)}>
`:'*');N-=2;s+=l(N)+l(N-4);return s}

Minha tentativa no JS ESGoogoltriplex.

user75200
fonte