{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "b1f2a3c4-5d6e-4f70-8a9b-1c2d3e4f5061",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Роял-флеш               4    0.0002%   1 к 649,740\n",
            "Стрит-флеш             36    0.0014%   1 к 72,193\n",
            "Каре                  624    0.0240%   1 к 4,165\n",
            "Фулл-хаус           3,744    0.1441%   1 к 694\n",
            "Флеш                5,108    0.1965%   1 к 509\n",
            "Стрит              10,200    0.3925%   1 к 255\n",
            "Сет                54,912    2.1128%   1 к 47\n",
            "Две пары          123,552    4.7539%   1 к 21\n",
            "Пара            1,098,240   42.2569%   1 к 2\n",
            "Старшая карта   1,302,540   50.1177%   1 к 2\n",
            "\n",
            "Всего рук: 2,598,960\n"
          ]
        }
      ],
      "source": [
        "from itertools import combinations\n",
        "from collections import Counter\n",
        "\n",
        "RANKS = '23456789TJQKA'\n",
        "SUITS = 'CDHS'\n",
        "DECK = [r + s for r in RANKS for s in SUITS]\n",
        "\n",
        "def classify(hand):\n",
        "    rank_vals = sorted((RANKS.index(r) for r, s in hand), reverse=True)\n",
        "    suits = {s for r, s in hand}\n",
        "    counts = Counter(rank_vals)\n",
        "    count_vals = sorted(counts.values(), reverse=True)\n",
        "\n",
        "    is_flush = len(suits) == 1\n",
        "    unique_vals = sorted(set(rank_vals))\n",
        "    is_straight = (len(unique_vals) == 5 and unique_vals[-1] - unique_vals[0] == 4) \\\n",
        "        or unique_vals == [0, 1, 2, 3, 12]  # колесо А-2-3-4-5\n",
        "    is_royal = is_straight and is_flush and unique_vals == [8, 9, 10, 11, 12]\n",
        "\n",
        "    if is_royal:\n",
        "        return 'Роял-флеш'\n",
        "    if is_straight and is_flush:\n",
        "        return 'Стрит-флеш'\n",
        "    if count_vals == [4, 1]:\n",
        "        return 'Каре'\n",
        "    if count_vals == [3, 2]:\n",
        "        return 'Фулл-хаус'\n",
        "    if is_flush:\n",
        "        return 'Флеш'\n",
        "    if is_straight:\n",
        "        return 'Стрит'\n",
        "    if count_vals == [3, 1, 1]:\n",
        "        return 'Сет'\n",
        "    if count_vals == [2, 2, 1]:\n",
        "        return 'Две пары'\n",
        "    if count_vals == [2, 1, 1, 1]:\n",
        "        return 'Пара'\n",
        "    return 'Старшая карта'\n",
        "\n",
        "result = Counter()\n",
        "for hand in combinations(DECK, 5):\n",
        "    result[classify(hand)] += 1\n",
        "\n",
        "total = sum(result.values())\n",
        "order = ['Роял-флеш', 'Стрит-флеш', 'Каре', 'Фулл-хаус', 'Флеш', 'Стрит',\n",
        "         'Сет', 'Две пары', 'Пара', 'Старшая карта']\n",
        "\n",
        "for name in order:\n",
        "    count = result[name]\n",
        "    odds = f'1 к {round(total / count):,}'\n",
        "    print(f'{name:14s} {count:>10,}   {count/total:>8.4%}   {odds}')\n",
        "\n",
        "print(f'\\nВсего рук: {total:,}')"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "c2e3b4d5-6e7f-4081-9b0c-2d3e4f506172",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Точная вероятность фулл-хауса: 0.1441%\n",
            "\n",
            "    1,000 раздач:   оценка 0.1000%   отклонение 0.0441%\n",
            "   10,000 раздач:   оценка 0.1100%   отклонение 0.0341%\n",
            "  100,000 раздач:   оценка 0.1240%   отклонение 0.0201%\n",
            "1,000,000 раздач:   оценка 0.1495%   отклонение 0.0054%\n"
          ]
        }
      ],
      "source": [
        "import random\n",
        "\n",
        "random.seed(42)\n",
        "\n",
        "def random_hand():\n",
        "    return random.sample(DECK, 5)\n",
        "\n",
        "exact = result['Фулл-хаус'] / total\n",
        "print(f'Точная вероятность фулл-хауса: {exact:.4%}\\n')\n",
        "\n",
        "for n in [1_000, 10_000, 100_000, 1_000_000]:\n",
        "    hits = sum(1 for _ in range(n) if classify(random_hand()) == 'Фулл-хаус')\n",
        "    est = hits / n\n",
        "    print(f'{n:>9,} раздач:   оценка {est:.4%}   отклонение {abs(est - exact):.4%}')"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.12.2"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 5
}
