無駄のない、平均的な豆の機械


26

離散確率分布の概念を人々に紹介する古典的な例は、Beanマシンです。このマシンには、上部の狭い通路から大量のビー玉が落下し、その後、インターレースピンの列にヒットします。各ピンでビー玉がヒットすると、ピンの左右に落ちる場合があります。最後に、ピンはマシンの下部にある垂直ビンに集められます。このマシンの簡単な図は次のようになります。

|     O     |
|     ^     |
|    ^ ^    |
|   ^ ^ ^   |
|  ^ ^ ^ ^  |
| ^ ^ ^ ^ ^ |
|_|_|_|_|_|_|

この図では、Oはビー玉が落ちる場所を示しています。それぞれ^は、大理石がピンの左または右のいずれかの正方形に移動する確率が50%であるピンです。次に、ビー玉はデバイスの下部のビンに集まります。十分な数のビー玉の場合、ビン内のビー玉スタックの高さは離散的な二項分布に似ています。

チャレンジ

この課題では、上記のような図に基づいて、Beanマシンの結果の確率分布を計算します。図は、側面のフィールドまたは現在のフィールドの下のフィールドに向かって、ビー玉が通過する2次元の「プログラム」として解釈されます。ビー玉が機械の底に達すると、確率分布としてカウントされます。面白くするために、これらの図には、単純なソースとピン以外のフィールドがいくつか含まれています。ダイアグラムの例は次のとおりです。

|     O     |
|     ^     |
|    ^ /    |
|   ^ | ^   |
|  <^- =  v |
| ^ ^ ^ ^ ^ |

さらに、ビー玉にはそれぞれ回転方向があります。この方向はいくつかのフィールドによって設定され、ビー玉が他のいくつかのフィールドで移動する次のフィールドを決定します。

以下のフィールドが定義されています:

  • O:ソース。その直下にビー玉を生成します。これらのビー玉の方向は左50%、右50%です。各ソースは同じ量のビー玉を生成します。
  • U:シンク。このフィールドに入るビー玉はすべて、ビーンマシンから削除されます。
  • : 空きスペース。大理石がこのフィールドに到着すると、それは下のフィールドに移動します。
  • -:フロア。大理石がこのフィールドに到着すると、現在の方向に応じて、左側のフィールドまたは右側のフィールドのいずれかに移動します。
  • ^:スプリッター。大理石がこのフィールドに到着すると、50%がスプリッターの右側のフィールドまたは左側のフィールドに移動します。これにより、大理石の方向も決まります。
  • v:参加します。大理石がこのフィールドに到着すると、それは下のフィールドに移動します。
  • /:傾斜パッド。大理石がこのフィールドに到着すると、パッドの左側のフィールドに移動し、大理石の方向を設定します。
  • \:前と同じですが、右側にあります。
  • |:リフレクター。大理石がこのフィールドに到着すると、大理石の方向を反転させ、この反転した方向に基づいて、大理石をフィールドの右または左に移動します。
  • =:キャノン。大理石がこのフィールドに到着すると、大理石が-またはでないフィールドに遭遇するまで、大理石を現在の方向で右または左に移動しOます。
  • <:前と同じですが、常に方向を設定し、左に移動します。
  • >:前と同じですが、右側にあります。

図に関して、以下の保証が与えられます。

  • 各入力行のフィールドの長さはまったく同じです。
  • 各行の左端と右端のフィールドは常にa |です。
  • ダイアグラムには、\/またはなどの不定の反復でビー玉がマシンに詰まる可能性のあるパスは含まれません^^
  • 図には、上記のフィールドのみが含まれます。
  • 1つ以上のソースがあります

結果

あなたの仕事は、ビー玉がグラフの下側を出る確率分布の16行の高さのASCIIバーグラフを生成し、最大の確率が16文字すべてをカバーするようにスケーリングすることです。したがって、次の問題の場合:

|     O     |
|     ^     |
|    ^ ^    |
|   ^ ^ ^   |
|  ^ ^ ^ ^  |
| ^ ^ ^ ^ ^ |

