Puntos Fractales en una Línea

12

A veces, cuando estoy realmente aburrido ( realmente aburrido), me gusta dibujar un segmento de línea y dibujar puntos en él.

Primero, dibujo un segmento de línea de cierto tamaño, que es 2 ^ N para algún valor de N. La línea estará representada por una serie de .caracteres.

................

Luego, trazo un punto en el extremo izquierdo. Los puntos serán representados por Xpersonajes.

X...............

Entonces, sigo un patrón. Comenzando en el punto trazado más recientemente (que llamaré A), avanzo al siguiente punto trazado (B) en la línea (ajustando según sea necesario). Luego, avanzo al siguiente punto trazado en la línea (C). Luego, trazo un nuevo punto a medio camino entre este tercer punto (C) y el siguiente punto ya trazado (D).

Cada vez que se ajusta alrededor de la línea, el "centro" se determina de manera envolvente. El punto recién trazado siempre está a la derecha de C.

Digamos que la siguiente línea era mi línea actual. Así es como trazaría los siguientes dos puntos. Para este ejemplo, etiquetaré cada punto importante con una letra.

X...A...X.X...X.
    ^

X...A...B.X...X.
        ^

X...A...B.C...X.
          ^

X...A...B.C...D.
            ^

X...X...X.X.A.X.
            ^

X...X...X.X.A.B.
              ^

C...X...X.X.A.B.
^

C...D...X.X.A.B.
  ^

X.A.X...X.X.X.X.
  ^

Volviendo al ejemplo anterior, el siguiente punto se trazará en el medio de la línea.

X.......X.......

Este es quizás un caso un poco especial: avanzar al siguiente punto simplemente te deja donde comenzaste. El único punto intermedio útil es el punto intermedio "cíclico" (el punto intermedio en la línea), en lugar de trazar un punto encima de sí mismo.

A continuación se muestra la serie de puntos que trazaría en la línea desde aquí hasta el final.

X.......X.......
X.......X...X...
X.......X.X.X...
X...X...X.X.X...
X...X...X.XXX...
X.X.X...X.XXX...
X.X.X...XXXXX...

Ya no hay espacio para trazar el siguiente punto, ya que tendría que estar encajado entre dos puntos adyacentes, por lo que he alcanzado la profundidad máxima para el valor dado de N = 4. La última línea en la lista anterior es "completa ".

El reto

El objetivo es escribir el programa más corto / función con nombre que imprimirá / devolverá la línea completa para un valor dado de N. Lo anterior muestra N = 4.

Entrada

La entrada será un único número entero no negativo N. La longitud de la línea generada será 2 ^ N.

Salida

La salida será la línea completa de longitud 2 ^ N, formada por .y Xcaracteres. Una nueva línea final no importa.

Ejemplo de E / S

0
X

1
XX

2
X.XX

3
X.X.XXX.

4
X.X.X...XXXXX...

5
X.X.X...X...X...X.XXX.XXX.......
PhiNotPi
fuente

Respuestas:

4

Pitón 2, 137

n=input()
l=[0]*2**n;i=0
while~i%2:i=i/2%2**n;l[i]=1;i=sum([k for k,v in enumerate(l*4)if(k>i)*v][1:3])
print''.join(['.X'[x]for x in l])

Bastante sencillo.

Pyth, 49

Más o menos una traducción. La principal diferencia es que no uso una lista que represente la línea, uso una cadena.

J*\.^2QW!%Z2K%/Z2lJ=JXJK\X=Zs<tf&q\X@JT>TKU*4J2)J

Pruébalo en línea .

                         Q=input(); Z=0 #implicit
J*\.^2Q                  J = "."*(2^Q)
W!%Z2                    while !(Z%2):
  K%/Z2lJ                  K=(Z/2)%(len(J))
  =JXJK\X                  change J, the point at index K is changed to a "X"
       f          U*4J     filter all elements T in [0, 1, 2, ..., 4*len(J)-1]:
        &q\X@JT>TK           where J[T]=='X' and T>K
     <t               2    only us the second and third element
  =Zs                      and store the sum to Z
)J                       end while and print J
Jakube
fuente
4

Clip , 95

