Catedral del fractal


22

Dado un entero positivo n >= 1, genera las primeras nfilas de la siguiente estructura:

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

La nenésima fila indexada es la representación binaria de n, reflejada sin copiar el último carácter, #en lugar de 1 y <space>en lugar de 0. Todas las filas están centradas.

Debe mostrar como ASCII-art, pero puede usar cualquier carácter que no sea un espacio en blanco en lugar de donde lo uso #en el ejemplo. Se permite el espacio en blanco al final y se permite una nueva línea al final. El resultado debe parecerse al ejemplo, y no debe haber espacios en blanco iniciales ni líneas nuevas.

Puedes ver las primeras 1023 filas de la catedral fractal aquí .

Para generar casos de prueba más grandes, aquí hay una implementación de referencia no protegida en Python


Buena idea. No habría adivinado los números binarios para haber producido un arte tan bonito.
Jonás

@ Jonás Gracias :) Me alegro de que te guste
HyperNeutrino

77
Ambos enlaces apuntan a la catedral generada.
Otávio

@ Otávio: lo arreglaré, gracias
HyperNeutrino

Respuestas:


6

MATL , 10 bytes

:B2&Zv35*c

Pruébalo en línea!

Explicación

:      % 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
Me pregunto si sería útil agregar algún tipo de construcción que corresponda a multiplicar por 35 y luego convertir a char. Parece que se usa a menudo
Conor O'Brien

@ ConorO'Brien Se usa a menudo, sí. Pero sería un dos personajes incorporados, por lo que no habría ganancia
Luis Mendo

¿Sin ganancias? 35*cson 4 personajes
Conor O'Brien

@ ConorO'Brien Ah, ¿quieres decir con 35fijo? Eso parece un poco específico. Por otro lado, algunos desafíos permiten cualquier char, por lo que puede ser una buena idea. ¿Crees que #es el más común?
Luis Mendo

2
Como referencia, esta característica se ha implementado (función Zc, con carácter 35, es decir #). Gracias, @ ConorO'Brien!
Luis Mendo

5

05AB1E , 9 bytes

Código:

Lb€û.c0ð:

Utiliza la codificación 05AB1E . Pruébalo en línea!

Explicación:

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]

Pruébalo en línea!

En Python 3, s=f'{x+1:0{len(bin(n))-2}b}'.replace(*'0 ')es más corto, pero los int(input())parens alrededor del printargumento lo empujan hasta 95 bytes.


Esa es una copia mía :) (pero uso inteligente de 2**len(bin(n))/4todos modos)
Erik the Outgolfer

3

JavaScript (ES6), 106 bytes

Se utiliza 1como carácter que no es un espacio en blanco.

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

Manifestación

Versión alternativa (mismo tamaño)

Sin 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
¡Muy agradable! La primera vez que lo vi Math.clz32, ¡ni siquiera sabía que existía!
Birjolaxew

@ Birjolaxew Sí, esta es una adición de ES6. Es útil de vez en cuando.
Arnauld

3

Casco , 21 20 18 bytes

¡Gracias @ Zgarb por jugar 2 bytes!

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

Pruébalo en línea!

Ungolfed / Explicación

Para evitar rellenos largos, esto determina el ancho del fractal que se da como 2*len(bin(N))-1y genera todas las secuencias de esa longitud con los símbolos #,_('_' denota un espacio).

Como el poder cartesiano se genera en orden y los números binarios también, esto está bien. Todo lo que necesitamos hacer para obtener el fractal en este punto es filtrar todos los palíndromos y eso es básicamente:

                    -- 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
Ṙ;puede ser justo Ry ȯes innecesario. Buena idea de respuesta!
Zgarb

2

Mathematica, 94 bytes

