{ "cells": [ { "cell_type": "markdown", "id": "b005228c-caa6-41ac-858b-2592f39ac1bc", "metadata": {}, "source": [ "# SW10 - Flipped Classroom\n", "\n", "*This Jupyter notebook is intended for practicing the theory accompanying the slides and is used as a “practical review of the theory input”. There are no sample solutions and the file is not corrected and does not have to be handed in.*\n", "\n", "In SW10, the theory script includes various simulations that are intended to illustrate the theoretical content of the lecture script [SW10_Probability](SW10_Probability.pdf)." ] }, { "cell_type": "markdown", "id": "a1154dff", "metadata": { "tags": [] }, "source": [ "# What is randomness?\n", "We will use a very simple example to examine what random or randomness is and how we can recognize it. We will also see whether humans can create randomness.\n", "\n", "In very vague terms, we call a system random if its behavior is unpredictable. In other words, it does not (exclusively) follow a law that allows us to deduce with certainty its future behavior from present conditions. It is a philosophical question whether this inability is due to a lack of knowledge (information) or whether it is a fundamental property of a system.\n", "\n", "Classical (Newtonian) mechanics is deterministic, i.e. randomness does not exist in theory. From the conditions of all the particles involved in a system at one point in time (initial conditions), the behavior of the system for the entire future can in principle be precisely predicted. Of course, in practice most systems are so complex that we never have all the information at our disposal. Even measured values such as the position of a particle are never completely precise. Randomness can arise from this lack of information, see the coin toss.\n", "\n", "According to the current state of knowledge, however, there is *real randomness* in quantum physics, for example in radioactive decay. The time at which a radioactive atom decays is *fundamentally* random. The unpredictability is therefore not due to a lack of information." ] }, { "cell_type": "markdown", "id": "8787f701", "metadata": {}, "source": [ "## Real coin toss\n", "In practice, a coin toss is a typical example of a random experiment. As the position, speed and orientation of the coin is never exactly the same for two tosses and this information is not known exactly, it is practically impossible to predict which side (heads or tails) the coin will come to rest on.\n", "\n", "Please try it out. Take any coin and define one side as the result $0$ and the other as the result $1$. Now toss the coin $20$ times and note the results. Now define a `numpy` array with your results:" ] }, { "cell_type": "code", "execution_count": null, "id": "db5dfc63", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "import pandas as pd\n", "\n", "coin_toss = np.array([\"\"\"Insert your results of the coin toss here\"\"\"])\n", "print(coin_toss)" ] }, { "cell_type": "markdown", "id": "905d4669", "metadata": {}, "source": [ "We calculate the relative frequencies of the results $0$ and $1$:" ] }, { "cell_type": "code", "execution_count": null, "id": "085900dd", "metadata": {}, "outputs": [], "source": [ "rel_frequ_coin = np.bincount(coin_toss)/len(coin_toss)\n", "print(rel_frequ_coin)" ] }, { "cell_type": "markdown", "id": "7c6dbb6b", "metadata": {}, "source": [ "We plot a bar chart to show these relative frequencies graphically:" ] }, { "cell_type": "code", "execution_count": null, "id": "669ab72f", "metadata": {}, "outputs": [], "source": [ "fig, ax = plt.subplots()\n", "ax.bar(['0','1'],rel_frequ_coin)\n", "plt.title('Real coin toss')\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "f7b6e860", "metadata": {}, "source": [ "Does this meet your expectations?\n", "\n", "If the coin is perfectly symmetric, then there is no reason to assume that one side will fall more often than the other. Therefore, it is plausible to expect both sides to fall equally often, so the relative frequencies are around $0.5$. Of course, it is not to be expected that they are exactly equal to $0.5$, otherwise the result could hardly be called random. If a $0$ appears twice in a row, then a $1$ would be more likely to follow, because the $0$ is “used up”. The next result is therefore no longer purely random.\n", "\n", "Let's take a look at how a result differs from the previous one. So we look at the differences between successive sequence elements:" ] }, { "cell_type": "code", "execution_count": null, "id": "53aa12f0", "metadata": {}, "outputs": [], "source": [ "diff_coin_toss = np.diff(coin_toss)\n", "print(diff_coin_toss)" ] }, { "cell_type": "markdown", "id": "c36384be", "metadata": {}, "source": [ "The possible differences are $-1$, $0$ and $1$. We plot another bar chart with the relative frequencies:" ] }, { "cell_type": "code", "execution_count": null, "id": "65f8c015", "metadata": {}, "outputs": [], "source": [ "rel_frequ_diff_coin = np.bincount(diff_coin_toss+1)/len(diff_coin_toss) # calculate relative frequencies; for unknown reasons, the method bincount() cannot treat negative values!\n", "\n", "fig, ax = plt.subplots()\n", "ax.bar(['-1','0','1'],rel_frequ_diff_coin)\n", "plt.title('Differences in the coin toss sequence')\n", "plt.show()\n" ] }, { "cell_type": "markdown", "id": "aee9bdd6", "metadata": {}, "source": [ "Note that we have added $1$ when calculating the relative frequencies of the differences, as the `numpy.bincount()` method cannot process negative numbers for unknown reasons.\n", "\n", "Does the result meet your expectations?\n", "\n", "Perhaps you need to think briefly about why the difference $0$ occurs more frequently than the other two. Approximately how often should it occur?\n", "\n", "Since there are two possibilities for the difference $0$, namely $0,0$ and $1,1$, and only one possibility for the difference $1$, i.e., $0,1$, you would expect the difference $0$ to occur twice as often as the difference $1$. An analogous argument applies to the difference $-1$.\n", "\n", "If you have “cheated” and thought up a sequence of zeros and ones without flipping a coin, then you have probably made sure that the two outcomes are approximately equally frequent. But you probably switched too often between the results, because it doesn't feel random to us if one result is repeated more often. Therefore, in this case you get the difference $0$ less than half of the time. This is an indication that the sequence is not completely random after all." ] }, { "cell_type": "markdown", "id": "2c9a7512", "metadata": {}, "source": [ "## Simulated coin toss\n", "A computer is first and foremost a completely deterministic system. It behaves according to an algorithm that prescribes a unique behavior in each step. The result of this step is determined if the complete state of the computer before this step is known, i.e. in particular the contents of each individual memory cell. For this reason, a computer cannot generate randomness by itself.\n", "\n", "However, there are mathematical procedures, so-called *random number generators*, which generate so-called *pseudo-random numbers*. Such a procedure always stores a momentary number that is assumed to be random. From this, a mathematical rule is used to calculate the next number, which looks random to us. The next number is calculated from this number according to the same rule, and so on. It is therefore a completely deterministic system. If you start with the same number, the entire sequence is determined. Nevertheless, the sequence fulfills many important properties of a random sequence.\n", "\n", "The number with which the random number generator starts is called the *seed*. In order to obtain good pseudo-random numbers, the seed should be chosen as a “truly” random number, for example the hundredth digit of the current time. In class, however, we often choose the same seed so that the results are the same and reproducible for everyone.\n", "\n", "Let's define a random number generator in Python:" ] }, { "cell_type": "code", "execution_count": null, "id": "9a9f6755", "metadata": {}, "outputs": [], "source": [ "rng = np.random.default_rng(42)" ] }, { "cell_type": "markdown", "id": "2db301b5", "metadata": {}, "source": [ "The number $42$ is the seed. It can also be omitted, in which case any default value is used.\n", "\n", "We can now simulate a repeated coin toss by generating a $0$-$1$ random sequence. Because it is so convenient, we create $1000$ coin tosses:" ] }, { "cell_type": "code", "execution_count": null, "id": "b759e18b", "metadata": {}, "outputs": [], "source": [ "sim_coin_toss = rng.choice(2,size=1000)\n", "print(sim_coin_toss)" ] }, { "cell_type": "markdown", "id": "f36fb754", "metadata": {}, "source": [ "Now we repeat the same analysis as for the real coin toss:" ] }, { "cell_type": "code", "execution_count": null, "id": "546f8665", "metadata": {}, "outputs": [], "source": [ "rel_frequ_sim_coin = np.bincount(sim_coin_toss)/len(sim_coin_toss)\n", "\n", "fig, ax = plt.subplots()\n", "ax.bar(['0','1'],rel_frequ_sim_coin)\n", "plt.title('Simulated coin toss')\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": null, "id": "40bfd571", "metadata": {}, "outputs": [], "source": [ "diff_sim_coin_toss = np.diff(sim_coin_toss)\n", "\n", "rel_frequ_diff_sim_coin = np.bincount(diff_sim_coin_toss+1)/len(diff_sim_coin_toss)\n", "\n", "fig, ax = plt.subplots()\n", "ax.bar(['-1','0','1'],rel_frequ_diff_sim_coin)\n", "plt.title('Differences in the simulated coin toss sequence')\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "e879da05", "metadata": {}, "source": [ "We can see from the result that the relative frequency of the difference zero is almost exactly $0.5$, as it should be for a true random sequence." ] }, { "cell_type": "markdown", "id": "86323624", "metadata": { "tags": [] }, "source": [ "# Randomness in prime numbers\n", "A prime number is a natural number that has exactly two divisors, namely $1$ and itself. The sequence of prime numbers begins with\n", "\n", "$$\n", "2, 3, 5, 7, 11, 13, 17, 19, 23, 29, \\ldots\n", "$$\n", "\n", "Although this sequence is purely deterministic, there does not appear to be a simple pattern that could be used to determine the next largest prime number. The distribution of prime numbers within the natural numbers looks *random* to us. We would like to generate a $0$-$1$ sequence from the prime numbers, which also looks random to our eyes. We want to test this with the above analysis.\n", "First of all, it is clear that $2$ is the only even prime number, because every other prime number must not be divisible by $2$. Similarly, $3$ is the only prime number divisible by $3$. So if we consider all prime numbers $>3$, then only the remainders $1$ and $2$ occur when dividing by $3$. If we subtract $1$ from this, then we have a $0$-$1$ sequence. We now generate this. We read in the file `primes.csv`, which contains a slightly longer beginning of the prime number sequence. Make sure that the file is in the same directory as this Jupyter notebook." ] }, { "cell_type": "code", "execution_count": null, "id": "69fedfa6", "metadata": {}, "outputs": [], "source": [ "data = pd.read_csv(\"primes.csv\", sep=\",\", header=None)\n", "primes = data.values[0]\n", "print(primes)" ] }, { "cell_type": "markdown", "id": "387b5483", "metadata": {}, "source": [ "We remove the $2$ and the $3$:" ] }, { "cell_type": "code", "execution_count": null, "id": "8dcb208e", "metadata": {}, "outputs": [], "source": [ "primes = primes[2:]" ] }, { "cell_type": "markdown", "id": "413ff9e3", "metadata": {}, "source": [ "We take the remainder of each prime number when dividing by $3$ with the method `numpy.mod()` and subtract $1$:" ] }, { "cell_type": "code", "execution_count": null, "id": "0253acbd", "metadata": {}, "outputs": [], "source": [ "primes_toss = np.mod(primes,3) - 1\n", "print(primes_toss)" ] }, { "cell_type": "markdown", "id": "c7ea66bf", "metadata": {}, "source": [ "That looks pretty random again. Let's take a look at the distribution of the zeros and ones:" ] }, { "cell_type": "code", "execution_count": null, "id": "4fef2b89", "metadata": {}, "outputs": [], "source": [ "rel_frequ_primes = np.bincount(primes_toss)/len(primes_toss) # calculate relative frequencies\n", "\n", "fig, ax = plt.subplots()\n", "ax.bar(['0','1'],rel_frequ_primes)\n", "plt.title('Rest von Primzahlen beim Teilen durch 3 (-1)')\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "27a66218", "metadata": {}, "source": [ "The two remainders therefore occur with fairly equal frequency. Let's look at the consecutive differences as above:" ] }, { "cell_type": "code", "execution_count": null, "id": "ab7afd6e", "metadata": {}, "outputs": [], "source": [ "diff_primes_toss = np.diff(primes_toss) # take consecutive differences\n", "\n", "rel_frequ_diff_primes = np.bincount(diff_primes_toss+1)/len(diff_primes_toss) # calculate relative frequencies; for unknown reasons, the method bincount() cannot treat negative values!\n", "\n", "fig, ax = plt.subplots()\n", "ax.bar(['-1','0','1'],rel_frequ_diff_primes)\n", "plt.title('Differences of the prime number sequence')\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "7db96160", "metadata": {}, "source": [ "Here we recognize that it is actually **not** a random sequence, since the difference $0$ occurs much less frequently than in half of all cases." ] }, { "cell_type": "code", "execution_count": null, "id": "9ffef326-f5b5-4731-8ca3-b5dee006fa56", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "id": "ab45ac28-a4aa-4921-9f6e-9030d0956a53", "metadata": { "tags": [] }, "source": [ "# Probability\n", "We now want to explore the concept of probability through a simulation. We will use the example of two fair coins." ] }, { "cell_type": "markdown", "id": "da984e8c-e67e-4774-bbeb-467564d40f0d", "metadata": { "tags": [] }, "source": [ "## Two coins\n", "We call a coin fair if the probability of heads ($K$) and tails ($Z$) are equal. Since probabilities are positive and the sum of the probabilities of all possible elementary events is equal to $1$, it follows that both probabilities must be equal to $\\frac{1}{2}$. We write\n", "\n", "$$\n", "P(K)=\\frac{1}{2} \\quad\\text{und}\\quad P(Z)=\\frac{1}{2}\n", "$$\n", "\n", "We now simulate the toss of two fair coins. First, let's think about how to represent an elementary event. If we toss *one* coin twice, then it makes sense to write the two results one after the other. The basic space is thus\n", "\n", "$$\n", "\\Omega = \\{KK,KZ,ZK,ZZ\\}\n", "$$\n", "\n", "We now convince ourselves that this is the identical situation as for a single toss of two coins. If the coins look the same, we cannot distinguish which shows heads and which shows tails (if we see both), but of course the coins are still two different physical objects. If we were to color them differently (e.g. red and green), then we could again distinguish the results $KZ$ and $ZK$. This is just a practical difference that does not change the probabilities.\n", "\n", "We now define the space of elementary events in Python with the more descriptive names $K$ and $Z$. We represent an elementary event as a tuple `(x,y)`, where `x` or `y` is either the string `'K'` or the string `'Z'`. We represent the sample space as a list `Omega` with all possible tuples." ] }, { "cell_type": "code", "execution_count": null, "id": "12a1d22e-572a-4c28-b76c-928c110b1c32", "metadata": {}, "outputs": [], "source": [ "one_coin = ['K','Z']\n", "Omega = [(x,y) for x in one_coin for y in one_coin]\n", "print(Omega)" ] }, { "cell_type": "markdown", "id": "b216faba-7814-4f81-9860-e76e1e6cede7", "metadata": {}, "source": [ "We can now conveniently make a random selection from this basic space:" ] }, { "cell_type": "code", "execution_count": null, "id": "0f895f6f-5b67-4e3e-ba01-d249ca60bf89", "metadata": {}, "outputs": [], "source": [ "two_coins_toss = rng.choice(Omega,size=100)\n", "print(two_coins_toss[:10])" ] }, { "cell_type": "markdown", "id": "37ac59a0-cef1-4897-8a19-9a020982e9d8", "metadata": {}, "source": [ "To determine the relative frequencies of an elementary event, based on the absolute frequencies to be determined first, we cannot use the `numpy.bincount()` method directly, because unfortunately this only works for non-negative integers. We must therefore first generate a list of integers. We take advantage of the fact that Boolean values `False` and `True` are automatically cast as `0` and `1` respectively.\n", "\n", "First, we want to determine how often $KK$ has occurred. To do this, we select those pairs `pair` that are equal to `('K','K')`. The technical difficulty here is that the elementary events are tuples and not arrays. So we convert the array into a tuple with `tuple(pair)`:" ] }, { "cell_type": "code", "execution_count": null, "id": "7f66e5db-afb1-46bb-9e0e-08a840b99972", "metadata": {}, "outputs": [], "source": [ "print([tuple(pair)==('K','K') for pair in two_coins_toss])" ] }, { "cell_type": "markdown", "id": "8733dcaa-b5ce-4301-91be-7a2b3d61d412", "metadata": {}, "source": [ "So now we have a list of Boolean values. Since `False` is cast as `0` and `True` as `1`, we can count the frequency of `True` with `sum()`." ] }, { "cell_type": "code", "execution_count": null, "id": "2eb82ad8-3d96-4758-a475-e98d046b2d14", "metadata": {}, "outputs": [], "source": [ "count_bothK = sum([tuple(pair)==('K','K') for pair in two_coins_toss])\n", "rel_frequ_bothK = count_bothK/len(two_coins_toss)\n", "print(rel_frequ_bothK)" ] }, { "cell_type": "markdown", "id": "99e8956b-33fe-4fa5-986e-b331211176e0", "metadata": {}, "source": [ "The relative frequency for `['K','K']` is therefore $0.24$." ] }, { "cell_type": "markdown", "id": "71d35ddd-3e51-41dd-a445-f40eb371bb5d", "metadata": {}, "source": [ "Run the simulation again with $1000$ repetitions. What do you expect?" ] }, { "cell_type": "markdown", "id": "006922cf-d797-4c80-ac51-0638507cfd81", "metadata": { "tags": [] }, "source": [ "# Combinatorics\n", "Counting combinatorics deals with methods that can be used to count items systematically. This is important because the quantities are often so large that manual counting would be too time-consuming. The items to be counted here are often put together from other elements by certain constructions, i.e. *combined*. This is where the name *combinatorics* comes from. " ] }, { "cell_type": "markdown", "id": "29cdaa91-be15-42fc-989b-84322279c670", "metadata": { "tags": [] }, "source": [ "## How many words with $4$ letters are there?\n", "We are not talking about words in a natural language here, but pure letter combinations. For the sake of simplicity, we are only looking at the $26$ capital letters of the alphabet. To count the words, we can consider how we can construct such a word. The *urn model* is helpful here. Let's imagine that we label $26$ balls with one letter each and place them in a bowl (mathematicians strangely call the bowl an *urn*). Then we can determine the first letter of the word by pulling a ball out of the urn and writing down its letter. Then we put the ball back and draw another ball. This provides the second letter and so on. For the first letter we have $26$ possibilities, for each choice we have again $26$ possibilities for the second letter, so in total $26\\cdot 26=26^2$. And so on, so for the $4$ letters we have\n", "$$\n", "26\\cdot 26\\cdot 26\\cdot 26=26^4\n", "$$\n", "possibilities, so" ] }, { "cell_type": "code", "execution_count": null, "id": "f85432e1-b0d4-4918-a24a-dd869fd5ebb8", "metadata": {}, "outputs": [], "source": [ "26**4" ] }, { "cell_type": "markdown", "id": "56065920-2a18-4e54-bfbb-74d5d33fb165", "metadata": {}, "source": [ "In this example, we have drawn with a backspace, because a word can contain the same letter several times." ] }, { "cell_type": "markdown", "id": "a4ea60be-f5fa-4cea-bda6-e8401a0d5336", "metadata": { "tags": [] }, "source": [ "## How many words with $4$ **different** letters are there?\n", "Here we can imagine that we draw balls from the urn without putting it back. A given ball can only be drawn once, so the resulting word has no repetition of letters. For the first letter we again have $26$ possibilities, but for the second only $26-1=25$, as a ball has already been removed from the urn. For the third letter, we again have one less available, so $26-2=24$ and so on. So we get\n", "$$\n", "26\\cdot 25\\cdot 24\\cdot 23\n", "$$\n", "words with $4$ different letters." ] }, { "cell_type": "code", "execution_count": null, "id": "5021e134-4dc0-426d-a05c-dce0b05b322b", "metadata": {}, "outputs": [], "source": [ "26*25*24*23" ] }, { "cell_type": "markdown", "id": "c7d43353-b867-446a-a675-c64b14f4c946", "metadata": { "tags": [] }, "source": [ "## How many permutations of all letters are there?\n", "A *permutation* or *arrangement* of all letters is a word in which each letter occurs exactly once, so it must have the length $26$. If we ask ourselves how many such words there are, then by analogous considerations as above we arrive at the result\n", "$$\n", "26\\cdot 25\\cdot 24\\cdot 23\\cdots 3 \\cdot 2\\cdot 1\n", "$$\n", "If we want to calculate this with Python as above, the typing work becomes quite tedious. We therefore use the *factorial* $26!$, i.e. the product of all integers from $1$ to $26$." ] }, { "cell_type": "code", "execution_count": null, "id": "a762ee47-02b5-43c1-a078-1072b8f694a6", "metadata": {}, "outputs": [], "source": [ "import math\n", "math.factorial(26)" ] }, { "cell_type": "markdown", "id": "d66aee44-6f32-46ae-bdff-3cdf23c171a8", "metadata": {}, "source": [ "This is the number of all *permutations* of the $26$ letters." ] }, { "cell_type": "markdown", "id": "bc99adde-216a-476d-b63f-addd1c7e3dba", "metadata": {}, "source": [ "We can also calculate the number of words with $10$ different letters using the factorial, because\n", "$$\n", "26\\cdot 25\\cdots 18\\cdot 17 = \\frac{26\\cdot 25\\cdots 18\\cdot 17\\cdot 16\\cdot 15\\cdots 2\\cdot 1}{16\\cdot 15\\cdots 2\\cdot 1} = \\frac{26!}{16!}\n", "$$\n", "So this number is" ] }, { "cell_type": "code", "execution_count": null, "id": "0326f85a-8910-46be-b3bc-044ee20f36d2", "metadata": {}, "outputs": [], "source": [ "math.factorial(26)//math.factorial(16)" ] }, { "cell_type": "markdown", "id": "9fbcce24-3fe3-4b2a-9560-050b7c20ba42", "metadata": { "tags": [] }, "source": [ "## How many possible HSLU handball teams are there?\n", "According to the website (source: https://www.hslu.ch/de-ch/hochschule-luzern/ueber-uns/portraet/jahresbericht-2023/), HSLU had exactly $8118$ students in the year $2023$. A handball team consists of $7$ players. How many handball teams can be formed from HSLU students?\n", "\n", "In contrast to the previous examples, the order of the players is now irrelevant (at least if we ignore which position they play in the team). So we draw $7$ from the $8118$ balls (students) without putting them back. If we first consider the order, then we have\n", "$$\n", "\\frac{8118!}{8111!}\n", "$$\n", "draws. But many of these draws lead to the same team, namely if they both consist of the same $7$ students but were drawn in a different order. These are all permutations of each other. This means that the draws are combined into groups of $7!$ draws each. So there are\n", "$$\n", "\\frac{8118!}{8111!\\cdot 7!}\n", "$$\n", "teams." ] }, { "cell_type": "markdown", "id": "4156dc38-73fd-49b9-a431-4e7c8eef39f7", "metadata": {}, "source": [ "The formula for the number of handball teams is the binomial coefficient\n", "$$\n", "\\binom{8118}{7}\n", "$$\n", "which we can calculate like this:" ] }, { "cell_type": "code", "execution_count": null, "id": "5afbed29-8f30-43cc-97b0-889fbab1583d", "metadata": {}, "outputs": [], "source": [ "math.comb(8118,7)" ] }, { "cell_type": "markdown", "id": "d31eb5d3-0dfa-4a1d-b09c-d772e34316f5", "metadata": {}, "source": [ "For control purposes, we can also calculate with factorials:" ] }, { "cell_type": "code", "execution_count": null, "id": "5a8753d6-6567-4ce6-a79c-a4a384552644", "metadata": {}, "outputs": [], "source": [ "math.factorial(8118)//(math.factorial(8111)*math.factorial(7))" ] }, { "cell_type": "markdown", "id": "425fc389-5c72-4ade-9313-e64ff7a62ec5", "metadata": { "tags": [] }, "source": [ "## How many products of the variables $a,b,c,d$ with $8$ factors are there?\n", "We can construct such a product by drawing $8$ balls from an urn with $4$ balls (variables), because there can be repetitions in the product (at least one variable **must** even be repeated). The order of the factors does not play a role in a product, so the order is not taken into account in the draw. If we describe the balls with the numbers $1$ to $4$ instead of the variables $a$ to $d$, then a possible draw is\n", "$$\n", "1,1,2,3,3,4,4,4\n", "$$\n", "where we have sorted the numbers, so the number of products we are looking for is equal to the number of weakly ascending sequences of the numbers $1,2,3,4$. If we now add $1$ to the second number of the sequence, $2$ to the third number, $3$ to the fourth number and so on, we get a truly ascending sequence of numbers between $1$ and $11$. From the above example we get\n", "$$\n", "1,2,4,6,7,9,10,11\n", "$$\n", "So the number you are looking for is equal to the number of such sequences. However, this is the number of draws of $8$ balls from an urn with $11$ balls without putting them back and without sequence. So the number you are looking for is equal to\n", "$$\n", "\\binom{11}{8}\n", "$$" ] }, { "cell_type": "code", "execution_count": null, "id": "1895874d-3462-475d-9bea-fcb74b5828d8", "metadata": { "tags": [] }, "outputs": [], "source": [ "math.comb(11,8)" ] } ], "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.8.18" } }, "nbformat": 4, "nbformat_minor": 5 }