二分木フラクタル


25

今日の課題は、この例のような美しいとしてバイナリツリーを描くことです。

                               /\
                              /  \
                             /    \
                            /      \
                           /        \
                          /          \
                         /            \
                        /              \
                       /                \
                      /                  \
                     /                    \
                    /                      \
                   /                        \
                  /                          \
                 /                            \
                /                              \
               /\                              /\
              /  \                            /  \
             /    \                          /    \
            /      \                        /      \
           /        \                      /        \
          /          \                    /          \
         /            \                  /            \
        /              \                /              \
       /\              /\              /\              /\
      /  \            /  \            /  \            /  \
     /    \          /    \          /    \          /    \
    /      \        /      \        /      \        /      \
   /\      /\      /\      /\      /\      /\      /\      /\
  /  \    /  \    /  \    /  \    /  \    /  \    /  \    /  \
 /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\

入力として正の整数が与えられます。この入力はツリー高さです。上記の例の高さは6です。

フルプログラムまたは関数のいずれかを送信できますデフォルトのIOメソッドは自由に使用できます。たとえば、ツリーを印刷する、改行を含む文字列を返す、2d char配列を返す、ツリーをファイルに保存するなどはすべて許可されます。

各行の末尾のスペースは許可されます。

入力とそれに対応する出力の例を次に示します。

1:
/\

2:
 /\
/\/\

3:
   /\
  /  \
 /\  /\
/\/\/\/\

4:
       /\
      /  \
     /    \
    /      \
   /\      /\
  /  \    /  \
 /\  /\  /\  /\
/\/\/\/\/\/\/\/\

5:
               /\
              /  \
             /    \
            /      \
           /        \
          /          \
         /            \
        /              \
       /\              /\
      /  \            /  \
     /    \          /    \
    /      \        /      \
   /\      /\      /\      /\
  /  \    /  \    /  \    /  \
 /\  /\  /\  /\  /\  /\  /\  /\
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\

残念ながら、出力は指数関数的に増加するため、より大きな例を表示することは困難です。8の出力へのリンクを次に示します。

いつものように、これは挑戦なので、標準の抜け穴が適用され、選択した言語で可能な限り最短のプログラムを作成しようとします。

ハッピーゴルフ!


すべての行を同じ長さにするために、末尾にスペースを入れることはできますか?
-xnor

@xnorはい、それで問題ありません。
DJMcMayhem

回答:


5

Python 2、77バイト

S=s=i=2**input()
while s:print S/s*('/'+' '*(s-i)+'\\').center(s);i-=2;s/=s/i

末尾にスペースを入れて印刷し、エラーで終了します。

このコードを提出からAnarchy Golf提起した課題に加えて、xsotによって1バイト改善されました。ハードコードされた128の値はに変更されました2**input()

これは、出力の各行が1回以上コピーされたセグメントであるという考え方です。入力分割後の半分には各セグメントのコピーが1つあり、次の分割後の四半期には2つのコピーがあり/\ます。

各セグメントは持っていた/\、中間、ならびに右長さにパッドに外側にスペースを含みます。外側のパディングはで行われcenterます。

変数sは各セグメントの現在のwithを追跡し、セグメントの数はS/s合計幅がツリー幅になるようにしSます。行番号iは2 sずつカウントダウンし、値が半分になると、分割が発生し、セグメント幅が半分になります。これは、式を介して行われますs/=s/i。にi達する0と、プログラムを終了するエラーが発生します。

アナゴルフはプログラムの提出のみを許可するため、再帰関数の可能性については調査しませんでした。



4

Canvas、11 バイト

/║╶╷[l\;∔↔║

ここで試してみてください!

説明:

/║          push `/\` ("/" palindromized so this is a Canvas object)
  ╶╷[       repeat input-1 times
     l        get the width of the ToS
      \       create a diagonal that long
       ;∔     prepend that to the item below
         ↔    reverse the thing horizontally
          ║   and palindromize it horizontally

3

ハスケル140の138 135バイト

e n=[1..n]>>" "
n!f=(e n++).(++e n)<$>f
f 0=[]
f n=1!f(n-1)++['/':e(2*n-2)++"\\"]
b n|n<2=f 1|t<-b$n-1,m<-2^(n-2)=m!f m++zipWith(++)t t

オンラインでお試しください!で呼び出すとb 5、文字列のリストが返されます。

プリティプリントの使用:

*Main> putStr . unlines $ b 5
               /\
              /  \
             /    \
            /      \
           /        \
          /          \
         /            \
        /              \
       /\              /\
      /  \            /  \
     /    \          /    \
    /      \        /      \
   /\      /\      /\      /\
  /  \    /  \    /  \    /  \
 /\  /\  /\  /\  /\  /\  /\  /\
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\

(一部)説明:

  • e nnスペースの文字列を生成します
  • n!f文字列のリストの各文字列を左右にスペースfn埋めます
  • f nnby 2n長方形に「ピーク」を描画します
  • b n 2つの小さなツリーを連結してバイナリツリーを描画し、それらの上の新しいピークを中央に配置します

編集:Zgarbのおかげで-3バイト!


私が考える1!f(n-1)m!f mバイトのカップルを保存する必要があります。
ズガルブ

@Zgarb指摘してくれてありがとう、これらの優先ルールは時々混乱するようになります。
ライコニ

2

J49 43 42バイト

' /\'{~(|.,-)"1@(=@i.@#,-)^:(<:`(,:@,&*-))

これは、数値を取得して2D文字配列を返す動詞に評価されます。 オンラインでお試しください!

説明

