Загрузка...

Probably Dice - задача

Тема в разделе Python создана пользователем oriole 30 июл 2019. 479 просмотров

Загрузка...
  1. oriole
    oriole Автор темы 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) - время ожидания может достигать нескольких десятков минут! Используйте принцип динамического программирования, например как здесь.

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

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

    Пример:
    Код

    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


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

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

    Код
    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 30 июл 2019 ♡ Лучший обменник zelenka.guru/threads/663277 0 14 окт 2017
    Тут мало кто поможет с кодингом. Одни школьники. Советую прочекать CyberForum или StackoverFlow, там точно есть кто шарит, в отличии от лулза :pepe_fat:
     
  3. Пиво_inactive2486604
    Пиво_inactive2486604 30 июл 2019 Заблокирован(а) 129 21 июл 2019
    Это шо такое?! Ахуеть я не шарю, но ты меня впечатлил
     
  4. oriole
    oriole Автор темы 1 авг 2019 был(а) давно
    Код
    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
    --- Сообщение объединено с предыдущим 1 авг 2019
    вот что получилось
    --- Сообщение объединено с предыдущим 1 авг 2019
    [IMG]
     
  5. oriole
    oriole Автор темы 1 авг 2019 был(а) давно
    Код
    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
     
Top