{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "96af9372-3368-4dfd-8882-7d6931539cf3",
   "metadata": {},
   "outputs": [],
   "source": [
    "import itertools"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "15c9f8d0-4bbe-41e5-897b-743088725e4a",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "854ab061-f9a1-4b74-b994-4938e21387c0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[('H', 'H'), ('H', 'T'), ('T', 'H'), ('T', 'T')]"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(itertools.product([\"H\", \"T\"], repeat=2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "04d9d096-e761-44a1-9449-9b9abf48eba5",
   "metadata": {},
   "outputs": [],
   "source": [
    "microstates = np.array(list(itertools.product([\"H\", \"T\"], repeat=4)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "4038e844-4bd5-4a41-a1a8-28c0b8f9278e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([['H', 'H', 'H', 'H'],\n",
       "       ['H', 'H', 'H', 'T'],\n",
       "       ['H', 'H', 'T', 'H'],\n",
       "       ['H', 'H', 'T', 'T'],\n",
       "       ['H', 'T', 'H', 'H'],\n",
       "       ['H', 'T', 'H', 'T'],\n",
       "       ['H', 'T', 'T', 'H'],\n",
       "       ['H', 'T', 'T', 'T'],\n",
       "       ['T', 'H', 'H', 'H'],\n",
       "       ['T', 'H', 'H', 'T'],\n",
       "       ['T', 'H', 'T', 'H'],\n",
       "       ['T', 'H', 'T', 'T'],\n",
       "       ['T', 'T', 'H', 'H'],\n",
       "       ['T', 'T', 'H', 'T'],\n",
       "       ['T', 'T', 'T', 'H'],\n",
       "       ['T', 'T', 'T', 'T']], dtype='<U1')"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "microstates"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "c60b3937-bc36-40aa-9331-742efb878637",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "16"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(microstates)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "e6760ef4-8639-4932-9f0b-7deb8ea6705b",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ True,  True,  True,  True],\n",
       "       [ True,  True,  True, False],\n",
       "       [ True,  True, False,  True],\n",
       "       [ True,  True, False, False],\n",
       "       [ True, False,  True,  True],\n",
       "       [ True, False,  True, False],\n",
       "       [ True, False, False,  True],\n",
       "       [ True, False, False, False],\n",
       "       [False,  True,  True,  True],\n",
       "       [False,  True,  True, False],\n",
       "       [False,  True, False,  True],\n",
       "       [False,  True, False, False],\n",
       "       [False, False,  True,  True],\n",
       "       [False, False,  True, False],\n",
       "       [False, False, False,  True],\n",
       "       [False, False, False, False]])"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Filter rows where count of 'H' equals 3\n",
    "# First, generate an array of True/False entries \n",
    "(microstates==\"H\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "6e8e70a3-5f0a-44e3-85a4-2945f003bca6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([8, 8, 8, 8])"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Now count how many 'H's there are on each column.  (Column is \"axis=0\").  There are 4 columns, so we get \n",
    "# an array of 4 counts.  Each column has 8 heads.\n",
    "(microstates==\"H\").sum(axis=0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "938238ba-55cb-4ffa-b587-50bdfed1a23b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0])"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Now count how many 'H's there are on each row.  (Row is \"axis=1\").  There are 16 rows, so we get an\n",
    "# array of 16 counts.  (axis=0 would count how many 'H's are in each column.  There are 4 columns, so\n",
    "# you would get an array of 4 elements.)\n",
    "(microstates==\"H\").sum(axis=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "ec0ec2e9-6549-49b4-aef3-0f77e8f27a9f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Now, make another True/False array for whether that count is 3.\n",
    "is_three = (microstates==\"H\").sum(axis=1) == 3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "b7430dd7-1054-4624-9259-e4b5d0cd311c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([['H', 'H', 'H', 'T'],\n",
       "       ['H', 'H', 'T', 'H'],\n",
       "       ['H', 'T', 'H', 'H'],\n",
       "       ['T', 'H', 'H', 'H']], dtype='<U1')"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Finally, use that array to pick out the True elements from the microstates array\n",
    "three_heads = microstates[is_three]\n",
    "three_heads"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "2ba6e0fb-e4d6-449d-8795-c2855019f428",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([['H', 'H', 'H', 'T'],\n",
       "       ['H', 'H', 'T', 'H'],\n",
       "       ['H', 'T', 'H', 'H'],\n",
       "       ['T', 'H', 'H', 'H']], dtype='<U1')"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Idiomatically, you would typically do this all as one command:\n",
    "three_heads = microstates[(microstates == \"H\").sum(axis=1) == 3]\n",
    "three_heads"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "a6fda6b4-dd8d-437a-8b54-70ddb987eaab",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[['H' 'H' 'H' 'T']\n",
      " ['H' 'H' 'T' 'H']\n",
      " ['H' 'T' 'H' 'H']\n",
      " ['T' 'H' 'H' 'H']]\n"
     ]
    }
   ],
   "source": [
    "print(three_heads)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "366adc29-bbc5-4cc0-a427-deef32adeb3c",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.14.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