まず、補助動詞を繰り返して値-1、0、1のマトリックスを作成し、次に数字を文字で置き換えます。補助動詞は次の反復の右半分を構成し、それを水平にミラーリングして残りを生成します。以下の説明では、,2D配列を垂直に連結し、1D配列を水平に連結します。

' /\'{~(|.,-)"1@(=@i.@#,-)^:(<:`(,:@,&*-))  Input is n.
                          ^:(            )  Iterate this verb
                             <:             n-1 times
                               `(       )   starting from
                                    ,&*-    the array 1 -1 (actually sign(n), sign(-n))
                                 ,:@        shaped into a 1x2 matrix:
                                             Previous iteration is y.
                      #                      Take height of y,
                   i.@                       turn into range
                 =@                          and form array of self-equality.
                                             This results in the identity
                                             matrix with same height as y.
                       ,-                    Concatenate with -y, pad with 0s.
       (    )"1@(        )                   Then do to every row:
        |.,-                                 Concatenate reversal to negation.
' /\'{~                                     Finally index entry-wise into string.

1

JavaScript(ES6)、105バイト

f=n=>n<2?"/\\":" "+f(n-1).split`/`[0].replace(/|/g,"$`$'$'/$`$`\\$'$'$` \n")+f(n-1).replace(/.*/g,"$&$&")

ベースケースから再帰的に結果を構築することで動作し/\ます。下半分は、各行が複製された前のケースです。上半分は少し複雑でした。前のケースを取り、両側のみを保持するように見えますが、文字列の幅を2倍にすることも心配する必要があるため、代わりに正規表現の魔法を使用します。前のケースから先頭のスペースを取り、各ポイントで分割することにより、そのポイントの前後のスペースを考慮することができます。一致するたびに、1ずつ増加する前のスペースと1ずつ減少した後のスペース。これを使用して/\正しい場所に。改行とパディングもここに追加されます。これにより、各行の末尾のスペースと、手動で追加する必要がある最初の行の先頭のスペースを除いて、すべてのパディングが処理されます。(後続の行の先頭のスペースは、一致した文字列に由来します)。


1

、12バイト

FN«→↗⌈X²⊖ι‖M

オンラインでお試しください!リンクは、コードの詳細バージョンです。説明:

 N              Input as a number
F «             Loop over implicit range
   →            Move right (because mirroring moves the cursor)
         ι      Current index
        ⊖       Decremented
      X²        Power of 2
     ⌈          Ceiling
    ↗           Draw diagonal line
          ‖M    Mirror image

行の長さは1、1、2、4、8 ... 2 ^(N-2)であるため、厄介な計算になります。



0

バッチ、218バイト

@echo off
set/a"n=1<<%1"
set s=set t=
%s%/\
set l=for /l %%i in (2,1,%n%)do call
%l% %s% %%t%% 
%l%:l
:l
echo %t%
set/an-=1,m=n^&n-1
%s%%t: /=/ %
%s%%t:\ = \%
if %m% neq 0 exit/b
%s%%t:/ =/\%
%s%%t: \=/\%

注:6行目はスペースで終わります。ブランチを毎回適切に左右に移動することにより機能します。ただし、最後から2 nの行を除きます。この場合、ブランチは代わりにフォークされます。


0

Haxe、181バイト

function g(n):String return(n-=2)==-1?"/\\":[for(y in 0...1<<n)[for(x in 0...4<<n)x+y+1==2<<n?"/":x-y==2<<n?"\\":" "].join("")].concat([for(y in g(n+1).split("\n"))y+y]).join("\n");

または、オプションの空白を使用して:

function g(n):String
  return
    (n -= 2) == -1
    ? "/\\"
    : [ for (y in 0...1 << n)
        [ for (x in 0...4 << n)
          x + y + 1 == 2 << n
          ? "/"
          : x - y == 2 << n
            ? "\\"
            : " "
        ].join("")
      ].concat([ for (y in g(n + 1).split("\n"))
        y + y
      ]).join("\n");

私はしばらくの間、適切なサイズのスペース文字の配列を最初に作成し、次に分岐したパスを繰り返し(そして各反復でより密に)配置するソリューションに取り組んでいました。ただし、230バイト以上のままでした。ここでのアプローチは、@ LaikoniのHaskellアプローチとほぼ同じです。:StringHaxeは、戻り値の型が常にStringであることを識別するのに十分なほどスマートではないため、持っていないことで逃げることができませんでした。

これは関数のみです。テストするための完全なプログラムは次のとおりです。

class Main {
    public static function main(){
        function g(n):String return(n-=2)==-1?"/\\":[for(y in 0...1<<n)[for(x in 0...4<<n)x+y+1==2<<n?"/":x-y==2<<n?"\\":" "].join("")].concat([for(y in g(n+1).split("\n"))y+y]).join("\n");
        Sys.println(g(Std.parseInt(Sys.args()[0])));
    }
}

上記をMain.hxでコンパイルしhaxe -main Main.hx -neko frac.n、テストしますneko frac.n 44目的の順序に置き換えます)。


0

PHP、188バイト

オンライン版

function f($l,$r=0,$m=1){global$a;for(;$i<$l;$i++)$i<$l/2?$a[$i+$r]=str_repeat(str_pad("/".str_pad("",2*$i)."\\",2*$l," ",2),$m):f($l/2^0,$r+$l/2,2*$m);}f(2**$argv[1]/2);echo join("\n",$a);

拡大

function f($l,$r=0,$m=1){
global$a;    
for(;$i<$l;$i++)    
$i<$l/2
    ?$a[$i+$r]=str_repeat(str_pad("/".str_pad("",2*$i)."\\",2*$l," ",2),$m)
    :f($l/2^0,$r+$l/2,2*$m);
}
f(2**$argv[1]/2);
echo join("\n",$a);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.