[z?zF#2(z*2*:(#2(z'.'X]'X]]n[Fa[b[q[j[r?=rirFrsrb'X]b]][t[u+*<ut*Blb/+tu2]]g+2jqg+3jq]#qa]%b'X}
Ypnypn
fuente
3

GolfScript (61 bytes)

~2\?,[]0{.@|$4*.@?2+1$>2<.+~<!4$,*++.2/\1&!}do;`{&!'X.'1/=}+%

El número de iteraciones de bucle requeridas parece ser A061419 , pero el bucle Do es más corto que calcularlo. Un divmod guardaría un char dentro del bucle do. La parte que se siente más derrochadora es la conversión de salida, pero no veo cómo mejorarla.

Peter Taylor
fuente
2

Java, 209 207 195 191 bytes

Me sorprende que haya podido hacerlo tan corto. Probablemente todavía hay margen de mejora. Como de costumbre, las sugerencias serán apreciadas :)

Esto devuelve a char[]. Llamar usando a(n).

char[]a;int b,c,d,e=2;char[]a(int f){java.util.Arrays.fill(a=new char[b=1<<f],'.');for(a[0]=88;d+1<e;c=(d+e)/2,a[c%b]=88)e=b(d=b(b(c)));return a;}int b(int f){for(;;)if(a[++f%b]>87)return f;}

Sangrado:

char[] a;
int b, c, d, e = 2;

char[] a(int f){
    java.util.Arrays.fill(
            a = new char[
                    b = 1 << f
                    ]
            , '.'
    );
    for(
            a[0] = 88;
            d + 1 < e;
                c = (d + e) / 2,
                a[c % b] = 88
        )
        e = b(
                d = b(
                        b(c)
                )
        );
    return a;
}

int b(int f){
    for (;;)
        if (a[++f % b] > 87)
            return f;
}

12 bytes gracias a Peter :)
4 bytes gracias a TNT;)

El numero uno
fuente
(c%b+b)%b? ¿Esperas cser negativo?
Peter Taylor
c=0y d=0se puede acortar a justo cy d. intlos tipos definidos en el nivel de clase se inicializan automáticamente a 0.
TNT
1

Haskell, 182 bytes

(a:b)%(c:d)|a<c=a:b%(c:d)|1<2=c:(a:b)%d
f i=putStr$map(!(0:g[0,n..]))[0..n-1]where n=2^i;e!l|e`elem`l='X'|1<2='.';g(_:_:c:d:r)|m==c=[]|1<2=mod m n:g((d:r)%[m,m+n..])where m=div(c+d)2

Uso: f 5. Salida: X.X.X...X...X...X.XXX.XXX........

Desafortunadamente, Haskell no tiene una función de fusión en las bibliotecas estándar, por lo que tengo que proporcionar la mía (-> %). Afortunadamente, tengo que fusionar solo listas infinitas, por lo que no tengo que cubrir los casos base, es decir, listas vacías. Todavía cuesta 40 bytes.

Cómo funciona: en lugar de configurar los Xs directamente en una matriz, mantengo una lista de posiciones donde están. Además, no me doy vuelta, 2^Npero sigo aumentando las posiciones hacia el infinito (por ejemplo, para N = 2 con un Xen la parte delantera, la lista de posiciones se ve así [0,4,8,12,16,20,…]). Tomo el tercer y cuarto elemento ( cy d), calculo la nueva posición (c+d)/2, la guardo para la lista de salida, fusiono la lista de posición anterior de la posición 4 (la d) con una nueva que comienza (c+d)/2y se repite. Me detengo cuando (c+d)/2es igual c. Finalmente agrego un 0a la lista de salida e imprimo Xs en las posiciones dadas y en .otros lugares.

step by step example, N=2

step  position list       (c+d)/2  output     lists to merge (pos. list for next round)
                                   list       old list from d on / new list from (c+d)/2

  #1  [0,4,8,12,16,…]       10     [10]          [12,16,20,24,…] / [10,14,18,22,…]
  #2  [10,12,14,16,18,…]    15     [10,15]       [16,18,20,22,…] / [15,19,23,27,…]
  #3  [15,16,18,19,20,…]    18

stop here, because c equals (c+d)/2

add 0 to the output list: [0,10,15]
take all elements modulo 2^N: [0,2,3]
print X at position 0, 2 and 3 
nimi
fuente
1

Mathematica, 110 102 112 108

a=Array["."&,n=2^Input[]];a[[Mod[Round@{n/2,n}//.{x_,y_,z___}/;y-x>1:>{z,x+n,(x+y)/2+n,y+n},n]+1]]="X";""<>a
alephalpha
fuente