Crie uma barraca de cabeça para baixo


27

Dado um número inteiro, produza uma barraca de cabeça para baixo.

A entrada determina o tamanho da barraca (valor absoluto) e se a entrada está no lado esquerdo (números negativos) ou no lado direito (números positivos).

If input = -1:
____
\/_/

If input = -2:
________
\  /   /
 \/___/

If input = -3:
____________
\    /     /
 \  /     /
  \/_____/

If input = 1:
____
\_\/

If input = 2:
________
\   \  /
 \___\/

If input = 3:
____________
\     \    /
 \     \  /
  \_____\/

et cetera

Observe que o topo da barraca (ou seja, a última linha) tem 2 * abs(input) - 1sublinhados.

Não pode haver nenhum espaços à esquerda, de modo que a primeira linha começa diretamente com um sublinhado.

Suponha que a entrada nunca será 0.

Seu código deve ser o mais curto possível.

Esse desafio é baseado em um mini desafio de bate - papo da Helka Homba , que pode ser usado em desafios reais sob as condições da Licença pública de hobby da Calvin .


1
Os espaços à direita estão OK? Ou seja, podemos produzir quatro strings de 12 comprimentos (um retângulo) para entrada, 3por exemplo?
AdmBorkBork 14/09/16

1
@ TimmyD Eles são permitidos.
user48538

2
@ TimmyD com certeza, que provavelmente também é um idiota de outra coisa, não tenho muita certeza de onde a cadeia começa. Só acho que já vimos o suficiente até agora.
21137 Nathaniel

5
Não vejo como as perguntas são remotamente semelhantes. Claro, os dois são desafios de arte que levam um número e você produz a n-ésima iteração de algo, mas é aí que a semelhança termina. Se isso é suficiente para parecer bobagem, não devemos aceitar mais nenhum desafio de arte .
DJMcMayhem

2
@ Nathaniel Nossa orientação aceita para que dois desafios sejam duplicados é se as respostas de um podem ser reutilizadas (competitivamente) por outro com pouca ou nenhuma modificação. Se os desafios trazem algo novo para a mesa não faz parte dessa diretriz. Use votos negativos para os desafios que você deseja desencorajar ou apenas os ignore se eles não acharem que são interessantes e deixe que aqueles que os apreciam.
Martin Ender

Respostas:


11

MATL , 55 53 52 51 bytes

|95cy4*Y"DXytPEt0*yvG0>?P_]!'\/ 'w)95JG|G0<yEq:++&(

Experimente online!

Explicação

Vamos Ndenotar a entrada. O código continua em três etapas.

Primeiro , a primeira linha de 4*Nsublinhados é criada como uma sequência e é exibida (o que a remove da pilha).

Segundo , a "estrutura" da barraca é construída usando os dois tipos de barras. Para isso, é criada uma matriz 2D numérica que contém 1e 2corresponde aos dois tipos de barras e 0para espaço.

Isso é feito concatenando quatro matrizes:

  1. Uma matriz de identidade de tamanho abs (N);
  2. Uma matriz do mesmo tamanho que contém 2no antidiagonal;
  3. Uma matriz nula do mesmo tamanho;
  4. Uma cópia da matriz 2.

Concatenar essas quatro matrizes verticalmente fornece, usando N=3como exemplo, a seguinte 4*N × Nmatriz:

1 0 0
0 1 0
0 0 1
0 0 2
0 2 0
2 0 0
0 0 0
0 0 0
0 0 0
0 0 2
0 2 0
2 0 0

(que, transposto, começa a parecer com a tenda).

Agora cuidamos do sinal da entrada. Se for positivo, simplesmente transporemos a matriz acima e indexaremos na string '\/ '. A indexação é baseada em 1 e modular, 1tornando - se '\', 2tornando '/'- 0se e tornando - se ' ', produzindo a matriz de caracteres 2D

\    /     /
 \  /     / 
  \/     /  

Por outro lado, se a entrada é negativa, invertemos verticalmente e negamos aritmeticamente a 4*N × Nmatriz, produzindo

-2  0  0
 0 -2  0
 0  0 -2
 0  0  0
 0  0  0
 0  0  0
-2  0  0
 0 -2  0
 0  0 -2
 0  0 -1
 0 -1  0
-1  0  0

