ルーチンBeanマシンではない


42

Beanマシンまたはplinko / パチンコゲームに似たメカニズムのこのASCIIバージョンを検討してください。

    O

    ^
   \ ^
  ^ ^ \
 \ ^ / ^
U U U U U
1 2 3 4 5

O落ちるボールです。

  • にヒットする^と、50〜50の確率で左または右に移動します。
  • にヒットすると/、常に左に移動します。
  • にヒットすると\、常に正しくなります。

最終的に、ボールUは下部の番号付きトラフのいずれかに落ちます。問題は、それが各谷で終わる確率は何ですか?

この特定のケースでは、確率は0.00.18750.56250.125、および0.125、それぞれトラフ5を介して1。

ここでは3つの谷の代わり5.確率があるとのもう一つの例だ0.50.5とは0.0

  O

  /
 ^ ^
U U U
1 2 3

この課題では、この問題を、任意の方法で設定された任意の数のレイヤーを持つメカニズムに一般化します。

チャレンジ

メカニズムのピラミッド構造のASCII表現を取り込むプログラムまたは関数を作成します。(stdin /コマンドライン/関数引数を使用して入力します。)

あなたはそれが適切な形にそれを置くスペースで入ってくると仮定するかもしれません、例えば

   ^
  \ ^
 ^ ^ \
\ ^ / ^

または、スペースがまったくない状態であると仮定することもできます。たとえば、

^
\^
^^\
\^/^

(必要に応じて、末尾の改行および/または末尾のスペースの一貫したパターンがあると仮定できます。)

入力ピラミッド構造には、ゼロを含む任意の数のレベル(ライン)を含めることができます。各レベルは、一以上有する^/または\最後のではなく、そしてあるlevels + 1(入力の一部ではない)底部の溝は

プログラム/機能は、ボールが各トラフに着地する確率のリストを印刷/返送する必要があります(左端のトラフから右端のトラフの順)。これらは、印刷時に、少なくとも3小数点以下の桁数を有する浮動小数点値をすべきである(余分なゼロまたは小数点が必要とされない。1罰金である1.000.5のために微細である0.500など)。関数を作成した場合、値を出力するか、フロートのリスト/配列を返すことができます。

妥当な印刷リスト形式であれば問題ありません。例えば0.5 0.5 0.0[0.5 0.5 0.0][0.5, 0.5, 0.0]{0.5, 0.5, 0.0}、または0.5\n0.5\n0.0すべて大丈夫だろう。

0レベル:(つまらないものになりますU

入力:[no input/empty string given]
出力:1.0

1レベル:

入力:^
出力:0.5 0.5

入力:/
出力:1.0 0.0

入力:\
出力:0.0 1.0

2レベル:(上記の2番目の例)

入力:

 /
^ ^

出力: 0.5 0.5 0.0

3つのレベル:

入力:

  ^
 ^ ^
^ ^ ^

出力: 0.125 0.375 0.375 0.125

入力:

  \
 / \
/ / \

出力: 0.0 0.0 0.0 1.0

4レベル:(上記の最初の例)

入力:

   ^
  \ ^
 ^ ^ \
\ ^ / ^

出力: 0.0 0.1875 0.5625 0.125 0.125

7レベル:

入力:

      ^
     / ^
    ^ ^ /
   / \ / \
  ^ ^ / ^ \
 ^ \ ^ \ / ^
\ ^ ^ ^ \ ^ /

出力: 0.0 0.09375 0.28125 0.4375 0.1875 0.0 0.0 0.0

得点

バイト単位の最短回答が優先されます。Tiebreakerは以前の投稿です。


16
Quincunxはこれに答えた良いでしょう
カルバンの趣味

「後続スペースの一定のパターン」-N行目の後続スペースは、ボールがN番目のバケットに着地する確率をエンコードすると仮定できますか?
Random832

4
@ Random832いいえ(あなたは本当に飛ぶと思いますか?)
カルビンの趣味

答えではなくコメントとして投稿した理由があります。このパズルが入力についてどれほど寛容であるかがおもしろいと思った-私が見たほとんどのことは、入力および/または出力の形式をより厳密に決定することだ。
Random832 19

@ Random832:入力と出力は非常に明確です。標準の抜け穴(入力の回答をエンコードするなど)は、すべての課題で対処する必要はありません。
アレックスA.

回答:


10

CJam、50 48 45 44 42 40バイト

1]q{iD%"(+0 0+( (\Y/::+ (d2/_a+"S/=~+}/p

これは、入力にスペースがなく、末尾に改行があることを想定しています。例えば:

^
\^
^^\
\^/^