プログラムは次の解決策を作成する必要があります(横へのパイプを含めて、入力プログラムと同じ幅にする必要があります。

     # #     
     # #     
     # #     
     # #     
     # #     
     # #     
     # #     
     # #     
   # # # #  
   # # # #  
   # # # #  
   # # # #  
   # # # #  
   # # # #  
 # # # # # #
 # # # # # # 

以下は、すべての異なるフィールドタイプの機能をテストする必要がある例です。

|     O     O         |
|  O  ^ /  <^\\\      |
|    ^ >            ^ |
|   ^ ^ ^            =|
|  ^ ^ | ^    <^   O  |
| ^ > ^ | ^   O ^> v  |
||  ^U  ^  |  =    ^\ |
|  ^ ^ ^ ^U ^\ ---^   |
| = ^   ^     =    v  |

結果は次のようになります。

                     # 
                     # 
                     # 
                     # 
                   # # 
                   # # 
                   # # 
       # #         # # 
       # #         # # 
       # #         # # 
       # #         # # 
      ## #         # # 
      ## # #       # # 
   # ### # #       # # 
 # # ### # #       # # 
 # # ### # #       # # 

ルール

機能と完全なプログラムの両方が、この課題に対する有効な答えを構成します。改行で区切られた文字列としてダイアグラムを受け取り、指定された形式で出力グラフを返す必要があります。デフォルトの入出力ルールが適用されます。出力では末尾と先頭の改行を使用できますが、各行は入力とまったく同じ幅にする必要があります。

より創造的なソリューションを可能にするためには、プログラムが同じダイアグラムに対して90%以上の時間で正しい結果を出力することが必要です。やはり確率シミュレーションです。

得点

これはであるため、バイト単位の最低スコアが優先されます。


はるかに単純ですが、関連しています。
ピーターテイラー

コメントは詳細なディスカッション用ではありません。この会話はチャットに移動さました
デニス

だからv= [space]
l4m2

@ l4m2 v[space]大砲が周囲で相互作用する方法が異なります。
CensoredUsername

回答:


8

Pythonの3431の 429 410バイト

def t(a):e=enumerate;p=a.split("\n");o=[0]*len(p[0]);{m(i,j,p,o,1):m(i,j,p,o,-1)for i,r in e(p)for j,c in e(r)if"O"==c};[print("".join(" #"[round(16*r/max(o)+i)>15]for r in o))for i in range(16)]
def m(r,k,p,o,l,x=1):
 while r<len(p):
  c=p[r][k]
  if"^"==c:x/=2;m(r,k-l,p,o,l,x)
  if"U"==c:return
  if c in" vO":r+=1;continue
  l=[1,l,-1,l,-l,1][ord(c)%6];k-=l
  while";"<c<"?"and p[r][k]in" O-":k-=l
 o[k]+=x

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

この答えは、Wheat WizardとCensoredUsernameの間の共同作業です。参考までに、これはungolfedアルゴリズムです。

-Mr. Xcoderから2バイト

CensoredUsernameから-19バイト


Python 2(printステートメント)に切り替えた場合、-2バイトですか?
コメアリンガーアーイング

1
:これは言われたのbut I can confirm it's doable in 519 characters of python 3 code ;) I don't think I can golf mine much more- CensoredUsername
スティーブン

それを言ったとき、私は絶望的に素朴でした。とはいえ、ゴルフ競技の確保は非常に面白かったです。また、@ cairdcoinheringaahing、python 2のprintステートメントは式ではなくステートメントであるため、リスト内包表記では使用できません。これは、上部のonelinerをいくつかのインデントされた行に分割する必要があることを意味します。
CensoredUsername

4

Python 2、731バイト

i=raw_input
l=i()
c=[]
while l:c,l=c+[l],i()
p=[[0]*len(l)for l in c]+[[0]*max(map(len,c))]
S=lambda r,C,p:r>=0and C>=0and r<len(p)and C<len(p[r])
def U(r,C,P,D,N=0):
 if S(r,C,p):p[r][C]+=P
 if S(r,C,c):
	K=c[r][C]
	if K in' O':U(r+1-N,C+D*N,P,D,N)
	elif'v'==K:U(r+1,C,P,D)
	elif'-'==K:U(r,C+D,P,D,N)
	elif'^'==K:U(r,C-1,P/2,-1);U(r,C+1,P/2,1)
	elif'/'==K:U(r,C-1,P,-1)
	elif'\\'==K:U(r,C+1,P,1)
	elif'='==K:U(r,C+D,P,D,1)
	elif'>'==K:U(r,C+1,P,1,1)
	elif'<'==K:U(r,C-1,P,-1,1)
	elif'|'==K:U(r,C-D,P,-D)
for r in range(len(c)):
 for C in range(len(c[r])):
	if'O'==c[r][C]:U(r+1,C,1.,1);U(r+1,C,1.,-1)
p=p[-1][::-1]
s=16/max(p)
f=['#'*min(int(n*s),16)+' '*min(int(16-n*s),16)for n in p]
print('\n'.join(map(''.join,zip(*f)))[::-1])

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

ケアード・コイナーリンガーのおかげで-17バイト

Nathan Shirainiのおかげで-12バイト

混合インデントに切り替えて-56バイト(Python 2)

-28 CensoredUsernameに感謝します。これは、確率が最終的に正規化されるため、最終確率が常に合計1になる必要がないためです。

計算のネコのおかげで、短い終了elifステートメントを使用して-7バイトになりました。

-218バイト、2つの関数をマージして



@cairdcoinheringaahingそうですね。
ハイパーニュートリノ

2
呼び出しではRLのようなR(r+1-N,C+N,P,N=N)(の最初の呼び出しR)、あなたは必要としないN=終わり。それはする必要がありますR(r+1-N,C+N,P,N)代わりに。
Nathan.Eilisha Shiraini

@NathanShirainiそうですね。
-HyperNeutrino

...忘れてしまいました。両方の最後の2行LとはR^^また、インデントの2番目のレベルはどこにでも4つのスペースで、私はあなたがそれが2作ることができると思う
Nathan.Eilisha Shiraini

3

C、569 568 556バイト

ゴルフ

#define A s[1]
#define c(i,j,k) break;case i:x=j;y=k;
w,S,i,j,d,x,y,z;main(int*a,char**s){w=strchr(&A[1],'|')+2-A;a=calloc(w,4);for(;i++<'~~';j=0){for(;A[j];){if(A[z=j++]==79){d=rand()%2;x=4;y=7;z+=w;for(;z<strlen(A);){z+=x%3-1+(y%3-1)*w;switch(A[z]){case 85:goto e;c(32,x/3*(3+1),y/3*(3+1))c(45,d*2+3,7)c(94,(d=rand()%2)*2+3,7)c(118,4,8)c(47,3,7)d=0;c(92,5,7)d=1;c(124,(d=!d)*2+3,7)c(60,x,y)case 62:d=A[z]/2%2;case 61:x=d*8;y=4;}}a[z%w]++;e:;}}}for(i=-1;++i<w;S=a[i]>S?a[i]:S);for(j=17;j-->1;puts(""))for(i=0;i<w-1;printf("%c",a[i++]*16./S+0.6<j?32:35));}

非ゴルフ

//Variable Definitions
//direction - marbles current direction, 0 -> left, 1-> right
//arrwidth - width of array
//x - change in x of marble in base 3 - 0 -> Left, 1 -> stay, 2-> right
//y - change in y of marble in base 3 - 0 -> Up, 1 -> stay, 2-> Down
//z - position of marble
//i - iterator on runs of program
//j - iterator on string
//k - iterator on outputstring
//argc - array holding all buckets

#define c(i,j,k) break;case i:x=j;y=k;

arrwidth,scale,i,j,direction,x,y,z;

main(int *argc, char**argv){
  arrwidth=strchr(&A[1],'|')+2 - A; //get width
  argc=calloc(arrwidth,4);
  for(;i++<'~~';j=0){
    for(;A[j];){
      if(A[z=j++] == 79){ //if it finds an O, start sim
        direction=rand()%2;
        x=4;
        y=7;
        z+=arrwidth;
        for(;z<strlen(A);){
          z+=x%3-1 + (y%3-1)*arrwidth;
          switch (A[z]){
            case 85://marble dies dont record
              goto e;
            c(32,x/3*(3+1),y/3*(3+1)) //case ' '
            c(45,direction*2+3,7)    //case -
            c(94,(direction=rand()%2)*2+3,7)    //case ^
            c(118,4,8)    //case v
            c(47,3,7)    //case /
              direction=0;
            c(92,5,7)   //case '\'
              direction=1;
            c(124,(direction=!direction)*2+3,7)
            c(60,x,y)    //case <
            case 62:    //case >
              direction=A[z]/2%2;
            case 61:  //case =
              x=direction*8;
              y=4;
          }
        }
        argc[z%arrwidth]++;
        e:;
      }
    }
  }
  //get output answer in terms of '#'
  for(i=-1;++i<arrwidth;scale=argc[i]>scale?argc[i]:scale);
  for(j=17;j-->1;puts(""))
    for(i=0; i < arrwidth-1;printf("%c",argc[i++]*16./scale+0.6<j?32:35));
}

編集

ケースマクロを変更して12バイトを節約しました。

ノート

私のコードでは、基数3の整数のシステムを使用して、ビー玉がどこに向かっているのかを判断します(大砲などの場合)。

私はそのPythonソリューションを打ち負かさなければならなかったので、本当にやりました。


1
568バイトを数えます。多分あなたは末尾の改行を数えましたか?気分が悪い CによってPythonでアウトゴルフされましたか?Jeez ...:P
ハイパーニュートリノ

あなたは正しいです、私はファイルに末尾のニューリングを残しました。ありがとう!
-dj0wns
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.