Euler : Problem 84

Posted by YpsilonTAKAI On 2012年6月30日土曜日 0 コメント

モノポリーの各マスに止まる確率を求める問題です。

純粋に計算で出るんじゃないかと思ったけど、だめっぽい。計算のしかたからしてわからない。どうしよう。どうしよう。


で、実際にやってみることにした。 シミュレーションです。
サイコロ振って、マス目を移動して、そこの指示に従う、ってのをたくさん繰り返して、それぞれのマスに止った数を数えて確率を計算します。
最終的に百万回で答を出してます。

ソースは長めですけど、パキパキとできあがって、たのしかったな。
ここのところ、見つけてきた公式にあてはめてっていうパターンが多かったのでさおさらかな。

そういえば、今回から1.4でやってます。mapvとかvecter系の関数はちょっと便利そう。まだ使ってないけど。



作って、とりあえず100回くらいまわしたら、1秒以下で出たので、いきなり百万回まわしてみました。
4秒でした。

※ 最初のソースは余計なデータとか、マクロじゃなくてもいいマクロとかあったので、修正しました。






board
board-pos

ボードの40マスをベクターで表現したもの。 マスのIDから数字と取った名前だけ並べてます。

g2j ..... back3 nxr nxu next-x

CCカードやCHカードの役割を表わす関数群です。
現在のポジションを渡すと、そのカードを引いたときの結果のポジションを返す関数になっています。
next-x関数は前のバージョンではマクロでした。

★cc-cards ch-cards

Community Chest と Chance Cardのデータです。 データとして、ポジションを渡すと行き先が返る関数を持っています。

★new-pile

カードの束を渡すと、その束をシャッフルした新しいパイルを作って、そこから1枚ずつ引いてくる関数を返します。


※上の★の2つは関数型言語の特徴を生かしたつくりになってると思う。

make-move

現在のポジションとダイスの目をとって次のポジションを返します。
CCとCHに止ったときのために、パイルも2つ受け取ります。

roll-two-dice

さいころを2つ振って、ダブルかどうかと2つの目の合計を返します。

uptdate-stat

結果保存用のmapに結果を保存します。
mapは、キーがポジション、値が訪れた回数です。

do-monopoly

さいころを振る回数とさいころの面数と保存用mapを引数にとって、指定回数さいころを振っておとずれたマスの情報を更新します。

pe84

do-monopolyを呼んで、結果をソートして出力します。




0 コメント:

コメントを投稿