[0 0.1875 0.5625 0.125 0.125]

アルゴリズム

基本的な考え方は、各文字の解析を続け(4文字しかありません)、確率分布(最初は値1の1要素を含む配列)で異なる操作を実行することです。入力文字の各行(最初の行の最初の文字から始まる)について、同じサイズの確率配列を維持します。各文字は、リストの最初の確率に基づいて動作し、結果のペアをリストの最後にプッシュします。各行の後に、リストからペアを合計して、次の行のアイテムとして正確なアイテム数を取得します。

以下は、4文字とそれぞれに対応する必要なアクションです。

  • ^:この文字が発生すると、現在の確率を2つの部分に分割します。たとえば、最初の行にこれがある場合、に変換する[1]必要があります[0.5 0.5]
  • /:この文字が発生すると<current probability> 0、配列内の現在の確率の代わりに配置する必要があります。
  • \:この文字が発生すると0 <current probability>、配列内の現在の確率の代わりに配置する必要があります。
  • \n:この文字が発生すると、新しい行があります。したがって、3文字以上のすべてのペアをグループ化し、それらを合計して、次の行の各アイテムの確率を取得します。例えば [0 0.5 0.25 0.25]に変換され[0 0.75 0.25]ます。最初と最後のアイテムには、それらの前後に暗黙のペア(値0)があることに注意してください。

ここで、適切なキャラクターを特定し、適切なアクションを実行するだけです。ここで通常の数学を使用してそれを行いましょう。以下のためのASCIIコード^\/\nしている949247、と10。数回の試行の後、これらの数値を0、1、2、および3に変換する次の簡単な式を取得します。

"^\/
":ied13f%ed4f%ed

与える:

Stack: [[94 92 47 10]]
Stack: [[3 1 8 10]]
Stack: [[3 1 0 2]]
3102

長さ4の配列では、最後4f%は暗黙的です。その%13ため、単にキャラクターのASCIIコードに対して行い、アクションの配列から適切なアクションを選択します。

コードの説明

1]                                 e# Initial probability array with 1 probability
  q{                          }/   e# Read the whole input and iterate char by char
    iD%                            e# mod the ASCII code of the character with 13
"(+0 0+( (\Y/::+ (d2/_a+"S/        e# This is our actions array in order of [\ / \n ^]
                           =~      e# We pick the correct action and eval it
                             +     e# Evaling each action will leave one number out of the
                                   e# pairs out of the array. So we put it back in
                                p  e# Print the final probability array

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


1
0行でどのようにテストしますか?
trichoplax

1
@trichoplaxはすぐに動作するはずです。
オプティマイザー

空の入力で動作するようになりました:)
trichoplax

15

ルビー140

->s{r=[1.0]
s.lines.map{|l|n=[i=0.0]*(r.size+1)
l.scan(/\S/).map{|e|a,b=e>?/?e>?]?[0.5]*2:[0,1]:[1,0]
z=r[i]
n[i]+=z*a
n[i+=1]+=z*b}
r=n}
r}

入力として文字列(ピラミッドとして適切にフォーマットできます)を受け取り、floatの配列を返す関数。

オンラインでテストする:http : //ideone.com/kmsZMe

非常に簡単な実装。ここでは、無料です:

F = -> input {
  probabilities = [1.0]

  input.lines.each { |line|

    new_probabilities = [0.0] * (probabilities.size+1)
    elements = line.scan /\S/
    elements.map.with_index{|el, i|
      deltas = el > '/' ? (el > ']' ? [0.5,0.5] : [0,1]) : [1,0]

      d1, d2 = deltas

      new_probabilities[i] += probabilities[i] * d1
      new_probabilities[i + 1] += probabilities[i] * d2
    }
    probabilities = new_probabilities
  }
  return probabilities
}

13

ルビー、140 158バイト

より良いルビーバージョンがあるとき、これを支持し続けないでください。ここにあなたのためのより多くのトリックがあります。

引数が1つの名前のない関数。スペースを含めることはできません。末尾の改行を含む場合と含まない場合があります。

->s{Z=(s.split'
')<<[]
K=[]
F=->i,j,f{k=Z[i][j]
K[i]||=0
k==?^?2.times{|m|F[i+1,j+m,f/2]}:!k ?K[j]+=f :F[i+1,j+(k==?/?0:1),f]}
F[0,0,1.0]
K}

処理する必要があるため、9バイトを無駄にします0 levels(空の文字列)。すべてのテストケースは正しく動作しますこちらのideoneをご覧ください


4
「より良い」Rubyの答えがあるからといって、あなた(または他のRubyの答え)が投票する価値がないというわけではありません。:)
アレックスA.