Column[Row/@Table[s=IntegerDigits[i,2];Join[s,Reverse@Most@s]/.{0->" ",1->"#"},{i,#}],Center]&

2
Realmente tengo que irme también ...
J42161217

2

Mathematica, 98 bytes

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

¡Pruébalo en el sandbox de Wolfram ! El y son tres bytes cada uno.

Es un enfoque diferente de las otras respuestas hasta ahora, utilizando la naturaleza fractal del patrón. El paso clave es ArrayFlatten@{{0,#,0},{1,0,1},{1,#,1}}&, que hace las cosas fractales, mejor explicado en forma de imagen:

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

El código repite este paso suficientes veces para obtener al menos n filas, luego recorta las filas adicionales y lo muestra muy bien.


2

Gaia , 11 bytes

 #”B¦ₔṫ¦€|ṣ

Pruébalo en línea!

Explicación

    ¦ₔ       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

gracias TheLethalCoder por la ayuda.

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()))

Pruébalo en línea!

bastante seguro de que esto puede reducirse mucho, muy probablemente en el relleno y la inversión de la cadena.


Bienvenido a PPCG! Por el momento, esta respuesta es solo un fragmento de código. Se puede solucionar agregando el x=>conteo de bytes y tenga en cuenta que no necesita incluir el punto y coma final. Enumerable.Range(1,x).Select(zes más corto como new int[x].Select((_,z)(creo que es correcto). Como está utilizando Linq, debe incluirlo using System.Linq;en su recuento de bytes. También lo está utilizando, Mathpor lo que debe incluirlo using System;o calificarlo por completo. Tenga en cuenta que esto es más corto comonamespace System.Linq{}
TheLethalCoder

No necesita incluir ,' 'en la PadLeftllamada ya que un espacio es el predeterminado.
TheLethalCoder


@TheLethalCoder disculpe las molestias, ahora está solucionado.
Dennis.Verweij

No te preocupes +1 de mi parte, es una buena respuesta :)
TheLethalCoder

1

Carbón , 28 bytes

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

Pruébalo en línea! El enlace es a la versión detallada del código. Explicación:

A…·¹Nθ

Crea una lista de los primeros nnúmeros naturales.

W⌈θ«

Repita hasta que todos los elementos sean cero.

Eθ§ #κ

Imprima el último dígito binario de cada elemento de la lista como a o #.

↓⸿

Moverse a la columna anterior.

AEθ÷κ²θ

Divide todos los elementos de la lista por dos.

»‖O

Una vez que se ha dibujado la mitad izquierda, reflexione.


Las versiones actuales de Charcoal tienen MapAssignRight(IntDivide, 2, q);que ahorra 3 bytes.
Neil

1

J, 29 bytes

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

Pruébalo en línea!

explicación

  • i. enteros hasta n, la entrada
  • (#.^:_1) convertido a base 2
  • (],}.@|.) fila por fila ("1 hace esa parte), tome el número binario ( ]es la identidad fn) y catéelo ( ,) con su reverso ( |.), donde se decapita el reverso (}. ).
  • ' #'{~convierte el 1sy0 S para hashes y espacios.

Puedes usar en #.invlugar de #.^:_1.
Conor O'Brien

@ ConorO'Brien, gracias, no estaba al tanto de eso.
Jonás

¿No es esto uno? Porque n = 1no imprimes nada. De todos modos, puede eliminar algunos bytes con algunos cambios como este ' #'{~(,|.@}:)"1@#:@:>:@i.(si uno puede desactivarlo, puede eliminar 4 bytes más). Básicamente, use un gancho porque funciona exactamente como una horquilla cuando el diente izquierdo es ]y use el incorporado en el #:que AFAIK es casi igual #.inv. EDITAR: Creo que mi respuesta es lo suficientemente similar como para justificar ser un comentario, avíseme si cree que debería ser una respuesta propia.
cole

@cole, gracias! Lo actualizaré un poco más tarde. Pensé que lo había intentado #:y no funcionó, pero debo estar recordando mal porque tienes razón en eso.
Jonás

@Jonah, es posible que hayas probado 2 #:lo que solo obtendrá el dígito más a la derecha. #:Funciones monádicas como #.inv(o #.&:_1). Esto difiere de diádico #:, que solo da tantos dígitos como átomos en su argumento izquierdo.
cole

1

Protón , 95 bytes

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

Pruébalo en línea!

Hay demasiados errores para no tener demasiados corchetes ... Necesito arreglar el analizador ...



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

Ejecutar como tubería con -nRo probarlo en línea . Usos 1como no espacios en blanco.


lamento estropearlo, pero algo está mal aquí. salida para $argn=1y $argn=3no es correcta, y $argnestá basada en 0 (especificada en base 1)
Felix Palmen

1
@FelixPalmen arreglado. La incorrección fue causada por la base incorrecta. Gracias por notarlo.
Tito




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("");}

Pruébalo en línea!

Esta es una función f(n)llamada con el número de filas n, usando un signo de exclamación ( !) como carácter que no es un espacio en blanco.

Explicacion :

#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 en --n&&o+p(n);o;lugar de --n?o,p(n),o:o;y en for(;c++<n;puts(""))p(b);lugar dewhile(c++<n)p(b),puts("");
ceilingcat

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"}
`

Pruébalo en línea!

Función recursiva. Desafortunadamente, JS no admite la inversión de una cadena, por lo que se utilizan 19 bytes para convertirla en una matriz y viceversa.


1
Puedes usar en [...b]lugar de b.split(""); también puedes usar en .join``.substr(1)lugar de .join("").substr(1); finalmente, creo que puedes usar en s+1lugar 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..$_

Pruébalo en línea!

Usando '1' en lugar de '#' porque ahorra un par de bytes.


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.