O índice -1agora se refere a '/'e -2para '\'. Ou seja, os dois tipos de barras foram trocados, conforme necessário. Mais uma vez, a transposição e indexação para a cadeia de caracteres '\/ 'fornece a barraca invertida:

\     \    /
 \     \  / 
  \     \/  

Terceiro , os sublinhados precisam ser preenchidos em parte da última linha da matriz de caracteres 2D. A posição horizontal desta linha depende do sinal da entrada e seu comprimento é abs(N).

Depois que os espaços correspondentes forem substituídos por sublinhados, o resultado será exibido implicitamente, abaixo da linha inicial de sublinhados que já foi exibida na primeira etapa.


Esses sublinhados no começo não deveriam ser espaços?
DJMcMayhem

@DJMcMayhem Desculpe, o que você quer dizer?
Luis Mendo

Quando executo seu código, a primeira linha está com todos os sublinhados. A saída que o zyabin deu não tem isso.
DJMcMayhem

@DJMcMayhem Eu não sigo. A primeira linha nos casos de teste é sublinhada, não é? E outras respostas (não a sua) também fazem isso?
Luis Mendo

1
@DJMcMayhem :-D Estranho mesmo. Tente um navegador diferente?
Luis Mendo

9

Javascript (ES6), 139 bytes

Constrói a barraca recursivamente:

f=(N,n=N>0?N:-N,i=0,r=(j,i)=>' _'[i||0].repeat(j),a=`\\${r(i)}/`,b=r(n*2+i-1,+!i))=>n--?f(N,n,i+2)+`
`+r(n)+(N<0?a+b+'/':'\\'+b+a):r(i*2,1)

Ungolfed e comentou

f = (
  N,                                  // N is the original parameter (remains unchanged)
  n = N > 0 ? N : -N,                 // n is initialized to abs(N)
  i = 0,                              // i is the row counter (*2)
  r = (j, i) => ' _'[i||0].repeat(j), // helper function to repeat ' ' or '_' j times
  a = `\\${r(i)}/`,                   // a = '\ /' pattern
  b = r(n*2+i-1, +!i)                 // b = padding pattern filled with ' ' or '_'
) =>
  n-- ?                               // if we haven't made it yet to the top row:
    f(N, n, i+2) + `\n` +             //   - compute next row(s) / append line break
    r(n) +                            //   - append leading spaces
    (N < 0 ? a+b+'/' : '\\'+b+a)      //   - append a/b patterns according to N sign
  :                                   // else:
    r(i*2, 1)                         //   - return top row, made of '_' characters

Exemplos

var f=(N,n=N>0?N:-N,i=0,r=(j,i)=>' _'[i||0].repeat(j),a=`\\${r(i)}/`,b=r(n*2+i-1,+!i))=>n--?f(N,n,i+2)+`
`+r(n)+(N<0?a+b+'/':'\\'+b+a):r(i*2,1)

console.log(f(3));
console.log(f(-4));


6

Python 2, 143 141 139 138 137 bytes

-2 bytes graças a @ Sp3000 (sem necessidade de parênteses ao exec em Python 2)
-1 byte graças a @ Sp3000 (use cmp)

def f(n):d=cmp(n,0);a,b='\/'[::-d];s=n*d;x=2*s-1;y=4*s;print'_'*y;i=0;exec"print' '*i+(b+' '*(y-3-x-i-i)+a+'_ '[s-i>1]*x+a)[::d];i+=1;"*s

Teste em ideone

Primeiro vemos se né negativo e fazemos d +1se é e -1se não é.
Em seguida, selecionamos as duas barras ae b, usando de dmodo que a='\', b='/'quando né positivo e a='/', b='\'quando né negativo.
Em seguida, definimos o s=abs(n)que pode ser alcançado por s=n*d.
Em seguida, calculamos o número de _na parte superior (parte inferior da imagem), que também é o número de na lateral da barraca como x=2*s-1.
Em seguida, calculamos o número de _na base da barraca (parte superior da imagem) e armazenamos como y=4*suma vez que será usada no loop para criar o restante da barraca.
Agora, imprimimos a base da barraca usando print'_'*y.
Em seguida, imprimimos o restante da tenda executando sinstruções print com uma variável em loop iinicializada na 0qual incrementa 1para cada instrução print.
O restante da barraca tem y-3-x-i-iespaços na porta e xespaços no corpo até que o topo seja atingido, quando for s-i>1avaliado como Falso, escolhendo a _partir de '_ '.
Para uma tenda positiva da porta esquerda, a tenda inteira, excluindo os espaços à esquerda, fica de trás para frente, de modo que é revertida enquanto a tenda positiva da porta direita não está [::d].