いくつかの素晴らしいトリックが含まれているため、私は自分でこれを支持しました。splitたとえば、マルチラインが好きです。
クリスチャンルパスク

12

Pyth、43 42 41バイト

umsdc+0sm@c[ZJhkJZKcJ2K)2x"\/"ekC,GH2.z]1

これは、入力にスペースがないことを想定しています。オンラインで試す:Pyth Compiler / Executor

Pyth、40バイト(疑わしい)

umsdc+0sm,K@[ZJhkcJ2)x"\/"ek-JKC,GH2.z]1

@isaacgに感謝します。1バイトを節約してくれました。このバージョンは、質問されたときにPythのバージョンでは実際には機能しなかったことに注意してください。コンパイラに小さなバグがありました。このコードはPythの新しい機能を使用していませんが(長い間Pythのドキュメントに含まれていて機能するはずだったもののみ)、これは有効な答えではないかもしれません。自分で決めてください。

オンラインで試す:Pyth Compiler / Executor

説明:

umsdc+0sm,K@[ZJhkcJ2)x"\/"ek-JKC,GH2.z]1   
u                                   .z]1  reduce G, starting with G = [1], for H in all_input():
                               C,GH         zip(G,H)
        m                                   map each pair k to:
            [ZJhkcJ2)                         create a list [0, k[0], k[0]/2]
                     x"\/"ek                  index of k[1] in "\/" (-1 for "^")
          K@                                  take the correspondent element of the list and store in K
         ,                  -JK               create a pair (K, k[0]-K)                                                      
     +0s                                    sum and insert 0 at the begin
    c                              2        chop into pairs
 msd                                        sum up each pair
                                            G gets updated with this new list

たとえば、現在入力確率G = [0.5, 0.5, 0.0]と行がH = "^/^"ある場合、次のようになります。

  • zip ... [(0.5,"^"), (0.5,"/"), (0.0,"^")]
  • 出力確率の作成... [[0.25,0.25], [0.5,0.0], [0.0, 0.0]]
  • 0+合計... [0, 0.25, 0.25, 0.5, 0.0, 0.0, 0.0]
  • チョップ... [0,0.25], [0.25,0.5], [0.0,0.0], [0.0]]
  • 合計... [0.25, 0.75, 0.0, 0.0]

3
私はこれをゴルフしようとしていましたが、それはコンパイラのバグにつながりました。バグを修正したので、ゴルフは機能します。ゴルフでは、2値リストのリストを1つのリストに置き換えてから、から最初の値を減算して他の値を生成しhkます。 ,K@[ZJhkcJ2)x"\/"ek-JK
isaacg

1
バグの修正が言語の新しいバージョンとしてカウントされていない場合(これは修正前に尋ねられた質問に対しても有効です)
オプティマイザー

1
@Optimizerあなたの権利。回答にいくつかのメモを追加し、状況を説明します。
寂部

2
@Optimizerこの場合、それは実際に言語の新しいバージョンであるか、バグを修正する言語実装の新しいバージョンであるかが、実装を仕様に近づけるのが良い経験則のようです。
-Desty

@Destyそれは私がその細い線を言った理由です;)
オプティマイザー

8

C#、274 247バイト

STDINから行を読み取り(スペースの有無にかかわらず、単にストリップする)、スペースで区切られた結果をSTDOUTに印刷する完全なプログラムは何もありません。

using Q=System.Console;class P{static void Main(){decimal[]k={1},t;string L;for(int l=0,i;(L=Q.ReadLine())!=null;k=t)for(L=L.Replace(" ",""),t=new decimal[++l+1],i=0;i<l;)t[i]+=k[i]-(t[i+1]=(8-L[i]%8)/2*k[i++]/2);Q.WriteLine(string.Join(" ",k));}}

コメント付きのよりきれいなコード:

using Q=System.Console;

class P
{
    // / 47
    // \ 92
    // ^ 94

    static void Main()
    {
        decimal[]k={1},t; // k is old array, t is new array

        string L; // L is the current line, R is the current result (1 if no rows)
        for(int l=0,i; // l is length of old array, i is index in old array
            (L=Q.ReadLine())!=null; // for each line of input
            k=t) // swap array over
            for(L=L.Replace(" ",""), // remove spaces
                t=new decimal[++l+1], // create a new array
                i=0;

                i<l;) // for each position

                t[i]+=k[i]-( // add to left position (for last time)
                        t[i+1]=(8-L[i]%8)/2*k[i++]/2 // assign right position (k is decimal)
                    );

        Q.WriteLine(string.Join(" ",k)); // print result
    }
}

