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


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

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


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.


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):''

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)

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]&

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.


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


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.


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.


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.

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 ...



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.


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

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]));
}

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.


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.


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.