Catedral do Fractal

22

Dado um número inteiro positivo n >= 1, produza as primeiras nlinhas da seguinte estrutura:

   #
  # #
  ###
 #   #
 # # #
 ## ##
 #####
#     #
#  #  #
# # # #
# ### #
##   ##
## # ##
### ###
#######

A n-ésima linha indexada 1 é a representação binária de n, espelhada sem copiar o último caractere, com #no lugar de 1 e <space>no lugar de 0. Todas as linhas são centralizadas.

Você deve produzir como arte ASCII, mas pode usar qualquer caractere que não seja um espaço em branco no lugar de onde eu uso #no exemplo. O espaço em branco à direita é permitido e uma nova linha à direita é permitida. A saída deve se parecer com o exemplo, e não há espaço em branco extra nem novas linhas de destaque.

Você pode ver as primeiras 1023 linhas da catedral fractal aqui .

Para gerar casos de teste maiores, aqui está uma implementação de referência não destruída em Python

HyperNeutrino
fonte
Boa ideia. Eu não teria imaginado que os números binários produzissem arte tão bonita quanto ascii.
Jonah
@Jonah Thanks :) feliz que você gosta
HyperNeutrino
7
Ambos os links estão apontando para a catedral gerada.
Otávio
@ Otávio: vou corrigir, graças
HyperNeutrino

Respostas:

6

MATL , 10 bytes

:B2&Zv35*c

Experimente online!

Explicação

:      % Implicitly input n. Push range [1 2 ... n]
B      % Convert to binary. Gives a matrix where each row corresponds to
       % a number. Rows have left-padding zeros if needed
2      % Push 2
&Zv    % Symmetrize along sepecified dimension (2nd means horizontally),
       % without repeating the last element
35*    % Multiply by 35 (ASCII code for '#')
c      % Convert to char. Char 0 is shown as space. Implicitly display
Luis Mendo
fonte
1
Gostaria de saber se seria útil adicionar algum tipo de builtin que corresponda à multiplicação por 35 e depois à conversão para char. Parece ser usado muitas vezes
Conor O'Brien
@ ConorO'Brien É usado frequentemente, sim. Mas seria um dois-char built-in, então não haveria nenhum ganho
Luis Mendo
Sem ganho? 35*cé 4 caracteres
Conor O'Brien
@ ConorO'Brien Ah, você quer dizer com 35fixo? Isso parece um pouco específico. Por outro lado, alguns desafios permitem qualquer caractere, por isso pode ser uma boa ideia. Você acha que #é o mais comum?
Luis Mendo
2
Para referência, esse recurso foi implementado (função Zc, com caractere 35, ie #). Obrigado, @ ConorO'Brien!
Luis Mendo
5

05AB1E , 9 bytes

Código:

Lb€û.c0ð:

Usa a codificação 05AB1E . Experimente online!

Explicação:

L              # List [1, .., input]
 b             # Convert each to binary
  €û           # Palindromize each binary number
    .c         # Join the array by newlines and centralize
      0ð:      # Replace zeroes by spaces
Adnan
fonte
4

Gelatina , 12 bytes

RBUz0ZUŒBo⁶Y

Experimente online!

Freira Furada
fonte
1
Eu também tenho que ir, então vou ler os comentários quando voltar. Sinta-se livre para jogar fora de mim.
Leaky Nun
+1 em "fique à vontade para me derrotar" e pela boa resposta.
Magic Octopus Urn
3

Python 2 , 92 bytes

n=input()
for x in range(n):s=bin(2**len(bin(n))/4+x+1)[3:].replace(*'0 ');print s+s[-2::-1]

Experimente online!

No Python 3, s=f'{x+1:0{len(bin(n))-2}b}'.replace(*'0 ')é mais curto, mas int(input())e parens em torno do printargumento aumentam para 95 bytes.

Lynn
fonte
Isso é uma cópia do meu :) (mas o uso inteligente de 2**len(bin(n))/4qualquer maneira)
Erik o Outgolfer
3

