問題[Pythonの]おそらくダイスにCheckiOソリューション


CheckiOは、それによってあなたのコーディングスキルを向上させること、困難な課題と面白いタスクに対処するためのコードゲーム、PythonとJavaScriptに初心者から上級プログラマを対象として、このブログでは、チェックポイントと実装コードで問題を行うPythonで自分の考えを記録することが主です他の偉大な神はコードを書いたから、だけでなく、学びます。

CheckiO公式サイト: https://checkio.org/

マイCheckiOホーム: https://py.checkio.org/user/TRHX/

列のCheckiO問題の解決シリーズ: https://itrhx.blog.csdn.net/category_9536424.html

CheckiO問題のソースへのすべてのソリューション: https://github.com/TRHX/Python-CheckiO-Exercise


タイトル説明

[おそらくダイス]:ダイスの数、顔の各ダイスの数、目標数の確率を計算するために、N投ダイス、各ダイス一緒に、:計算確率ダイス3つのパラメータが与えられると、ヒットポイント点の数と、その後ヒットがすべての場合に算出される目標、同様に、結果の精度を打つ確率が4桁でなければならない場合、すなわち、±0.0001は、例えば、2つのダイス6に直面スロー、および指し確率は2/36または5.56パーセントである、あなたは0.0556に返す必要があります。
ここに画像を挿入説明
[リンク] https://py.checkio.org/mission/probably-dice/

[入力]:3つのパラメータを:ダイスの数、ダイスの各々の面の数を計算する確率にターゲットの数、整数であります

[出力]:ヒットの確率は、浮動小数点

【前提】:1≤dice_number≤10、2つの≤辺≤20; 0≤目標<1000年

[例]

probability(2, 6, 3) == 0.0556  # 2 six-sided dice have a 5.56% chance of totalling 3
probability(2, 6, 4) == 0.0833
probability(2, 6, 7) == 0.1667
probability(2, 3, 5) == 0.2222  # 2 three-sided dice have a 22.22% chance of totalling 5
probability(2, 3, 7) == 0       # The maximum you can roll on 2 three-sided dice is 6
probability(3, 6, 7) == 0.0694
probability(10, 10, 50) == 0.0375

コードの実装

def probability(dice_number, sides, target):
    dic = {}
    def calculation(dice_number, sides, target):
        if dice_number > target or dice_number * sides < target:
            return 0
        if dice_number == 1:
            return 1
        if (dice_number, sides, target) in dic:
            return dic[(dice_number, sides, target)]
        else:
            dic[(dice_number, sides, target)] = sum(calculation(dice_number - 1, sides, target - i) for i in range(1, sides + 1))
        return dic[(dice_number, sides, target)]
    return calculation(dice_number, sides, target) / sides ** dice_number


if __name__ == '__main__':
    #These are only used for self-checking and are not necessary for auto-testing
    def almost_equal(checked, correct, significant_digits=4):
        precision = 0.1 ** significant_digits
        return correct - precision < checked < correct + precision
        
    assert(almost_equal(probability(2, 6, 3), 0.0556)), "Basic example"
    assert(almost_equal(probability(2, 6, 4), 0.0833)), "More points"
    assert(almost_equal(probability(2, 6, 7), 0.1667)), "Maximum for two 6-sided dice"
    assert(almost_equal(probability(2, 3, 5), 0.2222)), "Small dice"
    assert(almost_equal(probability(2, 3, 7), 0.0000)), "Never!"
    assert(almost_equal(probability(3, 6, 7), 0.0694)), "Three dice"
    assert(almost_equal(probability(10, 10, 50), 0.0375)), "Many dice, many sides"

大神解答

大神解答 NO.1

from numpy.polynomial.polynomial import polypow

def probability(dice_number, sides, target):
    """ The number of ways to obtain x as a sum of n s-sided dice
    is given by the coefficients of the polynomial:
    
    f(x) = (x + x^2 + ... + x^s)^n
    """
    
    # power series (note that the power series starts from x^1, therefore
    # the first coefficient is zero)
    powers = [0] + [1] * sides
    # f(x) polynomial, computed used polypow in numpy
    poly = polypow(powers, dice_number)

    # check if the target is in valid range
    # if an IndexError is raised, it means that the target cannot be reached,
    # therefore the probability is 0
    try:
        return poly[target] / sides ** dice_number
    except IndexError:
        return 0

大神解答 NO.2

from functools import lru_cache

@lru_cache(maxsize=None)
def probability(dice_number, sides, target):
    if dice_number == 1:
        return (1 <= target <= sides**dice_number)/sides
    return sum([probability(dice_number-1, sides, target-x)
                for x in range(1, sides+1)])/sides

大神解答 NO.3

from scipy.special import binom as b
probability=lambda n,s,p:sum((-1)**x*b(n, x)*\
    b(p-s*x-1,n-1)for x in range((p-n)//s+1))/s**n  

大神解答 NO.4

probability,C=lambda n,s,t:sum((-1)**k*C(n,k)*C(t-k*s-1,n-1)for k
in range(1+(t-n)//s))/s**n,lambda n,k:n*C(n-1,k-1)//k if k else 1
149元記事公開 ウォンの賞賛518 ビューに46万+を

おすすめ

転載: blog.csdn.net/qq_36759224/article/details/103583601