@ SP3000 infelizmente cmp(0,0)retorna0
Jonathan Allan

5

Python 2, 121 bytes

def f(n):i=k=abs(n);print'_'*k*4;exec"print' '*(k-i)+r'\\\%%s%\*%c%%*sc/'[n<0::2]%(' _'[i<2]*(2*k-1))%(2*i-1,47);i-=1;"*k

Apenas muita formatação de string.


5

C #, 215 214 bytes

string t(int N){var n=N<0;N=n?-N:N;var t=new string('_',4*N);for(int i=0;i<N;){string f=new string(i<N-1?' ':'_',2*N-1),p=new string(' ',2*N-2*i-2);t+='\n'+new string(' ',i++)+'\\'+(n?p+'/'+f:f+'\\'+p)+'/';}return t;}

Existe a possibilidade de salvar alguns bytes ao usar com using s=string;antecedência.

s t(int N){var n=N<0;N=n?-N:N;var t=new s('_',4*N);for(int i=0;i<N;){s f=new s(i<N-1?' ':'_',2*N-1),p=new s(' ',2*N-2*i-2);t+='\n'+new s(' ',i++)+'\\'+(n?p+'/'+f:f+'\\'+p)+'/';}return t;}

que seria 15 (usando) + 184 (método) = 199 bytes.


5
Bem-vindo ao PPCG, BackFromExile!
Erik the Outgolfer

