アスタリスクバイラル


9

正の整数N(「バイラリティ」)が与えられると、プログラムは、長さNの 2つのブランチが左上隅から下向きまたは右向きに伸びる、ASCIIアートのツリーの描画を作成する必要があります。

最初のアスタリスクの後に各ブランチが取る方向は、右向きでも下向きでもかまいません。この選択は、次のステップごとにランダムに1にする必要があります。

たとえば、入力が5の場合、出力は次のようになります。

***
* ***
**
 **

2つのブランチは(隣接するセル上にある)タッチすることはできますが、(同じセル上にある)オーバーラップすることはできないため、以下は許可されません。

***
* *
*****
  *
  *

inputの1場合、可能な出力は次のとおりです。

**
*

(これは、2つのブランチが同じパスをたどるとオーバーラップするため、すべての有効な出力に存在します。)

入力の可能な出力は3次のとおりです。

***
* *
**
**
***
*
*

入力用7

****
*  **
*   **
*
***
  *

入力用10

****
*  *      
*********
  *
  *****

これはなので、有効な最短の回答(バイト単位)が優先されます。

1.これは均一にランダム(つまり、各方向の50/50の確率)、または通常のハードウェアで取得できる限り均一にランダムでなければなりません。


私の長い投稿の利用で問題が発生した場合はコメントしてください-多分私は何かを短くすることができます(私はそれから試します)。
nicael

3
ただそれを期待することを学んでください。時々それはすべてのように忙しいです。また、今のように静かな場合もあります。イースターでもあります。
ザカリー

私の投稿の何が悪いのか本当にわかりません。反対票を投じた人は説明してくれませんか?
nicael

1
IMO Nは時間としてより適切に説明されています:P
ASCIIのみ

1
スペースとアスタリスクの代わりに0sと1sの行列を返すことはできますか?
ディルナン

回答:


5

CJam58 51バイト

[TT]{_2_m*\f.+{:-},mR}ri*]ee{~\)S*\{'*t}/}%::a:.+N*

オンラインでお試しください!

基本的な考え方は、最初[0 0]に各要素に0または1のいずれかを繰り返し追加し(重複を避けるために、最初以外は等しくないことを確認して)すべての中間結果を収集することです。

[[0 0] [0 1] [0 2] [0 2] [1 3]]

次に、各サブ配列が*元の配列の対応するペアによって指定されたインデックスに含まれ、他のすべての場所にスペースがある配列の大きな配列を作成します。

["*"
 "**"
 "* *"
 "* * "
 " * * "]

これにより、出力行列の対角スライスが生成されます(左から右に移動すると、実際の行列の右上から左下に移動します)。

次に、を使用::a:.+して「非対角化」し、結果の行を取得できます。

[ "**** "
  "*  *"
  "** "
  " *"
  ""     ]

3

チャコール31 24バイト

F²«J⁰¦⁰F⊕θ«¿ι*↓*≔‽²ι¿KK↗

オンラインでお試しください!リンクはコードの詳細バージョンです。元々、最初のステップをランダムにする方が簡単だと思っていましたが、最初の分岐を予測可能にするのはゴルファーであることがわかりました。説明:

F²«

インデックス変数を使用して2回ループしますi。(これは実際には暗黙のリストを反復処理するためi、ループ内で変更しても安全です。)

J⁰¦⁰

キャンバスの原点にジャンプします。

F⊕θ«

ループN+1時間。

¿ι*↓*

を印刷*しますが、の値に応じて、カーソルをカーソルの右または下に残しますi

‽²ι

i内部ループの次の反復の値をランダム化します。

¿KK↗

現在の文字がである場合*、これは2番目の分岐であり、右ではなく下に移動したことを意味します。右に移動して修正します。(最初のブランチは常に下向きに開始するため、2番目のブランチは常にその上にあります。つまり、垂直方向の衝突のみをチェックする必要があります。)


それはほぼ正しいですが、Nサイズのブラン​​チではなく、サイズの印刷N-1:)
nicael

@nicael申し訳ありませんが、修正されました。
ニール、

おそらくこれは何度も見たことがあるでしょうが、23バイト
ASCIIのみ

3

Java 10、273 272 268 239バイト

n->{var c=new char[++n][n];for(var d:c)java.util.Arrays.fill(d,' ');for(int i=0,j=0,k=0,l=0,r=0,s=0,t=0,u=0;n-->0;){c[i+=r][j+=s]=c[k+=t][l+=u]=42;do{r=t=2;r*=Math.random();t*=Math.random();s=r^1;u=t^1;}while(i+r==k+t&j+s==l+u);}return c;}

こちらからオンラインでお試しください。

29バイトのゴルフをしてくれたKevin Cruijssenに感謝します。

ゴルフされていないバージョン:

n -> { // lambda taking an int as argument
    var c = new char[++n][n]; // the output; increment the virality since the root does not count
    for(var d : c) // for every line
        java.util.Arrays.fill(d,' '); // initialize it with spaces
    for(int i = 0, j = 0, // coordinates of the first branch
            k = 0, l = 0, // coordinates of the second branch
            r = 0, s = 0, // offsets for the first branch, one will be 0 and the other 1 always except for the first '*' where the two branches overlap
            t = 0, u = 0; // offsets for the second branch, one will be 0 and the other 1 always except for the first '*' where the two branches overlap
        n-- > 0; ) { // decrement virality and repeat as many times
        c[i+=r][j+=s] = c[k+=t][l+=u] = 42; // move according to offsets and place an '*' for each branch, 42 is ASCII code
        do { // randomly pick offsets for both branches
            r = t = 2; // Math.random() provides results in [0,1)
            r *= Math.random(); // flip a coin for the first branch
            t *= Math.random(); // flip another coin for the second
            s = r^1; // set s to 0 if r=1, to 1 if r=0
            u = t^1; // set u to 0 if t=1, to 1 if t=0
        } while(i+r==k+t&j+s==l+u); // repeat if the branches overlap
    }
    return c; // return the output
}