JavaScript (ES6), 106 bytes

Usa 1como o caractere que não é um espaço em branco.

f=(n,k=0)=>k++<n?[...Array(32-Math.clz32(n))].reduce((s,_,i)=>(c=k>>i&1||' ')+s+(i?c:''),'')+`
`+f(n,k):''

Demo

Versão alternativa (mesmo tamanho)

Sem Math.clz32():

f=(n,a=[k=i=0])=>n>>i+1?f(n,a,a[++i]=i):k++<n?a.reduce((s,i)=>(c=k>>i&1||' ')+s+(i?c:''),'')+`
`+f(n,a):''
Arnauld
fonte
1
Muito agradável! Primeira vez que vi Math.clz32- nem sabia que existia!
precisa saber é o seguinte
@Birjolaxew Sim, esta é uma adição ao ES6. É útil de vez em quando.
Arnauld
3

Casca , 21 20 18 bytes

Obrigado @Zgarb por jogar fora 2 bytes!

S↑(tfS=↔ΠR" #"←DLḋ

Experimente online!

Ungolfed / Explicação

Para evitar o preenchimento prolongado, isso determina a largura do fractal que é dado como 2*len(bin(N))-1e gera todas as seqüências desse comprimento com os símbolos #,_('_' indica um espaço).

Como o poder cartesiano é gerado em ordem e os números binários também, isso é bom. Tudo o que precisamos fazer para obter o fractal neste momento é filtrar todos os palíndromos e é basicamente isso:

                    -- implicit input N
S↑(                 -- take N from the following list
        ΠR" #"      --   Cartesian power of [" #"] to
                Lḋ  --     number of bits in bin(N)
               D    --     2*
              ←     --     -1
    fS=↔            --   filter out palindromes
   t                --   drop the first line (all spaces)
ბიმო
fonte
1
Ṙ;pode ser justo Re ȯé desnecessário. Boa ideia de resposta!
Zgarb
2

Mathematica, 94 bytes

Column[Row/@Table[s=IntegerDigits[i,2];Join[s,Reverse@Most@s]/.{0->" ",1->"#"},{i,#}],Center]&
J42161217
fonte
2
Eu realmente tenho que ir também ...
J42161217
2

Mathematica, 98 bytes

Riffle[Nest[ArrayFlatten@{{0,#,0},{1,0,1},{1,#,1}}&,{1},⌊Log2@#⌋]~Take~#"#"/. 0->" ","
"]<>""&

Experimente na sandbox Wolfram ! Os e são três bytes cada.

É uma abordagem diferente das outras respostas até agora, usando a natureza fractal do padrão. O passo principal é ArrayFlatten@{{0,#,0},{1,0,1},{1,#,1}}&, que faz as coisas fracamente, melhor explicadas na forma de figura:

                 [    ]
                 [grid]
[    ]           [    ]
[grid]   --->   #      #
[    ]          #[    ]#
                #[grid]#
                #[    ]#

O código repete essa etapa várias vezes para obter pelo menos n linhas e, em seguida, corta as linhas extras e a exibe de maneira adequada.

Não é uma árvore
fonte
2

Gaia , 11 bytes

 #”B¦ₔṫ¦€|ṣ

Experimente online!

Explicação

    ¦ₔ       For each number 1..input:
 #”B          Convert it to base 2 and use space as 0 and # as 1
      ṫ¦     Palindromize each
        €|   Centre the lines
          ṣ  Join with newlines
Gato de negócios
fonte
2

Python 2 , 120 118 107 bytes

obrigado @luismendo, @officialaimm, @ halvard-hummel

def f(l):
 for a in range(1,l+1):print(bin(a)[2:]+bin(a)[-2:1:-1]).replace(*'0 ').center(len(bin(l+1))*2-4)

Experimente online!

wrymug
fonte
2
replace(*'0 ')para 2 bytes
officialaimm
2
107 bytes
Halvard Hummel
2

C # (.NET Core) , 192 178 bytes 168 + 23

obrigado TheLethalCoder pela ajuda.

x=>new int[x].Select((_,z)=>Convert.ToString(z+1,2).PadLeft((int)Math.Log(x,2)+2).Replace('0',' ')).Aggregate((y,z)=>y+"\n"+z+new string(z.Reverse().Skip(1).ToArray()))

Experimente online!

Certeza de que isso pode ser reduzido bastante, provavelmente no preenchimento e reversão da corda.

Dennis.Verweij
fonte
Bem-vindo ao PPCG! No momento, essa resposta é apenas um trecho de código. Pode ser corrigido adicionando a x=>contagem de bytes e observe que você não precisa incluir o ponto e vírgula à direita. Enumerable.Range(1,x).Select(zé mais curto quanto new int[x].Select((_,z)(acho que está correto). Como você está usando o Linq, você deve incluir using System.Linq;na sua contagem de bytes. Você também está usando, Mathpara incluir using System;ou qualificá-lo totalmente. Note-se que este é, em seguida, mais curtonamespace System.Linq{}
TheLethalCoder
Você não precisa incluir ,' 'na PadLeftchamada, pois o espaço é o padrão.
TheLethalCoder
@TheLethalCoder desculpe pelo inconveniente, agora está corrigido.
precisa saber é o seguinte
Não se preocupe +1 de mim É uma resposta nice :)
TheLethalCoder
1

Carvão , 28 bytes

A…·¹NθW⌈θ«Eθ§ #κ↓⸿AEθ÷κ²θ»‖O

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

A…·¹Nθ

Crie uma lista dos primeiros nnúmeros naturais.

W⌈θ«

Repita até que todos os elementos sejam zero.

Eθ§ #κ

Imprima o último dígito binário de cada elemento da lista como um ou #.

↓⸿

Mover para a coluna anterior.

AEθ÷κ²θ

Divida todos os elementos da lista por dois.

»‖O

Depois que a metade esquerda tiver sido desenhada, reflita-a.

Neil
fonte
As versões atuais do carvão vegetal têm MapAssignRight(IntDivide, 2, q);que economiza 3 bytes.
30517 Neil
1

J, 29 bytes

' #'{~(],}.@|.)"1@(#.^:_1)@i.

Experimente online!

explicação

  • i. inteiros até n, a entrada
  • (#.^:_1) convertido em base 2
  • (],}.@|.)linha por linha ( "1faz essa parte), pega o número binário ( ]é a identidade fn) e o cat ( ,) com seu reverso ( |.), onde o inverso é decapitado ( }.).
  • ' #'{~converte 1s e 0s em hashes e espaços.
Jonah
fonte
Você pode usar em #.invvez de #.^:_1.
Conor O'Brien
@ ConorO'Brien, obrigado, não sabia disso.
Jonah
Não é isso por um? Pois n = 1você não imprime nada. De qualquer forma, você pode cortar alguns bytes com algumas alterações como essa ' #'{~(,|.@}:)"1@#:@:>:@i.(se você tiver permissão para desativar um, poderá remover mais 4 bytes). Basicamente, use um gancho porque ele funciona exatamente como um garfo quando o dente esquerdo está ]e use o built-in em #:que o AFAIK é aproximadamente o mesmo que #.inv. Edição: Eu acho que minha resposta é semelhante o suficiente para justificar ser um comentário, deixe-me saber se você acha que deve ser uma resposta própria.
cole
@ cole, obrigado! vou atualizá-lo um pouco mais tarde. Eu pensei que tinha tentado #:e não funcionou, mas devo estar me lembrando errado, porque você está certo disso.
Jonah
@Jonah, você pode ter tentado o 2 #:que só obterá o dígito mais à direita. #:Funções monádicas como #.inv(ou #.&:_1). Isso difere da diádica #:, que fornece apenas quantos dígitos há átomos em seu argumento esquerdo.
cole
1

Próton , 95 bytes

r=>{for i:range(1,r)print(((bin(i)[2to]).rjust(len(bin(r))-2)[to-1,to by-1]).replace('0',' '))}

Experimente online!

Existem bugs demais para não ter colchetes demais ... Preciso corrigir o analisador ...

HyperNeutrino
fonte
1

PHP, 98 97 95 94 + 1 bytes

while($r++<$argn)echo$s=strtr(sprintf("%".-~log($argn,2).b,$r),0," "),substr(strrev("
$s"),1);

Execute como pipe -nRou experimente online . Usa 1como espaço não em branco.

Titus
fonte
desculpe estragá-lo, mas algo está errado aqui. saída para $argn=1e $argn=3não é correcta, e $argné 0-base (especificado foi baseada-1)
Felix Palmen
1
@FelixPalmen corrigido. A incorreta foi causada pela base errada. Obrigado por perceber.
Titus
0

Python 2 , 93 bytes

n=input()
for i in range(n):s=bin(2**n.bit_length()+i+1)[3:].replace(*'0 ');print s+s[-2::-1]

Experimente online!

Erik, o Outgolfer
fonte
0

C (gcc) , 146 108 105 bytes

#define o putchar(33-!(c&(1<<n)))
b;c;p(n){--n?o,p(n),o:o;}f(n){while(n>>++b);while(c++<n)p(b),puts("");}

Experimente online!

Essa é uma função f(n)chamada com o número de linhas n, usando um ponto de exclamação ( !) como caractere que não é um espaço em branco.

Explicação :

#define o putchar(33-!(c&(1<<n)))
b;c;
p(n)
{
    // least significant bit not yet reached?
    --n?
            // print bit twice with recursive step between
            o,
            p(n),
            o
        // for least significant, just print this bit
        :o;
}

// the main "cathedral function":
f(r)
{
    // determine max number of bits to shift
    while(r>>++b);

    // iterate over rows
    while(c++<r)

        // print row recursively
        p(b),

        // newline
        puts("");
}

/**
 * footer, just calling the function
 */
main(int argc, char **argv)
{
    f(atoi(argv[1]));
}
Felix Palmen
fonte
Sugerir em --n&&o+p(n);o;vez de --n?o,p(n),o:o;e em for(;c++<n;puts(""))p(b);vez dewhile(c++<n)p(b),puts("");
tetocat 22/08
0

JavaScript (Node.js) , 156 149 bytes

-7 bytes por @ ConorO'Brien

f=(n,w=n.toString(2).length,b=n.toString(2).replace(/0/g," "),s=" ".repeat(w-b.length))=>`${--n?f(n,w)+s+b+[...b].reverse().join``.substr(1):s+"1"}
`

Experimente online!

Função recursiva. Infelizmente, o JS não suporta a reversão de uma sequência, portanto, 19 bytes são usados ​​para transformá-la em uma matriz e vice-versa.

Birjolaxew
fonte
1
Você pode usar em [...b]vez de b.split(""); você também pode usar em .join``.substr(1)vez de .join("").substr(1); finalmente, acho que você pode usar em s+1vez des+"1"
Conor O'Brien
0

Perl 5 , 77 + 1 (-n) = 78 bytes

$x=1+(log$_)/log 2;map{$_=sprintf"%0${x}b",$_;y/0/ /;say$_.chop.reverse}1..$_

Experimente online!

Usando '1' em vez de '#' porque salva alguns bytes.

Xcali
fonte
0

Stax , 8 bytes

ç▼┼Ö☺ǬÉ

Execute e depure

Resposta mais curta até agora. Usa o código 1 do CP437 no lugar de #.

Equivalente ASCII:

{:B|pm|Cm
Weijun Zhou
fonte