Bem-vindo ao PPCG! Uma ótima primeira resposta +1. Tentei encontrar algo para jogar golfe (um bom tempo desde que programei em C #) e, no final, só consegui encontrar uma coisa para -1 byte: se você alterar a primeira vardentro do loop for para string, poderá remover o segundo var (incluindo espaço para salvar o byte). Então var fse torna string f, e ;var p=se torna ,p=.
Kevin Cruijssen 16/09

4

TSQL, 195 bytes

Golfe:

DECLARE @ INT=-2
DECLARE @b INT=ABS(@),@i INT=0PRINT REPLICATE('_',4*@b)z:SET @i+=1PRINT SPACE(@i-1)+'\'+STUFF(REPLICATE(IIF(@i<@b,' ','_'),4*@b-2*@i),@b*2-IIF(@<0,@i*2-1,0),1,IIF(@<0,'/','\'))+'/'IF @i<@b GOTO z

Ungolfed:

DECLARE @ INT=-2

DECLARE @b INT=ABS(@),@i INT=0

PRINT REPLICATE('_',4*@b)
z:
  SET @i+=1
  PRINT 
    SPACE(@i-1)+'\'
    +STUFF(REPLICATE(IIF(@i<@b,' ','_'),
      4*@b-2*@i),@b*2-IIF(@<0,@i*2-1,0),1,IIF(@<0,'/','\'))
    +'/'
IF @i<@b GOTO z

Violino


4

V , 66 bytes

é /ä
"aDoÀñá_>ñ^hr\A\/ò^hÄX$2é_Ó_/ òÄÒ_ñ/-
ddÍܨ[ _]*©Ü¨ *©/ܲ¯±

Experimente online!

Essa é uma abordagem bastante ingênua, então tentarei jogar mais tarde hoje. Esta solução contém caracteres não imprimíveis, então aqui está um hexdump:

0000000: e920 2fe4 0a22 6144 6f1b c0f1 e15f 3ef1  . /.."aDo...._>.
0000010: 5e68 725c 415c 2f1b f25e 68c4 5824 32e9  ^hr\A\/..^h.X$2.
0000020: 5fd3 5f2f 20f2 c4d2 5ff1 2f2d 0a64 64cd  _._/ ..._./-.dd.
0000030: dca8 5b20 5f5d 2aa9 dca8 202a a92f dcb2  ..[ _]*... *./..
0000040: afb1                                     ..

4

05AB1E , 52 bytes

Ä©'_4®*×,FNð×'\®·<N>®Qi'_ëð}×®N>-·ð×®¹Qi'\ës'/}s'/J,

Explicação

                                                     # implicit input, call this A
Ä©                                                   # store abs(A) in register for later use
  '_4®*×,                                            # print 4*A underscores (tent floor)
         F                                           # for each non-floor section in range(N)
          Nð×'\                                      # push N spaces at the beginning of the 
                                                     # row followed by a backslash
                  N>®Qi'_ëð}                         # if we're on the last row push an
                                                     # underscore, else a space
               ®·<          ×                        # repeat that char abs(A)*2-1 times
                             ®N>-·ð×                 # push 2*(abs(A)-(N+1)) spaces
                                    ®¹Qi'\ës'/}      # if input is positive push backslash
                                                     # else push a slash
                                               s'/   # move that char between the 2 sections
                                                     # of spaces
                                                  J, # join the row and print

Experimente online!


4

PowerShell v2 +, 217 205 190 187 184 bytes

param($b)"_"*(($a=[math]::Abs($b))*4);$z,$y='/\'[($b=$b-lt0),!$b]
((($x=1..$a|%{($w=" "*($_-1))+$z+" "*(2*($a-$_))+$y+(' ','_')[$_-eq$a]*($a*2-1)+$y+$w})|%{-join$_[($a*4)..0]}),$x)[$b]

Recebe a entrada $bcomo um número inteiro. Observe que, se $bfor negativo, é necessário cercá-lo explicitamente com parênteses para convertê-lo adequadamente (veja exemplos); caso contrário, o PowerShell achará que é uma sequência.

Independentemente de qual direção a tenda está voltada, a primeira linha é a mesma, um monte de sublinhados; exatamente 4*abs(input)muitos deles, na verdade. Esse número também é armazenado $apara uso posterior. Além disso, agora que temos o valor absoluto de $barmazenado em $a, transformamos $bem um booleano para seu sinal e escolhemos nossas barras armazenadas em $ye $z.

A próxima linha está construindo e formulando a saída, e é uma bagunça, então vamos detalhar.

Estamos essencialmente indexando em uma matriz de dois elementos, (big long calculations saved into $x)ou com $xbase em $b.

Os cálculos são onde o corpo da barraca é construído. Nós fazemos um loop 1..$a|%{...}. A cada iteração, estamos construindo uma linha do corpo da barraca. Começamos com um número de espaços igual à linha em que estamos -1, para que fique alinhado à esquerda. Isso é armazenado $wpara mais tarde e concatenado com a barra apropriada ($ z, com base em $b), o número de espaços do doorframe, a outra barra $ye os sublinhados ou espaços, dependendo se estamos no resultado final ou não, depois outra barra $ye, finalmente, o número apropriado de espaços à direita ( $w) para construir uma sequência retangular. Essa matriz resultante de strings é armazenada $x.

Se a metade esquerda da matriz é seleccionado (ou seja, $bé Falseuma vez que a entrada foi positiva), em seguida, temos de percorrer $xe reverso cada item de linha - isto é, onde os espaços à direita entram em jogo; permite simplesmente reverter as linhas em vez de recalcular as distâncias.

Se $bfor True, a metade direita da matriz $xé selecionada.

Em qualquer um dos casos, o pipeline agora contém uma matriz de seqüências de caracteres. Saída implícita via Write-Outputacontece na conclusão do programa, com nova linha padrão entre os elementos.

Exemplos

PS C:\Tools\Scripts\golfing> .\print-upside-down-tent.ps1 (-5)
____________________
\        /         /
 \      /         / 
  \    /         /  
   \  /         /   
    \/_________/    

PS C:\Tools\Scripts\golfing> .\print-upside-down-tent.ps1 (4)
________________
\       \      /
 \       \    / 
  \       \  /  
   \_______\/   

3

Haskell, 187 184 183 bytes

f x=unlines$[(n*4)%'_']++((' '#)<$>[0..n-2])++['_'#(n-1)]where m#i=i%' '++'\\':m!i++"/";m!i|x>0=(2*n-1)%m++'\\':(2*(n-i-1))%' '|q<-2*(n-i-1)=q%' '++'/':(2*n-1)%m;n=abs x;m%c=c<$[1..m]

Eu sinto que essa não é uma ótima nota para Haskell, então qualquer idéia de melhoria é bem-vinda.

Ungolfed

tent :: Int -> String
tent x = unlines $ [replicate (n*4) '_'] ++ (row ' '<$>[0..n-2]) ++ [row '_' (n-1)]
    where row m i = replicate i ' ' ++ "\\" ++ dir m i ++ "/"
          -- direction selector
          dir m i | x > 0 = side m ++ "\\" ++ entrance i ' '
                  | 1 > 0 = entrance i ' ' ++ "/" ++ side m
          side = replicate (2*n-1)
          entrance i = replicate (2*(n-i-1))
          n = abs x

Melhor do que os meus 290 bytes, eu estava prestes a postar ...
Myridium

Você não deve adicionar um mainpara que ele aceite stdincomo entrada?
Myridium 14/09/16

Você pode postar uma única função, a menos que a pergunta especifique o contrário. Há um meta-tópico para as regras gerais de resposta, tentarei encontrá-lo para você.
Sudee

1
Você pode salvar 2 bytes alterando o local onde você precede um único caractere para usá-lo :. ou seja, mude "\\" ++ entrance...para '\\':entrance.
Myridium 14/09/16

1
Não desperdice a proteção "caso contrário" : você pode mudar |1>0=(2*(n-i-1))%' 'para |q<-2*(n-i-1)=q%' '.
nimi

2

C, 240 207 193 bytes

#define P putchar
a,j,l,m;g(x,y,z){for(m=y+z+1;m--;P(m^z?l?32:95:x));}f(n){g(32,(a=abs(n))*4,0);for(P(10),j=2*(l=a)-1;l--;){for(m=a;--m>l;P(32));P(92);m=n>0?g(92,j,l*2):g(47,l*2,j);puts("/");}}

Dessa vez, otimizei a função g (...) para usar um único loop for.

#define P putchar
a,j,l,m;g(x,y,z){for(;y--;P(l?32:95));for(P(x);z--;P(l?32:95));}f(n){g(32,(a=abs(n))*4,0);l=a;j=2*a-1;P(10);for(;l--;){for(m=a;--m>l;P(32));P(92);m=n>0?g(92,j,l*2):g(47,l*2,j);puts("/");}}

Desta vez, a macro X é melhor como uma função g (...) e, como y e z são parâmetros em um novo escopo, posso apenas diminuí-los no escopo de g.

#define P putchar
#define X(x,y,z){for(k=0;k++<y;P(l?32:95));P(x);for(k=0;k++<z;P(l?32:95));}
a,i,j,k,l,m;f(n){for(l=a=abs(n);i++<a*4;P(95));j=2*a-1;P(10);while(l--){for(m=a;--m>l;P(32));P(92);if(n>0)X(92,j,l*2)else X(47,l*2,j)puts("/");}}

Teste com esta função principal; Isso deve diminuir muito mais.

main(c,v)char**v;
{
    f(atoi(v[1]));
}

2

C # 241 231 bytes

Guardado 10 bytes graças a @Kevin Cruijssen

using s=System.String;s f(int N){var f=N<0;N=N>0?N:-N;var o=new s('_',N*4);for(int j=0,z;j<N;){z=-2*j+2*N-2;var O=j>N-2?'_':' ';o+='\n'+new s(' ',j)+'\\'+new s(' ',z)+(f?'/':O)+new s(O,j++*2)+(f?O:'\\')+new s(' ',z)+'/';}return o;}

Versão antiga:

string f(int N){var f=N<0;N=N>0?N:-N;var o=new string('_',N*4);for(int j=0;j<N;){int z=-2*j+2*N-2;var O=j>N-2?'_':' ';o+='\n'+new string(' ',j)+'\\'+new string(' ',z)+(f?'/':O)+new string(O,j++*2)+(f?O:'\\')+new string(' ',z)+'/';}return o;}

Originalmente tinha a new string(...)como um Func<char,int,string>, mas salvou um byte usando o construtor. Eu queria int-> charestava implícito

Tenho certeza de que minha matemática também pode ser corrigida de alguma forma, mas não consigo vê-la


1
Você pode jogar um pouco mais. Primeiro de tudo você pode remover o int antes z=, adicionando-o ao lacete for-: int j=0,z. E uma vez que você usa stringbastante, você pode apelido de TI com using s=System.String;isso o total se torna: using s=System.String;s f(int N){var f=N<0;N=N>0?N:-N;var o=new s('_',N*4);for(int j=0,z;j<N;){z=-2*j+2*N-2;var O=j>N-2?'_':' ';o+='\n'+new s(' ',j)+'\\'+new s(' ',z)+(f?'/':O)+new s(O,j++*2)+(f?O:'\\')+new s(' ',z)+'/';}return o;}( 231 bytes )
Kevin Cruijssen

1

Swift 2.2 421 bytes

Bem ... Esta foi uma tentativa.

Golfe:

let t={(s:String,n:Int)->String in return String(count:n,repeatedValue:Character(s))};let e={(n:Int)in var w=[String]();w.append(t("_",abs(n)*4));let c = abs(n);let d = n>0 ? "/": "\\";let f = n>0 ? "\\": "/";for var i in 0...abs(n)-1 {w.append(t(" ",i)+d+t(" ",c*2-2-(2*i))+f+(i<c-1 ?t(" ",2*c-1)+f:t("_",2*c-1)+f)+(n>0 ?t(" ",i):""));};w=n<0 ?w:w.map(){String($0.characters.reverse())};print(w.joinWithSeparator("\n"))}

UnGolfed:

let t={(s:String,n:Int) -> String in
    return String(count:n,repeatedValue:Character(s))
};
let e={(n:Int) in
    var w=[String]();
    w.append(t("_",abs(n)*4));
    let c = abs(n);
    let d = n>0 ? "/": "\\";
    let f = n>0 ? "\\": "/";
    for var i in 0...abs(n)-1 {
        w.append(t(" ",i)+d+t(" ",c*2-2-(2*i))+f+(i<c-1 ?t(" ",2*c-1)+f:t("_",2*c-1)+f)+(n>0 ?t(" ",i):""));
    };
    w=n<0 ?w:w.map(){String($0.characters.reverse())};
    print(w.joinWithSeparator("\n"))
}

1

PHP, 143 bytes

$t=str_repeat;echo$t(_,4*$s=$k=abs($n=$argv[1]));for(;$k--;$p.=" "){$f=$t("  ",$k);$r=$t($k?" ":_,2*$s-1);echo"
$p\\",$n<0?"$f/$r/":"$r\\$f/";}

correr com php -r '<code>' <parameter>

demolir

$t=str_repeat;  // function name to variable saves 10-1 bytes
echo$t(_,4*$s=$k=abs($n=$argv[1])); // print bottom
for(
    ;
    $k--;   // $k from abs($n-1) to 0
    $p.=" "                 // create padding
)
{
    $f=$t("  ",$k);         // create front
    $r=$t($k?" ":_,2*$s-1); // create side/roof
    echo"\n$p\\",$n<0
        ?"$f/$r/"   // print, entrance left
        :"$r\\$f/"  // print, entrance right
    ;
}

1

Lote, 289 bytes

@echo off
set/pn=
set u=
for /l %%i in (2,1,%n:-=%)do call set u=_%%u%%_
echo _%u%__%u%_
set l=
set m=%u%/_%u%
if %n% gtr 0 set m=%u%_\%u%
set m=%m:_= %
for /l %%i in (2,1,%n:-=%)do call:l
set m=%m: =_%
:l
echo %l%\%m%/
set l= %l%
if %n% gtr 0 set m=  %m:~0,-2%
set m=%m:~2%

Recebe entrada em STDIN. Começa criando uma sequência de 2*(abs(n)-1)sublinhados. Isso é repetido mais 4 sublinhados adicionais para a base da barraca. O restante da barraca consiste em um recuo (que aumenta em 1 em cada linha), a \, o meio da barraca e a /. O meio da barraca começa como 2*(abs(n)-1)espaços, mais um \ou /mais um espaço (que não posso representar no Markdown), além de outros 2*(abs(n)-1)espaços. Eu reutilizo a sequência de sublinhado e as altero para espaços por conveniência, mas depois altero os espaços de volta para sublinhados para a última linha. Cada linha remove dois espaços de um lado do meio da barraca, embora seja um pouco mais golfista mover os dois espaços para o início da corda primeiro, se necessário.


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.