239バイト(私は唯一の内側に物事を変更しましたdo{}(とforループの最初の部分でint型を置く)ビットPS:あなたの最初の答えで0.5にgolfedされている可能性が.5。同様
ケビンCruijssen

@KevinCruijssenは、数学を勉強する必要があるようです。感謝:-)
OOBalance

3

パール5208の 124 122 118バイト

改行、インデント、コメントなしの118バイト。テイクNは、標準入力から:

@b=1..2;                            #number of branches is 2
for(1..<>){                         #add length <> (the input) to each branch
  ($x,$y)=@$_                       #get where current branch has its tip now
 ,.5>rand?$x++:$y++                 #increase either x or y
 ,$o[$y][$x]++&&redo                #try again if that place is already occupied
 ,$_=[$x,$y]                        #register new tip of current branch
   for@b                            #...and do all that for each branch 
}
say map$_||!$i++?'*':$",@$_ for@o;  #output the branches

オンラインでお試しください!


いいですが、枝が1つアスタリスクで
本来

私の質問の例をもう一度参照してください:)
nicael

ああ、私は今に変わっ2..$N1..shift、数バイトも削った。
Kjetil S.

1
いい答えです!を使用して数バイトを節約し、引数の<>代わりに入力するshiftだけでなくrand、括弧を回避するために呼び出した順序を変更することもできます。@oどちらにも割り当てをラップする必要はありません。機能して@b=([],[]);いるように見えるものを使用してみましたが、あまり実験していなかったので、そこでエッジケースを見逃してしまった可能性があります。彼らが少し助けてくれることを願っています!
ドムヘイスティングス

1
Perlページでのゴルフヒントにはいくつかの良いアドバイスがあります。必ず確認してください!頑張って楽しんでね!
ドムヘイスティングス



1

PHP、118バイト

for($r="*",$w=$argn+2;$argn--;$r[$q+=rand(0,$r[$q+1]<"*")?:$w]=$r)$r[$p+=rand(!$i++,1)?:$w]=$r;echo wordwrap($r,$w-1);

ElvisオペレーターにはPHP 5.4以降が必要です。古いPHP ?:と置き換え?1:ます。

でパイプとして実行する-nR、オンラインで試してください


1
そこで別の入力を確認するにはどうすればよいですか?
nicael

@nicael:行の引数を変更できます$argBak=$argn=
Galen Ivanov

OK!これがこの方法で入力を「受け入れる」ための良い方法であるかどうかは
わかりませんが

@nicael TiOでは、単にの値を置き換えます$argn。実際の環境で$argnは、でパイプとして実行すると、STDINから取得されます-R。次に、入力の各行のコードを実行します(ただし、PHPがその間の変数を設定解除しないことは確かです。そのため、明示的な連続実行は、不意の驚きを避ける可能性が高くなります。)
Titus

0

195 190バイト

func[n][g: func[s][i: 0 d: s while[i < n][b/(d): #"*"until[r: 1 if 1 = random 2[r: n + 1]b/(d + r) =#" "]d: d + r
i: i + 1]]b:""loop n[loop n[append b" "]append b"^/"]b/1: #"*"g n + 2 g 2 b]

オンラインでお試しください!

読みやすい:

f: func[n][
    g: func[s][
        i: 0
        d: s
        while[i < n][
            b/(d): #"*"
            until[
                r: 1 if 1 = random 2[r: n + 1]
                b/(d + r) = #" "
            ]
            d: d + r
            i: i + 1
        ]
    ]
    b: ""
    loop n[loop n[append b " "]append b "^/"]
    b/1: #"*"
    g n + 2
    g 2
    b
]

0

ゼリー50 43 41バイト

2ḶẊ⁸С+\‘Ṗ
⁸ÇU;Ǥ⁻Q$¿
‘,þ`⁼€þÇS+»þ`Ị$ị⁾* 

オンラインでお試しください!

これは書くのが本当に楽しいものでした。より最適な方法がいくつかあるかもしれません。この方法でも、おそらくゴルフをする必要があります。

これを投稿した直後に、の,þ`代わりに使用できることに気付きましたaþ,""oþ`Ɗ


0

R148 142バイト

n=scan();`~`=sample;o=r=k=1;l=c(1,n);for(i in 1:n){r=r+l~1;t=l~1;k=k+"if"(k+t-r,t,l[l!=t]);o=c(o,r,k)};write(c(" ","*")[1:n^2%in%o+1],1,n,,"")

オンラインでお試しください!

さらに、出力仕様には適合しませんが、2つのブランチを区別できます。オンラインでお試しください!

説明:

インデックスから始めて、またはをそれぞれ追加することにより1、ブランチの右または左の動きをランダムに選択します。次に、ブランチの別の右または左の移動を選択し、移動先と交差する場合は、別の方向を選択します。次に、およびをのインデックスとして使用し、これらの値をとして設定します。時間を繰り返して、結果を出力します。rn1krrkm"*"n-1



0

Pythonの2191の 187 176バイト

from random import*
n=input()
p,q=c=1,1j;s={p,q,0}
exec'z=choice(c);q,p=p+[z,1+1j-z][p+z in s],q;s|={q};'*2*~-n
R=range(n+1)
for y in R:print''.join(' *'[y+x*1jin s]for x in R)

オンラインでお試しください!

Pythonは、次の形式の複素数をネイティブでサポートしていa+bjます。これにより、いくつかの2次元問題が少し扱いやすくなります...

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