線上のフラクタル点


12

時々、私が本当に退屈している(本当に退屈している)とき、線分を描き、その上に点を描くのが好きです。

まず、特定のサイズの線分を描画します。これは、Nの値に対して2 ^ Nです。線は、一連の .文字でます。

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

次に、左端にポイントをプロットします。ポイントはX文字ます。

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

次に、パターンに従います。最後にプロットしたポイント(これをAと呼びます)から開始し、ライン上の次のプロットポイント(B)に進みます(必要に応じて折り返します)。次に、に進みますライン(C)上の次のプロットポイントます。次に、この3番目のポイント(C)と既にプロットされている次のポイント(D)の中間に新しいポイントをプロットします。

行を折り返すたびに、「中間」は折り返しの方法で決定されます。新しくプロットされたポイントは、常にCの右側にあります。

次の行が現在の行だったとしましょう。次の2点をプロットする方法を次に示します。この例では、重要な各ポイントに文字でラベルを付けます。

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

次のポイントをプロットする余地はもうありません。隣接する2つのポイントの間に挟まれる必要があるため、N = 4の指定された値の最大深度に達しました。上記のリストの最後の行は「complete 」

チャレンジ

目標は、指定されたNの値に対して完了した行を出力/返す最短のプログラム/名前付き関数を作成することです。上記はN = 4を示しています。

入力

入力は単一の非負整数Nになります。生成された行の長さは2 ^ Nになります。

出力

出力は、長さ2 ^ Nの完成した行で.あり、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

Python 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])

とても簡単です。

Pyth、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


3

GolfScript(61バイト)

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

必要なループ反復回数はA061419のようですが、doループはそれを計算するよりも短くなっています。divmodは、doループ内でcharを保存します。最も無駄に​​感じるのは出力変換ですが、それを改善する方法はわかりません。



2

Java、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ばかりに短縮することが可能cとd。intクラスレベルで定義されたタイプは自動的に0に初期化されます。
— TNT15年

1

Haskell、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が、無限に向かって位置を増やし続けます(たとえば、N = 2の場合X、先頭にあると、位置リストはのようになります[0,4,8,12,16,20,…])。3番目と4番目の要素(cおよびd)を取得し、新しい位置を計算(c+d)/2し、出力リスト用に保持し、位置4(d)の古い位置リストを新しいものとマージして(c+d)/2、繰り返します。(c+d)/2等しいときに停止しcます。最後に0、出力リストにaを追加Xし、指定された位置などにsを出力し.ます。

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

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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.