7

Python 3、113

P=[1]
for C in input().split():
 l,*Q=0,
 for p,c in zip(P,C):r=p*"\^/".find(c)/2;Q+=l+r,;l=p-r
 P=Q+[l]
print(P)

P各行に応じて確率ベクトルを繰り返し更新します。この新しい確率ベクトルQは、一度に1つのエントリが作成されます。新しいスロットを反復処理し、ペグからその右への寄与をとしてr計算しp-rます。また、今後のスロットへの残りの寄与をとして計算します。

行がバックスラッシュで終わる問題を回避するために、各行が少なくとも1つのスペースで終わることを想定しています。


入力には複数の行があるため、1行でinput()処理できるとは思わない。
randomra

入力の各行に末尾の改行は必要ありません。
ブライアンミントン

@randomra私はこれをIdleで書いたが、シェルプロンプトに複数行の入力を入れるとうまく機能した。
xnor

6

Python 3、138バイト

def f(s):
 r=[1];p=t=0
 for e in s:
  if'!'<e:b=p==t*-~t/2;r+=[0]*b;t+=b;v=ord(e)%7+1;a=r[p]/2;r[-1]+=v//3*a;r+=v%3*a,;p+=1
 return r[~t:]

すべての空白が(でif'!'<e)除外されるため、任意の空白で動作します。

方法:

  • r障害物とその下にある暗黙の谷に到達する確率のリストを常に拡大しています。リストから始めます[1]
  • 行の最初の障害にいる0場合、先頭のトラフのリストに追加を追加する必要があります。インデックスpを次の三角形の数値と比較することで、それが最初の障害かどうかを判断しt*-~t/2ます。
  • すべての障害について、そのリスト値を部分的に最後の要素に追加し、部分的に新しい後続要素に追加します。リスト値は、障害文字(^:0.5 0.5; /:1 0; \:0 1)に基づいて分割されます。次の方法を使用します。
    • テイクv = ord(char) mod 7 + 1^:4 /:6 \:2
    • v div 3 / 2最初の分数(^:0.5 /:1 \:0)を生成します
    • v mod 3 / 22番目の分数(^:0.5 /:0 \:1)を生成します
  • 結果は、t + 1最終リストの最後の要素ですr

@ Sp3000のチャットアドバイスのおかげで2バイト。


4

Perl、78

#!perl -p0a
@r=($/=1);$^=.5;@r=map$r-$l+($l=$$_*($r=shift@r)),/./g,$r=$l=0for@F;$_="@r"

スペースなしで入力を受け取ります。

私を試してください


1

TI-BASIC、73 76

文字列の改行や空の文字列はTI-BASICでは有効ではないため、入力は一度に1行ずつ入力され、スペースが単独で入力されると終了します。

{1→X
Input Str1
While Str1≠"  //one space
.5seq(inString("^/",sub(Str1,I,1)),I,1,dim(Ans
augment(Ans∟X,{0})+augment({0},∟X-∟XAns→X
Input Str1
End
∟X

サイズが適切であると確信しています(TI-BASICはトークン化されているため、各コマンドは1バイトまたは2バイトを使用します。seq()は1バイト、inString()は2バイト、dim()は1バイトなどを使用します。手動でサイズをカウントしました。)

文字列ではバックスラッシュ文字が有効ですが、電卓を変更しない限り、プログラム内からバックスラッシュ文字を入力する方法がないことに注意してください。


0

Javascript-117

再帰を使用してみましたが、長すぎました...

帽子先端XNORダース以上の文字削り取ら減算アイデアについて。

w=s=>{a=[1];s.split('\n').map(m=>{for(b=[i=0];z=a[i],f=m[i];b[i++]+=z-b[i])b[i+1]=f>']'?z/2:f<':'?0:z;a=b})
return a}

ゴルフをしていない:

// s must not have spaces
w=s=>{
  // a is the current probability array
  a=[1];
  s.split('\n').map(
    // for each row of input...
    m=>{
      b=[0];  // b is the next row's probability array
      for(i=0; i<m.length;){
        z=a[i]; // z = probability
        f=m[i]; // f = letter
                                  // let's assume i == 0
        b[i+1] = (f>']') ? z/2 :  // if f == '^', b[1] = z/2
          (f<':' ? 0 :            // else if f == '/', b[1] = 0 
            z);                   // else b[1] = z
        b[i++]+=z-b[i];           // then add (z-b[1]) to b[0]
      }
      a=z-b    // increment current probability array
    }
  )
  return a;
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.