質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.01%

計算のミス?

受付中

回答 2

投稿

  • 評価
  • クリップ 1
  • VIEW 685

souroppy

score 42

ガチャのコンプリートまでに引く回数を計算するプログラムを作りたいです。 
具体的には、まず1種類キャラクターがいるときにコンプリートするまでにかかる回数=1、次に二種類キャラクターがいるときにコンプリートまでにかかる回数=3、次に三種類キャラクターがいるときに・・・と続けていき、大体50ぐらいまでその作業を行いこの結果の「1」、「3」、・・・の部分を表示させるプログラムが作りたいのですが自分が作ってみたもの

import UIKit



var A: Int = 1
var B: Double = 0
var C: Double = 0
var kekka:Double = 0
var saigo:Double = 0
var saigo2:Double = 1

for count in 1...49 {
    A = A + 1
    saigo2 = saigo2 + saigo
    saigo = 0
    print(saigo2)
    var C: Double = Double(A)
    for count in 1...A {
        var B: Double = Double(A)
        B = B - 1
        kekka = C / B

        saigo = saigo + kekka
        kekka = 0

    }
}

では、少し答えがおかしくなってしまいます。(数字が思っているものと違う)

1.0
5.0
9.5
14.8333333333333
21.0833333333333
28.2833333333333
36.45
45.5928571428571
55.7178571428571
66.8289682539683
78.9289682539683
92.0198773448773
106.103210678211
121.180133755134
137.251562326562
154.318228993229
172.380728993229
191.439552522641
211.495108078196
232.547739657144
254.597739657144
277.645358704763
301.690813250217
326.734291511087
352.775958177754
379.815958177754
407.854419716215
436.891456753252
466.927171038966
497.961653797587
529.99498713092
563.027245195437
597.058495195437
632.08879822574
668.118209990445
705.146781419017
743.174559196795
782.201586223822
822.227902013295
863.253543038936
905.278543038936
948.302933282839
992.326742806648
1037.3499986206
1083.37272589333
1130.39494811555
1178.41668724599
1227.43796384173
1277.45879717506

補足
確率は全て一律とします。(例えば50種類の時は一つのものの確率は2%。)
あくまでも計算上の話です。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • Mr_Roboto

    2016/07/20 15:49

    ひとつ前に、同じような質問をしていますね? https://teratail.com/questions/41613 そちらは、どうなりましたか?
    回答している人に失礼になりますので、きちんと1つずつ解決してからにしてくださいね。

    キャンセル

  • ozwk

    2016/07/20 17:18 編集

    2種類のとき3回という数字はどうやって導出しましたか?期待値ですか?

    キャンセル

  • coco_bauer

    2016/07/20 18:21

    2種類のキャラが、それぞれ100個ずつ入っているとすればコンプリートまで101回。1000個ずつ入っていれば1001回が、確実にコンプリートするまでに必要な回数です。 最初にガチャに何が入っているのかという条件を書かないと、回答は出せませんよ。

    キャンセル

回答 2

0

まともな仕様が出てきそうにないので逆丸投げ。

for num in 1...49 {
    var sigma = 0.0
    for count in 1...num {
        sigma = sigma + 1.0 / Double(count)
    }
    let comp = Double(num) * sigma
    print("[\(num)種類] \(comp)回")
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

まず、ガチャがソシャゲのように各キャラクターのストックに出現量の制限がないものなのか、それとも現実のガチャガチャの様に各キャラクターのストックの出現量に制限が存在するかで問題が変わりますね。

さてまずは、ソシャゲタイプのガチャの場合を考えてみます。

この場合は、ひとつのキャラが永遠に出現することもあり、何回ガチャを引けどもコンプリートできない場合があります。

そこで、

n種類のキャラクターが等確率で出現するガチャで、m(>=n)回までにコンプリートできる確率

を求めることにします。

数学っぽい問題にして考えるならば、

n個の穴に向かってm回ボールを投げ入れる。各穴にボールが入る確率は等確率として、すべての穴にボールが入っている確率

を求めるわけですね。

まず全パターン数を求めます。

穴を○と表現し、区切りを|で表すとして、

n個の丸と(m-1)個の|の並び替えを考えます。(|○○○||○○|○|○○ のような表現)

区切りによってできる各部分が穴に入ったボールの個数というわけです。(上記の表現なら穴1は空、穴2には3つのボールが入っている...)

この考えで全パターンは

(m+n-1)C(n-1)

となります。

で次に、

少なくともすべての穴に1つ以上ボールが入っているパターン数

を求めます。これは、

各穴に1つボールが入った状態からボールを投げるパターン数

と一致します。つまりパターン数は、

(m-n+(n-1))C(n-1)

となります。

よって求める確率は

(m-n+(n-1))C(n-1)/(m+n-1)C(n-1)

ですね。(数式のCは高校数学のコンビネーションのものです)

次に、リアルのガチャガチャの場合を考えてみます。

条件として、

n個のキャラクターc1,c2,...,cnがガチャガチャの中に、p1,p2,...,pn(pi > 0, i=1,..n)個存在するとします。

このとき、確実にコンプリートできるパターンで、最もたくさんガチャガチャを引かなければならない(運が悪い)のは

一番ストックの少ないキャラが最後まで出てこない

(つまり、ガチャガチャの中が一番ストックの少ないキャラだけになり、その後に最後の1回を引いてコンプリート)

パターンの時ですね。

なので、コンプリートするまでに最も運が悪いと

p1+p2+...+pn - min(p1,p2,...,pn) + 1

回引くことになります。

計算は多分あっていると思います。

swiftはよくわかりませんので、実装はお任せ致します。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.01%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる