선상의 프랙탈 포인트


12

정말 (지루있을 때 가끔, 정말 지루), I는 선분을 그리고 그 위에 점을 그리는 것을 좋아합니다.

먼저, 특정 크기의 선분을 그립니다. N의 값은 2 ^ N입니다. 선은 일련의 .문자 로 표시됩니다 .

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

그런 다음 왼쪽 끝에 점을 그립니다. 포인트는 X문자 로 표시됩니다 .

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

그런 다음 패턴을 따릅니다. 가장 최근에 플롯 된 지점 (A라고 부름)에서 시작하여 라인에서 다음 플롯 지점 (B)으로 이동합니다 (필요에 따라 줄 바꿈). 그런 다음 선 (C) 에서 다음 플롯 포인트로 이동합니다. 그런 다음이 세 번째 점 (C)과 다음에 이미 표시된 점 (D) 사이의 중간에 새 점을 플로팅합니다.

줄을 감쌀 때마다 "중간"이 줄 바꿈 방식으로 결정됩니다. 새로 그려진 점은 항상 C의 오른쪽에 있습니다.

다음 줄이 현재 줄이라고 가정 해 봅시다. 다음 두 점을 그리는 방법은 다음과 같습니다. 이 예에서는 각 중요한 점에 문자를 표시합니다.

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

이전 예제로 돌아 가면 다음 점이 선의 중간에 그려집니다.

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

이것은 아마도 특별한 경우 일 것입니다. 다음 단계로 넘어 가면 시작한 곳을 떠나게됩니다. 유일하게 유용한 중간 지점은 "순환"중간 지점 (선의 중간 지점)이며 그 위에 점을 플로팅하는 것과는 반대입니다.

아래는 여기서 끝까지 선에 그리는 일련의 점입니다.

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

인접한 두 점 사이에 끼워 져야하므로 다음 점을 그릴 공간이 더 이상 없으므로 주어진 값 N = 4의 최대 깊이에 도달했습니다. 위 목록의 마지막 줄은 "완료"입니다. "

도전

목표는 주어진 N 값에 대해 완성 된 줄을 인쇄 / 반환하는 가장 짧은 프로그램 / 명명 된 함수를 작성하는 것입니다. 위의 내용은 N = 4입니다.

입력

입력은 음이 아닌 단일 정수 N이됩니다. 생성 된 라인의 길이는 2 ^ N입니다.

산출

출력에 의해 형성된 길이 ^ N (2)의 완성 라인 것 .X캐릭터. 후행 줄 바꿈은 중요하지 않습니다.

예제 I / O

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

답변:


4

파이썬 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])

아주 간단합니다.

피시스, 49

다소의 번역. 주요 차이점은 줄을 나타내는 목록을 사용하지 않고 문자열을 사용한다는 것입니다.

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

온라인으로 사용해보십시오 .

                         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

4

클립 , 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}

3

GolfScript (61 바이트)

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

필요한 루프 반복 횟수는 A061419 인 것처럼 보이지만 do-loop는이를 계산하는 것보다 짧습니다. divmod는 do 루프 안에 문자를 저장합니다. 가장 낭비되는 부분은 출력 변환이지만 개선 방법을 모르겠습니다.



2

자바, 209 207 195 191 바이트

나는 이것을 짧게 얻을 수 있다는 것에 놀랐다. 여전히 개선의 여지가있을 것입니다. 평소와 같이 제안을 부탁드립니다. :)

이것은를 반환합니다 char[]. 을 사용하여 전화하십시오 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;}

들여 쓰기 :

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

Peter 덕분에 12 바이트 :)
TNT 덕분에 4 바이트;)


(c%b+b)%b? 당신은 c부정적인 것으로 기대하고 있습니까?
피터 테일러

c=0그리고 d=0단지에 단축 할 수 cd. int클래스 수준에서 정의 된 유형은 자동으로 0으로 초기화됩니다.
TNT

1

하스켈, 182 바이트

(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

사용법 : f 5. 출력 : X.X.X...X...X...X.XXX.XXX........

불행히도 Haskell은 표준 라이브러리에 병합 기능이 없으므로 내 (-> %) 를 제공해야합니다 . 다행히도 무한 목록 만 병합해야하므로 기본 사례 (예 : 빈 목록)를 다루지 않아도됩니다. 여전히 40 바이트입니다.

작동 방식 : X배열에서 s를 직접 설정하는 대신 위치를 목록으로 유지합니다. 또한 나는 감싸지 않고 2^N무한대로 향한 위치를 계속 증가시킵니다 (예 : X앞면 에 N = 2 인 경우 위치 목록은 다음과 같습니다 [0,4,8,12,16,20,…]). 3 번째 및 4 번째 요소 ( cd)를 가져 와서 새 위치를 계산하고 (c+d)/2출력 목록을 위해 유지하고 위치 4의 이전 위치 목록 ( d)을 새 위치로 병합 (c+d)/2하고 반복합니다. (c+d)/2같을 때 나는 멈춘다 c. 마지막으로 0출력 목록 에 a 를 추가 X하고 주어진 위치와 .다른 곳에을 인쇄 합니다.

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 

1

매쓰, 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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.