Загрузка...

Probably Dice - challenge

Thread in Python created by oriole Jul 30, 2019. 489 views

  1. oriole
    oriole Topic starter Jul 30, 2019 был(а) давно
    Вы едете на конвент по настольным играм. Скорее всего, там будет достаточно жесткая конкуренция и поэтому вы решили узнать немного больше о теории вероятности, поскольку вы подозреваете, что в ближайшее время вам придется много раз бросать кости .

    Обычно, при использовании нескольких кубиков, вы просто кидаете их, а результат суммируете. Для того, чтобы начать исследования по вероятности выпадения тех или иных значений игральных костей, напишите функцию, которая принимает на вход число кубиков, число сторон на кубике и исследуемый номер, а возвращает вероятность получения заданного значения. Результат должен возвращаться с точностью в четыре цифры после запятой - ±0.0001. Например, если вы бросили 2 шестигранных кубика, вероятность что выпадет 3 составляет 2/36 или 5,56% в процентном соотношении, соответственно ваша функция должна вернуть число, записанное как ≈0.0556. В дроби 2/36 числитель, это количество возможных вариаций получения числа 3 на двух кубиках (1;2 или 2;1), а знаменатель, это количество возможных комбинаций для 2-х шистигранных кубиков (6**2)

    [IMG]

    Для каждого теста, предполагается, что все кости одинаковы и пронумерованы от 1 и до числа сторон, заданных входными данными включительно. Таким образом, 4-сторонний кубик (D4) будет иметь равные шансы на выпадения чисел 1, 2, 3 или 4. И эти шансы можно оценить как 1/4. А 20-сторонний кубик (D20) будет иметь равные шансы на выпадение любого числа от 1 до 20, которые можно оценить как 1/20.

    Советы: Будьте осторожны, если вы захотите решить эту задачу путем перебора всех возможных вариаций - вам возможно придется очень долго ждать! Например для входных данных (10, 10, 50) - время ожидания может достигать нескольких десятков минут! Используйте принцип динамического программирования, например как здесь.

    На входе: Три аргумента. Количество кубиков, количество сторон на кубике и исследуемое значение как целые числа.

    На выходе: Вероятность получения заданного значения за один бросок игральных костей, как число с плавающей запятой.

    Пример:
    Code

    probability(2, 6, 3) == 0.0556 # на 2-х шестигранных кубиках вероятность выпадения 3 равна 5.56%
    probability(2, 6, 4) == 0.0833
    probability(2, 6, 7) == 0.1667
    probability(2, 3, 5) == 0.2222 # на 2-х трехгранных кубиках вероятность выпадения 5 равна 22.22%
    probability(2, 3, 7) == 0 # на 2-х трехгранных кубиках вы можете выкинуть максимум 6 (3;3)
    probability(3, 6, 7) == 0.0694
    probability(10, 10, 50) == 0.0375


    итак, как решить эту задачу?

    я вот набросал код, он правильлный но пиздец долго будет считать

    Code
    if dice_number == 10:
    for i in range(1,sides+1):
    for j in range(1,sides+1):
    for k in range(1,sides+1):
    for q in range(1,sides+1):
    for w in range(1,sides+1):
    for e in range(1,sides+1):
    for r in range(1,sides+1):
    for t in range(1,sides+1):
    for y in range(1,sides+1):
    if i+j+k+q+w+e+r+t+y == target:
    co += 1
    так вот, как сделать по другому чтобы быстро работало
     
  2. CYBEER_inactive192423
    CYBEER_inactive192423 Jul 30, 2019 ♡ Лучший обменник zelenka.guru/threads/663277 0 Oct 14, 2017
    Тут мало кто поможет с кодингом. Одни школьники. Советую прочекать CyberForum или StackoverFlow, там точно есть кто шарит, в отличии от лулза :pepe_fat:
     
  3. Пиво_inactive2486604
    Это шо такое?! Ахуеть я не шарю, но ты меня впечатлил
     
  4. oriole
    oriole Topic starter Aug 1, 2019 был(а) давно
    Code
    def probability(dice_number, sides, target):
    if sides*dice_number<target or target == 0:
    return 0
    if dice_number == 1:
    return dice_number/sides
    pr = (1/sides ** dice_number)
    print(pr)
    ver = 0
    if target > dice_number*sides//2+1:
    for i in range(dice_number,(dice_number*sides)//2+2):
    ver += pr
    for i in range((dice_number*sides)//2+2,target+1):
    ver -= pr
    print(ver)
    if dice_number>2:
    return ver*dice_number
    return ver
    else:
    for i in range(dice_number,target+1):
    ver += pr
    if dice_number > 2:
    return ver*dice_number

    return ver
    The post was merged to previous Aug 1, 2019
    вот что получилось
    The post was merged to previous Aug 1, 2019
    [IMG]
     
  5. oriole
    oriole Topic starter Aug 1, 2019 был(а) давно
    Code
    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
     
Loading...
Top