ジャン拳 V.S. ジャジャン拳
Powered by dKingyo Visual Basic | コンパイラ | Cisco技術者 | アルゴリズム | オープンソース
http://satoshi.blogs.com/life/2007/03/post_16.html
より・・・
自分でも解けそうだったのでやってみました。
このルールを見る限り
といった形で表すと
強い方>弱い方
賞金比率
といった関係
チョ>パ>グ>チョ>パ ...
2 :5:0:2 :5 ...
- 負けてもペナルティー(マイナス)がないという事
- 賞金の合計額は相手との競争でない事
- 問題中の条件で「大切なのは試合中に見えるのは相手が何を出したかだけです。」
賞金の比率を見ると500:200なので
パーで50%の確率で勝ちつづけた場合とチョキで勝ちつづけた場合
250:200
となるのでチョキで1回勝つより賞金額が高い。
それを2回も続けないとパーで50%の確率で勝った賞金額に届かない。
よって、チョキは絶対に出さない。
という戦略をとります。(名付けてグーパー交互戦略)
相手も自分も最高額の賞金を手に入れたいと思うならば
からこの戦略が最もであるのは明白でしょう。
自分がパーで1000回勝つ。 自分は500000円。相手は0円
両者ともパーで500回勝つ。 自分は250000円。相手は250000円
自分がチョキで1000回勝つ。自分は200000円。相手は0円
自分がグーで1000回勝つ。 自分は0円。 相手は0円
強いて問題を挙げるならばこの条件を相手サイドもルールから理解しているかと言う事です。
だけど、この手の問題を考える時必ず、抜け穴があるはずだ!!!と考えてしまうのです。
ちょっと考えた結果
- 相手が賞金なんて関係ナシにランダムに手を選ぶような機械であったり
- 相手がずっとチョキだけを出す主催者サイドの手先であったり
- 負けると挽回不可能なペナルティーがあったり
- 賞金の合計額は相手との競争で相手より賞金が多くないとその賞金は帳消しであったり
- 「試合中に見えるのは相手が何を出したかだけです。」から何を出したかという結果を見ても相手が戦略の意図を理解できなかったり
- 相手が何を出したか知ることが出来なかったり
- 自分がパーのときに相手がチョキを出してペースを乱してしまったり
した場合はこの戦略は使えません。
ちなみにこの問題は
http://d.hatena.ne.jp/yaneurao/20070326
のような問題を思い出して、この手の考え方を使用してみました。
前回行った「かめかめ算」の時にはC++のプログラムを掲載したので今回はRubyで掲載してみます。
続きを読む
#usr/local/bin/ruby =begin 一番高い金額の手で交互に勝ち負けをするといったアルゴリズム =end paper = 500 scissors = 200 stone = 0 count = 1000 arr = Array.new win_score = Array.new class Element def initialize(_id,_value) @id = _id @value = _value end attr_accessor :id, :value def print_name case(id) when 0 print "パー" when 1 print "チョキ" when 2 print "グー" end end end et = Array.new t = Element.new(0,paper) et.push(t) t = Element.new(1,scissors) et.push(t) t = Element.new(2,stone) et.push(t) arr =[paper,scissors,stone] score_rank = [0,1,2] win_score = [paper * count,scissors * count,stone * count] #0:paper 1:scissors 2:stone arr.sort!{|a, b| -(a <=> b)} for i in 0..2 do #score rank sort for j in 0..2 do if et[j].value == arr[i] then score_rank[i] = et[j].id end end end lose = [0,1] lose[0] = score_rank[0] lose[1] = score_rank[0] == 0 ? 2 : score_rank[0] - 1 for i in 0..1 do et[lose[i]].print_name if 0==i then print " と " end end puts " を交互に出せばよい" sc = ( win_score[lose[0]] ) / 2 print "自分、相手の賞金額は","#{sc}","円\n" exit
[]追記:あえて最初に書くのも無粋かと思ったけど、これって一種の行動心理テストに近いものがあるなーと・・・ってのは勘違いか^^;[]