{
  "chapter": {
    "id": "algorithmique-programmation",
    "level": "terminale-specialite",
    "theme": "Algorithmique et programmation",
    "title": "Algorithmique et programmation",
    "description": "Listes (génération, manipulation, parcours) et algorithmes du\nprogramme : dichotomie, méthodes de Newton et de la sécante, méthode\nd'Euler, méthodes des rectangles et des trapèzes, Monte-Carlo, seuil\nd'une loi binomiale et surréservation, simulation d'échantillons,\nmarche aléatoire, planche de Galton.",
    "parties": [
      {
        "id": "listes",
        "title": "Listes"
      },
      {
        "id": "analyse",
        "title": "Algorithmes d'analyse"
      },
      {
        "id": "probabilites",
        "title": "Algorithmes de probabilités"
      }
    ],
    "prerequisites": [],
    "references": []
  },
  "questions": [
    {
      "id": "q01",
      "difficulty": 1,
      "skills": [
        "liste",
        "comprehension"
      ],
      "title": "Les termes d'une suite en compréhension",
      "partie": "listes",
      "statement": "La suite $(u_n)$ est définie par $u_n = \\dfrac{1}{n + 1}$. Que\ncontient la liste `[1 / (n + 1) for n in range(4)]` ?",
      "options": [
        {
          "text": "Les termes $u_0$, $u_1$, $u_2$ et $u_3$",
          "correct": true,
          "feedback": "Bonne réponse : `n` prend les valeurs $0$ à $3$, soit $1$,\n$0{,}5$, $0{,}333\\ldots$ et $0{,}25$."
        },
        {
          "text": "Les termes $u_1$, $u_2$, $u_3$ et $u_4$",
          "correct": false,
          "feedback": "Erreur : `range(4)` commence à $0$, donc le premier terme est\n$u_0 = 1$."
        },
        {
          "text": "Les termes $u_0$ à $u_4$",
          "correct": false,
          "feedback": "Erreur : `range(4)` produit quatre valeurs, de $0$ à $3$. Le\nterme $u_4$ n'est pas calculé."
        },
        {
          "text": "La somme $u_0 + u_1 + u_2 + u_3$",
          "correct": false,
          "feedback": "Erreur : une liste en compréhension range chaque valeur\nséparément. La somme s'obtiendrait avec `sum`."
        }
      ],
      "explanation": "`[expression for n in range(p)]` fournit la liste des termes\nd'indices $0$ à $p - 1$."
    },
    {
      "id": "q02",
      "difficulty": 2,
      "skills": [
        "liste",
        "produit-cartesien"
      ],
      "title": "Lister des couples",
      "partie": "listes",
      "statement": "Combien d'éléments contient la liste\n`[(a, b) for a in range(1, 4) for b in range(1, 3)]` ?",
      "options": [
        {
          "text": "$6$",
          "correct": true,
          "feedback": "Bonne réponse : $a$ prend $3$ valeurs et $b$ en prend $2$ ; la\nliste contient les $3 \\times 2 = 6$ couples du produit cartésien."
        },
        {
          "text": "$5$",
          "correct": false,
          "feedback": "Erreur : les deux choix se combinent. On multiplie les nombres\nde valeurs, on ne les additionne pas."
        },
        {
          "text": "$12$",
          "correct": false,
          "feedback": "Erreur : les bornes de droite sont exclues : $a$ va de $1$ à\n$3$ et $b$ de $1$ à $2$."
        },
        {
          "text": "$9$",
          "correct": false,
          "feedback": "Erreur : `range(1, 3)` ne produit que $1$ et $2$, soit deux\nvaleurs pour $b$."
        }
      ],
      "explanation": "Deux boucles dans une compréhension parcourent le produit cartésien\n$\\{1, 2, 3\\} \\times \\{1, 2\\}$ : c'est le principe multiplicatif."
    },
    {
      "id": "q03",
      "difficulty": 2,
      "skills": [
        "liste",
        "parcours",
        "condition"
      ],
      "title": "Filtrer une liste",
      "partie": "listes",
      "statement": "Que renvoie `f([3, -1, 4, -5, 2])` ?\n\n```python\ndef f(L):\n    R = []\n    for x in L:\n        if x > 0:\n            R.append(x)\n    return R\n```",
      "options": [
        {
          "text": "`[3, 4, 2]`",
          "correct": true,
          "feedback": "Bonne réponse : la fonction parcourt `L` et recopie dans `R` les\néléments strictement positifs, dans l'ordre."
        },
        {
          "text": "`[-1, -5]`",
          "correct": false,
          "feedback": "Erreur : la condition `x > 0` retient les éléments positifs, pas\nles négatifs."
        },
        {
          "text": "`3`",
          "correct": false,
          "feedback": "Erreur : $3$ est le nombre d'éléments retenus. La fonction\nrenvoie la liste elle-même."
        },
        {
          "text": "`[2, 3, 4]`",
          "correct": false,
          "feedback": "Erreur : la liste `R` n'est pas triée ; l'ordre de `L` est\nconservé."
        }
      ],
      "explanation": "On obtient la même liste en compréhension :\n`[x for x in L if x > 0]`."
    },
    {
      "id": "q04",
      "difficulty": 2,
      "skills": [
        "liste",
        "indices",
        "suite"
      ],
      "title": "Tester la monotonie sur une liste",
      "partie": "listes",
      "statement": "La liste `U` contient les premiers termes d'une suite. Que teste la\nfonction suivante ?\n\n```python\ndef test(U):\n    for i in range(len(U) - 1):\n        if U[i + 1] < U[i]:\n            return False\n    return True\n```",
      "options": [
        {
          "text": "Si la liste est rangée par ordre croissant",
          "correct": true,
          "feedback": "Bonne réponse : la fonction renvoie `False` dès qu'un terme est\nplus petit que le précédent, `True` sinon."
        },
        {
          "text": "Si la suite est croissante pour tout entier $n$",
          "correct": false,
          "feedback": "Erreur : seuls les termes de la liste sont examinés. Le résultat\nne démontre rien sur les termes suivants."
        },
        {
          "text": "Si la liste contient un terme négatif",
          "correct": false,
          "feedback": "Erreur : chaque terme est comparé à son voisin, pas à $0$."
        },
        {
          "text": "Si la suite est décroissante sur la liste",
          "correct": false,
          "feedback": "Erreur : un terme plus petit que son prédécesseur fait renvoyer\n`False`. La fonction reconnaît l'ordre croissant."
        }
      ],
      "explanation": "L'indice `i` s'arrête à `len(U) - 2` pour que `U[i + 1]` existe. Un\ntest sur quelques termes permet de conjecturer, pas de démontrer."
    },
    {
      "id": "q05",
      "difficulty": 3,
      "skills": [
        "liste",
        "suppression",
        "indices"
      ],
      "title": "Insérer et supprimer",
      "partie": "listes",
      "statement": "Que contient `L` après ces instructions ?\n\n```python\nL = [2, 4, 6, 8]\nL.insert(1, 3)\ndel L[3]\n```",
      "options": [
        {
          "text": "`[2, 3, 4, 8]`",
          "correct": true,
          "feedback": "Bonne réponse : après l'insertion de $3$ à l'indice $1$, la\nliste est `[2, 3, 4, 6, 8]` ; l'élément d'indice $3$ est $6$,\nque l'on supprime."
        },
        {
          "text": "`[2, 3, 4, 6]`",
          "correct": false,
          "feedback": "Erreur : `del L[3]` supprime l'élément d'indice $3$, pas le\ndernier."
        },
        {
          "text": "`[2, 3, 6, 8]`",
          "correct": false,
          "feedback": "Erreur : les indices ont été lus sur la liste de départ. Après\nl'insertion, les éléments suivants sont décalés d'un rang."
        },
        {
          "text": "`[3, 2, 4, 6]`",
          "correct": false,
          "feedback": "Erreur : `L.insert(1, 3)` place la valeur $3$ à l'indice $1$,\njuste après le premier élément."
        }
      ],
      "explanation": "`L.insert(i, x)` place `x` à l'indice `i` en décalant la suite ;\n`del L[i]` supprime l'élément d'indice `i`."
    },
    {
      "id": "q06",
      "difficulty": 2,
      "skills": [
        "dichotomie",
        "intervalle"
      ],
      "title": "Le principe de la dichotomie",
      "partie": "analyse",
      "statement": "La fonction $f$ est continue et strictement croissante sur\n$[1\\,;\\,2]$, avec $f(1) < 0 < f(2)$ et $f(1{,}5) > 0$. Dans quel\nintervalle la dichotomie poursuit-elle la recherche de la solution\nde $f(x) = 0$ ?",
      "options": [
        {
          "text": "$[1\\,;\\,1{,}5]$",
          "correct": true,
          "feedback": "Bonne réponse : $f$ change de signe entre $1$ et $1{,}5$, donc la\nsolution s'y trouve d'après le théorème des valeurs\nintermédiaires."
        },
        {
          "text": "$[1{,}5\\,;\\,2]$",
          "correct": false,
          "feedback": "Erreur : $f(1{,}5)$ et $f(2)$ sont tous deux positifs, $f$ ne\ns'annule pas entre ces deux valeurs."
        },
        {
          "text": "$[1{,}25\\,;\\,1{,}75]$",
          "correct": false,
          "feedback": "Erreur : la dichotomie garde toujours une des deux moitiés de\nl'intervalle, celle où $f$ change de signe."
        },
        {
          "text": "$[1\\,;\\,2]$, sans changement",
          "correct": false,
          "feedback": "Erreur : le calcul de $f(1{,}5)$ sert justement à diviser la\nlongueur de l'intervalle par deux."
        }
      ],
      "explanation": "Dichotomie : on calcule l'image du milieu et l'on garde la moitié\naux bornes de laquelle $f$ prend des valeurs de signes contraires."
    },
    {
      "id": "q07",
      "difficulty": 3,
      "skills": [
        "dichotomie",
        "python"
      ],
      "title": "Compléter une dichotomie",
      "partie": "analyse",
      "statement": "La fonction $f$ est continue sur $[a\\,;\\,b]$ et $f(a) \\times f(b) < 0$.\nQuelle ligne compléter ?\n\n```python\ndef dicho(a, b, e):\n    while b - a > e:\n        m = (a + b) / 2\n        if f(a) * f(m) <= 0:\n            b = m\n        else:\n            ...\n    return a, b\n```",
      "options": [
        {
          "text": "`a = m`",
          "correct": true,
          "feedback": "Bonne réponse : si $f(a)$ et $f(m)$ ont le même signe, le\nchangement de signe a lieu entre $m$ et $b$ : on remplace $a$\npar $m$."
        },
        {
          "text": "`b = a`",
          "correct": false,
          "feedback": "Erreur : l'intervalle serait réduit à un point, sans garantie\nqu'il contienne la solution."
        },
        {
          "text": "`m = a`",
          "correct": false,
          "feedback": "Erreur : modifier `m` ne change pas l'intervalle, et la boucle\nne se termine jamais."
        },
        {
          "text": "`a = b`",
          "correct": false,
          "feedback": "Erreur : la boucle s'arrêterait avec un intervalle de longueur\nnulle, placé à la mauvaise extrémité."
        }
      ],
      "explanation": "À chaque tour, la longueur $b - a$ est divisée par $2$ ; la boucle\ns'arrête quand elle ne dépasse plus la précision $e$."
    },
    {
      "id": "q08",
      "difficulty": 2,
      "skills": [
        "dichotomie",
        "nombre-etapes"
      ],
      "title": "Nombre d'étapes d'une dichotomie",
      "partie": "analyse",
      "statement": "On part de l'intervalle $[0\\,;\\,1]$. Combien d'étapes de dichotomie\nfaut-il au minimum pour obtenir un intervalle de longueur inférieure\nou égale à $10^{-3}$ ?",
      "options": [
        {
          "text": "$10$",
          "correct": true,
          "feedback": "Bonne réponse : après $n$ étapes, la longueur vaut\n$\\dfrac{1}{2^n}$ ; $2^9 = 512$ ne suffit pas, $2^{10} = 1\\,024$\nsuffit."
        },
        {
          "text": "$3$",
          "correct": false,
          "feedback": "Erreur : chaque étape divise la longueur par $2$, pas par $10$."
        },
        {
          "text": "$1\\,000$",
          "correct": false,
          "feedback": "Erreur : la longueur ne diminue pas de $10^{-3}$ par étape, elle\nest divisée par $2$."
        },
        {
          "text": "$9$",
          "correct": false,
          "feedback": "Erreur : $\\dfrac{1}{2^9} = \\dfrac{1}{512}$, qui est encore\nsupérieur à $10^{-3}$."
        }
      ],
      "explanation": "On cherche le plus petit $n$ tel que $2^n \\geq 1\\,000$, soit\n$n \\geq \\dfrac{\\ln 1\\,000}{\\ln 2} \\approx 9{,}97$, d'où $n = 10$."
    },
    {
      "id": "q09",
      "difficulty": 3,
      "skills": [
        "newton",
        "iteration"
      ],
      "title": "Une étape de Newton pour racine de trois",
      "partie": "analyse",
      "statement": "La méthode de Newton pour $f(x) = x^2 - 3$ s'écrit\n$x_{n+1} = x_n - \\dfrac{x_n^2 - 3}{2x_n}$. Avec $x_0 = 2$, que vaut\n$x_1$ ?",
      "options": [
        {
          "text": "$1{,}75$",
          "correct": true,
          "feedback": "Bonne réponse : $x_1 = 2 - \\dfrac{4 - 3}{4} = 2 - 0{,}25$.\nC'est déjà une bonne approximation de $\\sqrt{3} \\approx 1{,}732$."
        },
        {
          "text": "$2{,}25$",
          "correct": false,
          "feedback": "Erreur de signe : on retranche le quotient\n$\\dfrac{f(x_0)}{f'(x_0)}$, on ne l'ajoute pas."
        },
        {
          "text": "$1{,}5$",
          "correct": false,
          "feedback": "Erreur : le dénominateur est $2x_0 = 4$, pas $2$."
        },
        {
          "text": "$\\sqrt{3}$",
          "correct": false,
          "feedback": "Erreur : $\\sqrt{3}$ est la limite de la suite. Une étape n'en\ndonne qu'une valeur approchée."
        }
      ],
      "explanation": "La méthode de Newton remplace $x_n$ par l'abscisse du point où la\ntangente en $x_n$ coupe l'axe des abscisses. La convergence est\ntrès rapide dans les cas favorables."
    },
    {
      "id": "q10",
      "difficulty": 3,
      "skills": [
        "secante",
        "methode"
      ],
      "title": "La méthode de la sécante",
      "partie": "analyse",
      "statement": "La méthode de la sécante approche une solution de $f(x) = 0$ à\npartir de deux valeurs $a$ et $b$. Par quoi remplace-t-elle la\ntangente de la méthode de Newton ?",
      "options": [
        {
          "text": "Par la droite passant par $(a\\,;\\,f(a))$ et $(b\\,;\\,f(b))$",
          "correct": true,
          "feedback": "Bonne réponse : on prend l'abscisse du point où cette droite\ncoupe l'axe des abscisses, sans avoir besoin de la dérivée."
        },
        {
          "text": "Par la tangente au milieu de $[a\\,;\\,b]$",
          "correct": false,
          "feedback": "Erreur : une tangente demande encore le calcul de la dérivée,\nque la sécante permet d'éviter."
        },
        {
          "text": "Par l'axe des abscisses, sans utiliser la courbe",
          "correct": false,
          "feedback": "Erreur : l'axe des abscisses ne dépend pas de $f$, il ne peut\ndonc pas localiser une solution."
        },
        {
          "text": "Par le milieu $\\dfrac{a + b}{2}$, comme en dichotomie",
          "correct": false,
          "feedback": "Erreur : c'est la dichotomie. La sécante tient compte des\nvaleurs $f(a)$ et $f(b)$, pas seulement des bornes."
        }
      ],
      "explanation": "La pente de la sécante, $\\dfrac{f(b) - f(a)}{b - a}$, remplace le\nnombre dérivé : c'est une méthode de Newton sans dérivée."
    },
    {
      "id": "q11",
      "difficulty": 2,
      "skills": [
        "euler",
        "equation-differentielle"
      ],
      "title": "Un pas de la méthode d'Euler",
      "partie": "analyse",
      "statement": "La fonction $y$ vérifie $y' = -2y + 4$ et $y(0) = 1$. La méthode\nd'Euler de pas $h = 0{,}1$ utilise $y(x + h) \\approx y(x) + h\\,y'(x)$.\nQuelle valeur approchée de $y(0{,}1)$ donne-t-elle ?",
      "options": [
        {
          "text": "$1{,}2$",
          "correct": true,
          "feedback": "Bonne réponse : $y'(0) = -2 \\times 1 + 4 = 2$, donc\n$y(0{,}1) \\approx 1 + 0{,}1 \\times 2$."
        },
        {
          "text": "$1{,}4$",
          "correct": false,
          "feedback": "Erreur : le second membre $4$ a été ajouté sans le terme\n$-2y(0)$ : on a pris $y'(0) = 4$."
        },
        {
          "text": "$3$",
          "correct": false,
          "feedback": "Erreur : l'accroissement $y'(0) = 2$ doit être multiplié par le\npas $h = 0{,}1$."
        },
        {
          "text": "$0{,}8$",
          "correct": false,
          "feedback": "Erreur de signe : $y'(0) = 2$ est positif, donc $y$ augmente sur\nce premier pas."
        }
      ],
      "explanation": "Méthode d'Euler pour $y' = ay + b$ :\n$y_{k+1} = y_k + h(ay_k + b)$. On calcule ainsi, pas à pas, une\napproximation de la solution."
    },
    {
      "id": "q12",
      "difficulty": 3,
      "skills": [
        "euler",
        "python"
      ],
      "title": "Programmer la méthode d'Euler",
      "partie": "analyse",
      "statement": "Quelle ligne compléter pour que `euler(n)` renvoie une valeur\napprochée de $y(1)$, où $y' = y$ et $y(0) = 1$, avec $n$ pas de\nlongueur $\\dfrac{1}{n}$ ?\n\n```python\ndef euler(n):\n    h = 1 / n\n    y = 1\n    for k in range(n):\n        ...\n    return y\n```",
      "options": [
        {
          "text": "`y = y + h * y`",
          "correct": true,
          "feedback": "Bonne réponse : ici $y' = y$, donc chaque pas ajoute $h \\times y$.\nOn obtient $\\left(1 + \\dfrac{1}{n}\\right)^n$, proche de $e$."
        },
        {
          "text": "`y = y + h`",
          "correct": false,
          "feedback": "Erreur : cette ligne correspond à $y' = 1$. On obtiendrait $2$,\nla valeur en $1$ de $x \\mapsto 1 + x$."
        },
        {
          "text": "`y = h * y`",
          "correct": false,
          "feedback": "Erreur : on doit ajouter l'accroissement $h\\,y$ à la valeur\nactuelle, pas la remplacer par cet accroissement."
        },
        {
          "text": "`y = y * (1 + k)`",
          "correct": false,
          "feedback": "Erreur : le pas $h$ n'intervient plus. On calculerait une\nfactorielle, sans rapport avec l'équation."
        }
      ],
      "explanation": "Plus $n$ est grand, plus l'approximation de $y(1) = e$ est précise :\n$n = 1\\,000$ donne environ $2{,}717$."
    },
    {
      "id": "q13",
      "difficulty": 2,
      "skills": [
        "rectangles",
        "integrale"
      ],
      "title": "La méthode des rectangles",
      "partie": "analyse",
      "statement": "On approche $\\displaystyle\\int_0^1 x^2\\,dx$ par la somme des aires de\n$4$ rectangles de largeur $0{,}25$, dont la hauteur est l'image de la\nborne **gauche** de chaque intervalle. Quelle valeur obtient-on ?",
      "options": [
        {
          "text": "$0{,}21875$",
          "correct": true,
          "feedback": "Bonne réponse :\n$0{,}25 \\times (0 + 0{,}0625 + 0{,}25 + 0{,}5625) = 0{,}21875$."
        },
        {
          "text": "$0{,}46875$",
          "correct": false,
          "feedback": "Erreur : ce sont les bornes **droites**, $0{,}25$, $0{,}5$,\n$0{,}75$ et $1$, qui ont été utilisées."
        },
        {
          "text": "$0{,}875$",
          "correct": false,
          "feedback": "Erreur : la somme des hauteurs n'a pas été multipliée par la\nlargeur $0{,}25$ des rectangles."
        },
        {
          "text": "$\\dfrac{1}{3}$",
          "correct": false,
          "feedback": "Erreur : c'est la valeur exacte de l'intégrale. La méthode des\nrectangles en donne une approximation."
        }
      ],
      "explanation": "La fonction carré étant croissante sur $[0\\,;\\,1]$, les rectangles à\ngauche donnent une valeur par défaut et ceux à droite une valeur\npar excès : $0{,}21875 \\leq \\dfrac{1}{3} \\leq 0{,}46875$."
    },
    {
      "id": "q14",
      "difficulty": 3,
      "skills": [
        "rectangles",
        "python"
      ],
      "title": "Programmer la méthode des rectangles",
      "partie": "analyse",
      "statement": "Que calcule `rect(0, 1, 100)` pour une fonction `f` continue sur\n$[0\\,;\\,1]$ ?\n\n```python\ndef rect(a, b, n):\n    h = (b - a) / n\n    s = 0\n    for k in range(n):\n        s = s + h * f(a + k * h)\n    return s\n```",
      "options": [
        {
          "text": "Une valeur approchée de $\\displaystyle\\int_0^1 f(x)\\,dx$",
          "correct": true,
          "feedback": "Bonne réponse : la fonction additionne les aires de $100$\nrectangles de largeur $h = 0{,}01$, de hauteur l'image de la\nborne gauche."
        },
        {
          "text": "La valeur exacte de $\\displaystyle\\int_0^1 f(x)\\,dx$",
          "correct": false,
          "feedback": "Erreur : une somme de rectangles ne donne qu'une approximation,\nsauf cas particulier comme une fonction constante."
        },
        {
          "text": "La valeur moyenne des images $f(0)$ et $f(1)$",
          "correct": false,
          "feedback": "Erreur : la fonction utilise les images de $100$ points de\nl'intervalle, pas seulement celles des bornes."
        },
        {
          "text": "La somme des images $f(0)$, $f(0{,}01)$, …, $f(0{,}99)$",
          "correct": false,
          "feedback": "Erreur : chaque image est multipliée par la largeur `h` : on\nadditionne des aires, pas des hauteurs."
        }
      ],
      "explanation": "Quand $n$ augmente, la somme des aires des rectangles se rapproche de\nl'intégrale. Les méthodes des milieux et des trapèzes convergent plus\nvite."
    },
    {
      "id": "q15",
      "difficulty": 3,
      "skills": [
        "trapezes",
        "integrale"
      ],
      "title": "La méthode des trapèzes",
      "partie": "analyse",
      "statement": "On approche $\\displaystyle\\int_0^2 f(x)\\,dx$ par un seul trapèze, de\nsommets $(0\\,;\\,0)$, $(2\\,;\\,0)$, $(2\\,;\\,f(2))$ et $(0\\,;\\,f(0))$.\nAvec $f(0) = 1$ et $f(2) = 5$, quelle valeur obtient-on ?",
      "options": [
        {
          "text": "$6$",
          "correct": true,
          "feedback": "Bonne réponse : l'aire du trapèze vaut\n$2 \\times \\dfrac{f(0) + f(2)}{2} = 2 \\times 3$."
        },
        {
          "text": "$3$",
          "correct": false,
          "feedback": "Erreur : $3$ est la hauteur moyenne. Il faut la multiplier par la\nlargeur $2$."
        },
        {
          "text": "$10$",
          "correct": false,
          "feedback": "Erreur : c'est l'aire du rectangle de hauteur $f(2)$, qui\nmajore le trapèze."
        },
        {
          "text": "$12$",
          "correct": false,
          "feedback": "Erreur : la somme des deux bases est divisée par $2$ dans la\nformule du trapèze."
        }
      ],
      "explanation": "Méthode des trapèzes sur $[a\\,;\\,b]$ :\n$\\displaystyle\\int_a^b f \\approx (b - a) \\dfrac{f(a) + f(b)}{2}$,\nappliquée sur chaque petit intervalle d'une subdivision."
    },
    {
      "id": "q16",
      "difficulty": 3,
      "skills": [
        "monte-carlo",
        "integrale"
      ],
      "title": "Une intégrale par Monte-Carlo",
      "partie": "analyse",
      "statement": "Le module `random` est importé. La fonction $f$ est continue sur\n$[0\\,;\\,1]$ et vérifie $0 \\leq f(x) \\leq 1$. Que renvoie\n`mc(100000)`, environ ?\n\n```python\ndef mc(n):\n    c = 0\n    for i in range(n):\n        x = random.random()\n        y = random.random()\n        if y <= f(x):\n            c = c + 1\n    return c / n\n```",
      "options": [
        {
          "text": "$\\displaystyle\\int_0^1 f(x)\\,dx$",
          "correct": true,
          "feedback": "Bonne réponse : la fréquence des points du carré unité situés sous\nla courbe approche l'aire sous la courbe, qui est l'intégrale."
        },
        {
          "text": "$f(0{,}5)$, la valeur au milieu",
          "correct": false,
          "feedback": "Erreur : les abscisses sont tirées au hasard dans tout\nl'intervalle, pas seulement au milieu."
        },
        {
          "text": "$1 - \\displaystyle\\int_0^1 f(x)\\,dx$",
          "correct": false,
          "feedback": "Erreur : ce serait la fréquence des points **au-dessus** de la\ncourbe, avec la condition `y > f(x)`."
        },
        {
          "text": "Le maximum de $f$ sur $[0\\,;\\,1]$",
          "correct": false,
          "feedback": "Erreur : la fonction compte des points, elle ne cherche aucun\nmaximum."
        }
      ],
      "explanation": "Méthode de Monte-Carlo : l'aire du carré unité vaut $1$, donc la\nproportion de points sous la courbe estime directement l'intégrale."
    },
    {
      "id": "q17",
      "difficulty": 3,
      "skills": [
        "suite-recurrente",
        "seuil"
      ],
      "title": "Seuil pour une suite convergente",
      "partie": "analyse",
      "statement": "La suite définie par $u_0 = 0$ et $u_{n+1} = 0{,}5\\,u_n + 3$\nconverge vers $6$. Que renvoie la fonction suivante ?\n\n```python\ndef rang():\n    u = 0\n    n = 0\n    while 6 - u > 0.01:\n        u = 0.5 * u + 3\n        n = n + 1\n    return n\n```",
      "options": [
        {
          "text": "Le premier rang où $6 - u_n \\leq 0{,}01$",
          "correct": true,
          "feedback": "Bonne réponse : ici $6 - u_n = 6 \\times 0{,}5^n$, et la boucle\ns'arrête dès que cet écart ne dépasse plus $0{,}01$ : $n = 10$."
        },
        {
          "text": "La limite de la suite, arrondie au centième",
          "correct": false,
          "feedback": "Erreur : la fonction renvoie `n`, un rang, et non une valeur de\nla suite."
        },
        {
          "text": "Le terme $u_n$ le plus proche de $6$",
          "correct": false,
          "feedback": "Erreur : la fonction renvoie le compteur `n`, pas le terme `u`."
        },
        {
          "text": "Rien, car la suite n'atteint jamais $6$",
          "correct": false,
          "feedback": "Erreur : la boucle ne demande pas d'atteindre $6$, seulement de\ns'en approcher à moins de $0{,}01$, ce qui arrive."
        }
      ],
      "explanation": "On a $6 - u_n = 6 \\times 0{,}5^n$ ; $6 \\times 0{,}5^9 \\approx 0{,}0117$\net $6 \\times 0{,}5^{10} \\approx 0{,}0059$, donc la fonction renvoie\n$10$."
    },
    {
      "id": "q18",
      "difficulty": 2,
      "skills": [
        "binomiale",
        "python"
      ],
      "title": "Calculer une probabilité binomiale",
      "partie": "probabilites",
      "statement": "On dispose d'une fonction `comb(n, k)` qui renvoie\n$\\dbinom{n}{k}$. Quelle expression Python calcule $P(X = k)$ lorsque\n$X$ suit la loi binomiale $\\mathcal{B}(n, p)$ ?",
      "options": [
        {
          "text": "`comb(n, k) * p ** k * (1 - p) ** (n - k)`",
          "correct": true,
          "feedback": "Bonne réponse : $P(X = k) = \\dbinom{n}{k} p^k (1 - p)^{n - k}$."
        },
        {
          "text": "`comb(n, k) * p ** k * (1 - p) ** k`",
          "correct": false,
          "feedback": "Erreur : l'exposant de $1 - p$ est le nombre d'échecs, $n - k$."
        },
        {
          "text": "`p ** k * (1 - p) ** (n - k)`",
          "correct": false,
          "feedback": "Erreur : c'est la probabilité d'**une** liste d'issues. Il faut\nmultiplier par le nombre de listes à $k$ succès, $\\dbinom{n}{k}$."
        },
        {
          "text": "`comb(n, k) * p * k * (1 - p) * (n - k)`",
          "correct": false,
          "feedback": "Erreur : `*` est la multiplication. La puissance s'écrit `**`."
        }
      ],
      "explanation": "Une liste de $n$ issues avec $k$ succès a pour probabilité\n$p^k(1 - p)^{n - k}$, et il y a $\\dbinom{n}{k}$ telles listes."
    },
    {
      "id": "q19",
      "difficulty": 3,
      "skills": [
        "binomiale",
        "cumul"
      ],
      "title": "Probabilité cumulée par une boucle",
      "partie": "probabilites",
      "statement": "La fonction `pbin(n, p, k)` renvoie $P(X = k)$ pour\n$X \\sim \\mathcal{B}(n, p)$. Que calcule la fonction suivante ?\n\n```python\ndef f(n, p, k):\n    s = 0\n    for i in range(k + 1):\n        s = s + pbin(n, p, i)\n    return s\n```",
      "options": [
        {
          "text": "$P(X \\leq k)$",
          "correct": true,
          "feedback": "Bonne réponse : la boucle additionne $P(X = i)$ pour $i$ allant\nde $0$ à $k$."
        },
        {
          "text": "$P(X < k)$",
          "correct": false,
          "feedback": "Erreur : `range(k + 1)` va jusqu'à $k$ inclus, donc $P(X = k)$\nest ajoutée."
        },
        {
          "text": "$P(X \\geq k)$",
          "correct": false,
          "feedback": "Erreur : les valeurs additionnées vont de $0$ à $k$, ce sont les\npetites valeurs de $X$."
        },
        {
          "text": "$P(X = k)$",
          "correct": false,
          "feedback": "Erreur : $P(X = k)$ n'est qu'un des termes de la somme calculée."
        }
      ],
      "explanation": "Probabilité cumulée : $P(X \\leq k) = \\sum_{i = 0}^{k} P(X = i)$. Les\ncalculatrices la fournissent directement."
    },
    {
      "id": "q20",
      "difficulty": 3,
      "skills": [
        "surreservation",
        "seuil"
      ],
      "title": "Le problème de la surréservation",
      "partie": "probabilites",
      "statement": "Une compagnie vend $n$ billets pour un avion de $k$ places ; le\nnombre $X$ de passagers qui se présentent suit une loi binomiale.\nLa fonction `F(j)` renvoie $P(X \\leq j)$. Que renvoie la fonction\nsuivante, pour $\\alpha = 0{,}05$ ?\n\n```python\ndef seuil(alpha):\n    k = 0\n    while 1 - F(k) > alpha:\n        k = k + 1\n    return k\n```",
      "options": [
        {
          "text": "Le plus petit $k$ tel que $P(X > k) \\leq 0{,}05$",
          "correct": true,
          "feedback": "Bonne réponse : $1 - F(k) = P(X > k)$. La boucle s'arrête au\npremier $k$ pour lequel ce risque ne dépasse plus $0{,}05$."
        },
        {
          "text": "Le plus grand $k$ tel que $P(X > k) \\leq 0{,}05$",
          "correct": false,
          "feedback": "Erreur : $k$ augmente à partir de $0$ et la boucle s'arrête dès\nque la condition est remplie : c'est le plus petit $k$."
        },
        {
          "text": "Le plus petit $k$ tel que $P(X \\leq k) \\leq 0{,}05$",
          "correct": false,
          "feedback": "Erreur : $1 - F(k)$ est la probabilité de l'événement contraire,\n$P(X > k)$."
        },
        {
          "text": "Le nombre moyen de passagers qui se présentent",
          "correct": false,
          "feedback": "Erreur : la moyenne est l'espérance $np$. La fonction cherche un\nseuil de risque."
        }
      ],
      "explanation": "Avec $k$ places, le risque de refuser un passager est\n$P(X > k)$ ; la compagnie choisit le plus petit nombre de places\nqui rend ce risque inférieur à $\\alpha$."
    },
    {
      "id": "q21",
      "difficulty": 3,
      "skills": [
        "intervalle",
        "binomiale"
      ],
      "title": "Un intervalle de forte probabilité",
      "partie": "probabilites",
      "statement": "Pour $X \\sim \\mathcal{B}(100\\,;\\,0{,}5)$, on lit à la calculatrice\n$P(X \\leq 39) \\approx 0{,}018$ et $P(X \\leq 60) \\approx 0{,}982$. Que\npeut-on affirmer ?",
      "options": [
        {
          "text": "$P(40 \\leq X \\leq 60) \\approx 0{,}964$",
          "correct": true,
          "feedback": "Bonne réponse : $P(40 \\leq X \\leq 60) = P(X \\leq 60) - P(X \\leq\n39)$, soit environ $0{,}982 - 0{,}018$."
        },
        {
          "text": "$P(40 \\leq X \\leq 60) \\approx 0{,}982$",
          "correct": false,
          "feedback": "Erreur : il faut retirer les valeurs inférieures à $40$, de\nprobabilité $0{,}018$."
        },
        {
          "text": "$P(39 \\leq X \\leq 60) \\approx 0{,}964$",
          "correct": false,
          "feedback": "Erreur : en retranchant $P(X \\leq 39)$, on retire aussi la\nvaleur $39$ ; l'intervalle commence à $40$."
        },
        {
          "text": "$P(40 \\leq X \\leq 60) \\approx 1$",
          "correct": false,
          "feedback": "Erreur : les valeurs hors de $[40\\,;\\,60]$ ne sont pas\nimpossibles : leur probabilité totale est d'environ $0{,}036$."
        }
      ],
      "explanation": "$P(a \\leq X \\leq b) = P(X \\leq b) - P(X \\leq a - 1)$ pour une\nvariable à valeurs entières. On obtient ainsi un intervalle $I$ tel\nque $P(X \\in I) \\geq 1 - \\alpha$, ici avec $\\alpha \\approx 0{,}04$."
    },
    {
      "id": "q22",
      "difficulty": 2,
      "skills": [
        "simulation",
        "echantillon"
      ],
      "title": "Simuler un échantillon",
      "partie": "probabilites",
      "statement": "Le module `random` est importé. Que renvoie `ech(50, 0.3)` ?\n\n```python\ndef ech(n, p):\n    L = []\n    for i in range(n):\n        if random.random() < p:\n            L.append(1)\n        else:\n            L.append(0)\n    return L\n```",
      "options": [
        {
          "text": "Une liste de $50$ valeurs égales à $0$ ou $1$",
          "correct": true,
          "feedback": "Bonne réponse : chaque élément vaut $1$ avec probabilité $0{,}3$\net $0$ sinon ; c'est un échantillon de taille $50$."
        },
        {
          "text": "Le nombre de succès en $50$ épreuves",
          "correct": false,
          "feedback": "Erreur : la fonction renvoie la liste des résultats. Le nombre\nde succès s'obtiendrait avec `sum`."
        },
        {
          "text": "Une liste de $50$ nombres compris entre $0$ et $0{,}3$",
          "correct": false,
          "feedback": "Erreur : les éléments valent $1$ ou $0$ selon la comparaison de\n`random.random()` avec $p$."
        },
        {
          "text": "Une liste contenant exactement $15$ fois le nombre $1$",
          "correct": false,
          "feedback": "Erreur : $15$ est le nombre moyen de succès. Le nombre obtenu\nvarie d'une simulation à l'autre."
        }
      ],
      "explanation": "`sum(ech(n, p))` simule une variable de loi $\\mathcal{B}(n, p)$ et\n`sum(ech(n, p)) / n` une fréquence observée."
    },
    {
      "id": "q23",
      "difficulty": 3,
      "skills": [
        "simulation",
        "moyenne-echantillon"
      ],
      "title": "Dispersion des moyennes simulées",
      "partie": "probabilites",
      "statement": "On simule un grand nombre d'échantillons de taille $n$ d'une\nvariable d'écart type $\\sigma$ et l'on calcule l'écart type $s$ des\nmoyennes obtenues. Autour de quelle valeur $s$ se situe-t-il ?",
      "options": [
        {
          "text": "$\\dfrac{\\sigma}{\\sqrt{n}}$",
          "correct": true,
          "feedback": "Bonne réponse : la moyenne d'un échantillon a pour variance\n$\\dfrac{\\sigma^2}{n}$, donc pour écart type\n$\\dfrac{\\sigma}{\\sqrt{n}}$."
        },
        {
          "text": "$\\dfrac{\\sigma^2}{n}$",
          "correct": false,
          "feedback": "Erreur : $\\dfrac{\\sigma^2}{n}$ est la variance de la moyenne.\nL'écart type en est la racine carrée."
        },
        {
          "text": "$\\dfrac{\\sigma}{n}$",
          "correct": false,
          "feedback": "Erreur : c'est la **variance** qui est divisée par $n$. L'écart\ntype l'est par $\\sqrt{n}$."
        },
        {
          "text": "$\\sigma\\sqrt{n}$",
          "correct": false,
          "feedback": "Erreur : $\\sigma\\sqrt{n}$ est l'écart type de la **somme** des\n$n$ valeurs, pas de leur moyenne."
        }
      ],
      "explanation": "La simulation confirme le résultat du cours : pour quadrupler la\nprécision de la moyenne, il faut un échantillon seize fois plus\ngrand."
    },
    {
      "id": "q24",
      "difficulty": 2,
      "skills": [
        "marche-aleatoire",
        "simulation"
      ],
      "title": "Une marche aléatoire",
      "partie": "probabilites",
      "statement": "Le module `random` est importé. Un pion part de $0$ et fait $n$ pas\nde $+1$ ou de $-1$ avec la même probabilité. Que renvoie\n`marche(10)` ?\n\n```python\ndef marche(n):\n    x = 0\n    for i in range(n):\n        if random.random() < 0.5:\n            x = x + 1\n        else:\n            x = x - 1\n    return x\n```",
      "options": [
        {
          "text": "La position du pion après $10$ pas",
          "correct": true,
          "feedback": "Bonne réponse : `x` part de $0$ et change de $\\pm 1$ à chaque pas.\nSa valeur finale est un entier pair compris entre $-10$ et $10$."
        },
        {
          "text": "Toujours $0$, les pas se compensant",
          "correct": false,
          "feedback": "Erreur : les pas ne se compensent qu'en moyenne. L'espérance de\nla position vaut $0$, mais la position varie d'une simulation à\nl'autre."
        },
        {
          "text": "Le nombre de pas vers la droite",
          "correct": false,
          "feedback": "Erreur : les pas vers la gauche diminuent `x`, qui n'est donc\npas un simple compteur."
        },
        {
          "text": "La distance totale parcourue, égale à $10$",
          "correct": false,
          "feedback": "Erreur : la fonction renvoie une position, qui tient compte du\nsens de chaque pas."
        }
      ],
      "explanation": "Si $D$ est le nombre de pas vers la droite, la position vaut\n$D - (10 - D) = 2D - 10$, avec $D \\sim \\mathcal{B}(10\\,;\\,0{,}5)$.\nOn peut donc calculer la loi de la position."
    },
    {
      "id": "q25",
      "difficulty": 3,
      "skills": [
        "galton",
        "binomiale"
      ],
      "title": "La planche de Galton",
      "partie": "probabilites",
      "statement": "Dans une planche de Galton à $6$ rangées de clous, une bille part à\ndroite ou à gauche avec probabilité $\\dfrac{1}{2}$ à chaque clou,\nde façon indépendante. Quelle loi suit le nombre $X$ de rebonds à\ndroite ?",
      "options": [
        {
          "text": "La loi binomiale $\\mathcal{B}\\left(6\\,;\\,\\dfrac{1}{2}\\right)$",
          "correct": true,
          "feedback": "Bonne réponse : $6$ épreuves de Bernoulli identiques et\nindépendantes, le succès étant « aller à droite »."
        },
        {
          "text": "La loi uniforme sur $\\{0, 1, \\ldots, 6\\}$",
          "correct": false,
          "feedback": "Erreur : les cases du milieu reçoivent bien plus de billes que\nles bords, $P(X = 3) = \\dfrac{20}{64}$ contre\n$P(X = 0) = \\dfrac{1}{64}$."
        },
        {
          "text": "La loi binomiale $\\mathcal{B}\\left(\\dfrac{1}{2}\\,;\\,6\\right)$",
          "correct": false,
          "feedback": "Erreur : l'ordre des paramètres est inversé. On écrit d'abord le\nnombre d'épreuves, puis la probabilité du succès."
        },
        {
          "text": "Une loi qui dépend de la case de départ",
          "correct": false,
          "feedback": "Erreur : toutes les billes partent du même point, et les rebonds\nsuivent la même règle à chaque clou."
        }
      ],
      "explanation": "La case d'arrivée d'une bille est déterminée par son nombre de\nrebonds à droite. La simulation de nombreuses billes fait apparaître\nla forme en cloche de la loi binomiale."
    },
    {
      "id": "q26",
      "difficulty": 3,
      "skills": [
        "bienayme",
        "simulation"
      ],
      "title": "Comparer une fréquence observée à la borne",
      "partie": "probabilites",
      "statement": "Pour $S_n \\sim \\mathcal{B}(n\\,;\\,p)$, l'inégalité de\nBienaymé-Tchebychev donne\n$P\\left(|S_n - np| \\geq \\sqrt{n}\\right) \\leq p(1 - p)$. Avec\n$p = 0{,}5$, une simulation donne une fréquence de cet événement\nproche de $0{,}05$. Qu'en conclure ?",
      "options": [
        {
          "text": "La borne $0{,}25$ est respectée, mais large",
          "correct": true,
          "feedback": "Bonne réponse : $0{,}05 \\leq 0{,}25$. L'inégalité est vraie mais\ngrossière, la probabilité réelle étant bien plus petite."
        },
        {
          "text": "La simulation contredit l'inégalité",
          "correct": false,
          "feedback": "Erreur : l'inégalité fournit un majorant. Une probabilité plus\npetite que la borne est conforme."
        },
        {
          "text": "La probabilité vaut exactement $0{,}25$",
          "correct": false,
          "feedback": "Erreur : $0{,}25$ n'est qu'un majorant, et la simulation montre\nque la probabilité est bien plus petite."
        },
        {
          "text": "Il faut remplacer $\\sqrt{n}$ par $n$ dans l'inégalité",
          "correct": false,
          "feedback": "Erreur : la simulation ne remet pas l'inégalité en cause ; elle\nmontre seulement que la borne est large."
        }
      ],
      "explanation": "Ici $V(S_n) = np(1 - p)$ et l'écart vaut $\\sqrt{n}$ : la borne est\n$\\dfrac{np(1 - p)}{n} = p(1 - p) = 0{,}25$. L'inégalité est\nuniverselle, donc rarement précise."
    },
    {
      "id": "q27",
      "difficulty": 2,
      "skills": [
        "monte-carlo",
        "pi"
      ],
      "title": "Précision d'une estimation par Monte-Carlo",
      "partie": "probabilites",
      "statement": "Une estimation de $\\pi$ par Monte-Carlo avec $n$ points donne des\nrésultats qui fluctuent d'une exécution à l'autre. Comment évolue\ncette fluctuation quand on multiplie $n$ par $100$ ?",
      "options": [
        {
          "text": "Elle est environ divisée par $10$",
          "correct": true,
          "feedback": "Bonne réponse : l'écart type d'une fréquence est proportionnel à\n$\\dfrac{1}{\\sqrt{n}}$, et $\\sqrt{100} = 10$."
        },
        {
          "text": "Elle est environ divisée par $100$",
          "correct": false,
          "feedback": "Erreur : c'est la variance qui est divisée par $100$. L'écart\ntype l'est par $\\sqrt{100}$."
        },
        {
          "text": "Elle disparaît complètement",
          "correct": false,
          "feedback": "Erreur : tant que la simulation utilise le hasard, le résultat\nfluctue, même pour un très grand $n$."
        },
        {
          "text": "Elle ne change pas",
          "correct": false,
          "feedback": "Erreur : d'après la loi des grands nombres, la fréquence se\nconcentre autour de sa probabilité quand $n$ grandit."
        }
      ],
      "explanation": "Gagner une décimale de précision demande de multiplier le nombre de\npoints par $100$ : la méthode de Monte-Carlo converge lentement."
    },
    {
      "id": "q28",
      "difficulty": 2,
      "skills": [
        "suite",
        "somme",
        "python"
      ],
      "title": "Une somme alternée qui approche ln 2",
      "partie": "analyse",
      "statement": "Que calcule `s(4)` ?\n\n```python\ndef s(n):\n    t = 0\n    for k in range(1, n + 1):\n        t = t + (-1) ** (k + 1) / k\n    return t\n```",
      "options": [
        {
          "text": "$1 - \\dfrac{1}{2} + \\dfrac{1}{3} - \\dfrac{1}{4}$",
          "correct": true,
          "feedback": "Bonne réponse : pour $k$ impair, $(-1)^{k+1} = 1$ ; pour $k$\npair, il vaut $-1$. On obtient $\\dfrac{7}{12} \\approx 0{,}58$."
        },
        {
          "text": "$1 + \\dfrac{1}{2} + \\dfrac{1}{3} + \\dfrac{1}{4}$",
          "correct": false,
          "feedback": "Erreur : le facteur $(-1)^{k+1}$ alterne les signes des termes."
        },
        {
          "text": "$-1 + \\dfrac{1}{2} - \\dfrac{1}{3} + \\dfrac{1}{4}$",
          "correct": false,
          "feedback": "Erreur : pour $k = 1$, $(-1)^{k+1} = (-1)^2 = 1$ ; le premier\nterme est positif."
        },
        {
          "text": "$1 - \\dfrac{1}{2} + \\dfrac{1}{3}$",
          "correct": false,
          "feedback": "Erreur : `range(1, n + 1)` va jusqu'à $k = 4$ ; le terme\n$-\\dfrac{1}{4}$ est ajouté."
        }
      ],
      "explanation": "Ces sommes se rapprochent de $\\ln 2 \\approx 0{,}693$ quand $n$\ngrandit, mais lentement. Brouncker a proposé une autre écriture de\n$\\ln 2$ qui converge plus vite."
    },
    {
      "id": "q29",
      "difficulty": 3,
      "skills": [
        "suite-recurrente",
        "point-fixe"
      ],
      "title": "Itérer une fonction continue",
      "partie": "analyse",
      "statement": "On pose $f(x) = \\sqrt{x + 2}$. Vers quelle valeur les nombres\nrenvoyés par `iter(n)` se rapprochent-ils quand $n$ grandit ?\n\n```python\ndef iter(n):\n    u = 0\n    for k in range(n):\n        u = (u + 2) ** 0.5\n    return u\n```",
      "options": [
        {
          "text": "$2$",
          "correct": true,
          "feedback": "Bonne réponse : $f$ est continue, donc la limite $\\ell$ vérifie\n$\\ell = \\sqrt{\\ell + 2}$, soit $\\ell^2 - \\ell - 2 = 0$ avec\n$\\ell \\geq 0$ : $\\ell = 2$."
        },
        {
          "text": "$\\sqrt{2}$",
          "correct": false,
          "feedback": "Erreur : $\\sqrt{2}$ est seulement $u_1$. Les termes suivants\ncontinuent de croître."
        },
        {
          "text": "$-1$",
          "correct": false,
          "feedback": "Erreur : $-1$ est l'autre solution de $\\ell^2 - \\ell - 2 = 0$,\nmais une racine carrée est positive."
        },
        {
          "text": "$+\\infty$",
          "correct": false,
          "feedback": "Erreur : la suite est croissante mais majorée par $2$, donc\nelle converge."
        }
      ],
      "explanation": "Pour $u_{n+1} = f(u_n)$ avec $f$ continue, une limite finie $\\ell$\nvérifie $f(\\ell) = \\ell$. On obtient les valeurs $0$, $1{,}414$,\n$1{,}848$, $1{,}962$, …"
    },
    {
      "id": "q30",
      "difficulty": 2,
      "skills": [
        "liste",
        "esperance",
        "simulation"
      ],
      "title": "Moyenne d'une liste de résultats simulés",
      "partie": "probabilites",
      "statement": "La liste `R` contient $10\\,000$ résultats simulés d'une variable\naléatoire $X$. Que fournit `sum(R) / len(R)` ?",
      "options": [
        {
          "text": "Une estimation de $E(X)$",
          "correct": true,
          "feedback": "Bonne réponse : la moyenne d'un grand échantillon se rapproche\nde l'espérance, d'après la loi des grands nombres."
        },
        {
          "text": "La valeur exacte de $E(X)$",
          "correct": false,
          "feedback": "Erreur : la moyenne observée fluctue d'une simulation à l'autre.\nElle approche l'espérance sans l'égaler."
        },
        {
          "text": "Une estimation de la variance $V(X)$",
          "correct": false,
          "feedback": "Erreur : la variance est la moyenne des carrés des écarts à la\nmoyenne, pas la moyenne des valeurs."
        },
        {
          "text": "La valeur la plus fréquente de $X$",
          "correct": false,
          "feedback": "Erreur : la fonction additionne toutes les valeurs puis divise\npar leur nombre : c'est une moyenne."
        }
      ],
      "explanation": "Simuler un échantillon puis calculer sa moyenne permet d'estimer une\nespérance inaccessible au calcul direct."
    },
    {
      "id": "q31",
      "difficulty": 1,
      "skills": [
        "listes",
        "comprehension",
        "carres"
      ],
      "title": "Les carrés par une liste en compréhension",
      "partie": "listes",
      "statement": "Qu'affiche `print([k**2 for k in range(1, 5)])` ?",
      "options": [
        {
          "text": "`[1, 4, 9, 16]`",
          "correct": true,
          "feedback": "Bonne réponse : `range(1, 5)` donne $1$, $2$, $3$, $4$, dont on\nprend les carrés.\n"
        },
        {
          "text": "`[0, 1, 4, 9, 16]`",
          "correct": false,
          "feedback": "Erreur : `range(1, 5)` commence à $1$, pas à $0$.\n"
        },
        {
          "text": "`[1, 4, 9, 16, 25]`",
          "correct": false,
          "feedback": "Erreur : la borne $5$ est exclue.\n"
        },
        {
          "text": "`[2, 4, 6, 8]`",
          "correct": false,
          "feedback": "Erreur : `k**2` est le carré, pas le double.\n"
        }
      ],
      "explanation": "`[expression for k in range(a, b)]` construit la liste des valeurs\nde l'expression pour `k` de `a` à `b - 1`."
    },
    {
      "id": "q32",
      "difficulty": 2,
      "skills": [
        "listes",
        "sum",
        "comprehension"
      ],
      "title": "Une somme de termes par compréhension",
      "partie": "listes",
      "statement": "Que vaut, arrondi au centième, `sum([1/k for k in range(1, 4)])` ?",
      "options": [
        {
          "text": "`1.83`, soit $1 + \\dfrac{1}{2} + \\dfrac{1}{3}$",
          "correct": true,
          "feedback": "Bonne réponse : la liste contient $1$, $0{,}5$ et $0{,}333\\ldots$,\nde somme $1{,}833\\ldots$\n"
        },
        {
          "text": "`2.08`, soit $1 + \\dfrac{1}{2} + \\dfrac{1}{3} + \\dfrac{1}{4}$",
          "correct": false,
          "feedback": "Erreur : `range(1, 4)` s'arrête à $3$.\n"
        },
        {
          "text": "`0.83`, soit $\\dfrac{1}{2} + \\dfrac{1}{3}$",
          "correct": false,
          "feedback": "Erreur : le terme $k = 1$, qui vaut $1$, fait partie de la\nliste.\n"
        },
        {
          "text": "`6`, la somme des entiers de $1$ à $3$",
          "correct": false,
          "feedback": "Erreur : la liste contient les **inverses** des entiers.\n"
        }
      ],
      "explanation": "`sum` additionne les éléments d'une liste ; combinée à une\ncompréhension, elle calcule une somme de termes définis par une\nformule."
    },
    {
      "id": "q33",
      "difficulty": 2,
      "skills": [
        "listes",
        "filtrage",
        "len"
      ],
      "title": "Compter les éléments positifs",
      "partie": "listes",
      "statement": "Avec `L = [3, -1, 4, -2, 5]`, que vaut `len([x for x in L if x > 0])` ?",
      "options": [
        {
          "text": "`3`, le nombre d'éléments positifs",
          "correct": true,
          "feedback": "Bonne réponse : la compréhension garde $3$, $4$ et $5$, et\n`len` compte ces trois éléments.\n"
        },
        {
          "text": "`12`, la somme des éléments positifs",
          "correct": false,
          "feedback": "Erreur : `len` compte, il n'additionne pas ; `sum` donnerait\n$12$.\n"
        },
        {
          "text": "`5`, la longueur de `L` sans filtre",
          "correct": false,
          "feedback": "Erreur : le filtre `if x > 0` écarte les deux négatifs.\n"
        },
        {
          "text": "`[3, 4, 5]`, la liste filtrée",
          "correct": false,
          "feedback": "Erreur : c'est la liste filtrée ; `len` en renvoie la longueur.\n"
        }
      ],
      "explanation": "Filtrer par compréhension puis compter avec `len` : une façon\ncompacte de dénombrer."
    },
    {
      "id": "q34",
      "difficulty": 3,
      "skills": [
        "listes",
        "suite-recurrente",
        "append"
      ],
      "title": "Les premiers termes d'une suite rangés dans une liste",
      "partie": "listes",
      "statement": "Qu'affiche ce programme ?\n```python\nu = 1\nL = [u]\nfor k in range(3):\n    u = 2 * u + 1\n    L.append(u)\nprint(L)\n```",
      "options": [
        {
          "text": "`[1, 3, 7, 15]`",
          "correct": true,
          "feedback": "Bonne réponse : la liste contient $u_0 = 1$, puis les trois\ntermes suivants calculés par $u_{n+1} = 2u_n + 1$.\n"
        },
        {
          "text": "`[3, 7, 15, 31]`",
          "correct": false,
          "feedback": "Erreur : $u_0$ est rangé dans la liste avant la boucle.\n"
        },
        {
          "text": "`[1, 3, 7]`",
          "correct": false,
          "feedback": "Erreur : `range(3)` ajoute trois termes après $u_0$, soit\nquatre éléments.\n"
        },
        {
          "text": "`[1, 2, 4, 8]`",
          "correct": false,
          "feedback": "Erreur : la relation est $2u + 1$, pas $2u$.\n"
        }
      ],
      "explanation": "Pour conserver tous les termes d'une suite, on les ajoute un à un à\nune liste avec `append`.",
      "variants": [
        {
          "statement": "Qu'affiche ce programme ?\n```python\nu = 1\nL = [u]\nfor k in range(3):\n    u = 2 * u + 1\n    L.append(u)\nprint(L)\n```",
          "options": [
            {
              "text": "`[1, 3, 7, 15]`",
              "correct": true,
              "feedback": "Bonne réponse : la liste contient $u_0 = 1$, puis les trois\ntermes suivants calculés par $u_{n+1} = 2u_n + 1$.\n"
            },
            {
              "text": "`[3, 7, 15, 31]`",
              "correct": false,
              "feedback": "Erreur : $u_0$ est rangé dans la liste avant la boucle.\n"
            },
            {
              "text": "`[1, 3, 7]`",
              "correct": false,
              "feedback": "Erreur : `range(3)` ajoute trois termes après $u_0$, soit\nquatre éléments.\n"
            },
            {
              "text": "`[1, 2, 4, 8]`",
              "correct": false,
              "feedback": "Erreur : la relation est $2u + 1$, pas $2u$.\n"
            }
          ],
          "explanation": "Pour conserver tous les termes d'une suite, on les ajoute un à un à\nune liste avec `append`."
        },
        {
          "statement": "Qu'affiche ce programme ?\n```python\nu = 2\nL = [u]\nfor k in range(3):\n    u = 2 * u + 1\n    L.append(u)\nprint(L)\n```",
          "options": [
            {
              "text": "`[2, 5, 11, 23]`",
              "correct": true,
              "feedback": "Bonne réponse : la liste contient $u_0 = 2$, puis les trois\ntermes suivants calculés par $u_{n+1} = 2u_n + 1$.\n"
            },
            {
              "text": "`[5, 11, 23, 47]`",
              "correct": false,
              "feedback": "Erreur : $u_0$ est rangé dans la liste avant la boucle.\n"
            },
            {
              "text": "`[2, 5, 11]`",
              "correct": false,
              "feedback": "Erreur : `range(3)` ajoute trois termes après $u_0$, soit\nquatre éléments.\n"
            },
            {
              "text": "`[2, 4, 8, 16]`",
              "correct": false,
              "feedback": "Erreur : la relation est $2u + 1$, pas $2u$.\n"
            }
          ],
          "explanation": "Pour conserver tous les termes d'une suite, on les ajoute un à un à\nune liste avec `append`."
        },
        {
          "statement": "Qu'affiche ce programme ?\n```python\nu = 0\nL = [u]\nfor k in range(3):\n    u = 2 * u + 1\n    L.append(u)\nprint(L)\n```",
          "options": [
            {
              "text": "`[0, 1, 3, 7]`",
              "correct": true,
              "feedback": "Bonne réponse : la liste contient $u_0 = 0$, puis les trois\ntermes suivants calculés par $u_{n+1} = 2u_n + 1$.\n"
            },
            {
              "text": "`[1, 3, 7, 15]`",
              "correct": false,
              "feedback": "Erreur : $u_0$ est rangé dans la liste avant la boucle.\n"
            },
            {
              "text": "`[0, 1, 3]`",
              "correct": false,
              "feedback": "Erreur : `range(3)` ajoute trois termes après $u_0$, soit\nquatre éléments.\n"
            },
            {
              "text": "`[0, 0, 0, 0]`",
              "correct": false,
              "feedback": "Erreur : la relation est $2u + 1$, pas $2u$.\n"
            }
          ],
          "explanation": "Pour conserver tous les termes d'une suite, on les ajoute un à un à\nune liste avec `append`."
        }
      ]
    },
    {
      "id": "q35",
      "difficulty": 3,
      "skills": [
        "listes",
        "index",
        "max"
      ],
      "title": "La position du maximum",
      "partie": "listes",
      "statement": "Avec `L = [4, 9, 2, 9]`, que vaut `L.index(max(L))` ?",
      "options": [
        {
          "text": "`1`, l'indice de la première occurrence de $9$",
          "correct": true,
          "feedback": "Bonne réponse : `max(L)` vaut $9$ et `index` renvoie la\nposition de sa **première** occurrence.\n"
        },
        {
          "text": "`9`, la valeur du maximum",
          "correct": false,
          "feedback": "Erreur : `index` renvoie une position, pas une valeur.\n"
        },
        {
          "text": "`3`, l'indice de la dernière occurrence",
          "correct": false,
          "feedback": "Erreur : `index` s'arrête à la première occurrence trouvée.\n"
        },
        {
          "text": "Une erreur, le maximum apparaissant plusieurs fois",
          "correct": false,
          "feedback": "Erreur : `index` accepte les répétitions ; il renvoie la\npremière position.\n"
        }
      ],
      "explanation": "`max` donne la valeur, `index` sa première position : combinés, ils\nlocalisent le maximum.",
      "variants": [
        {
          "statement": "Avec `L = [4, 9, 2, 9]`, que vaut `L.index(max(L))` ?",
          "options": [
            {
              "text": "`1`, l'indice de la première occurrence de $9$",
              "correct": true,
              "feedback": "Bonne réponse : `max(L)` vaut $9$ et `index` renvoie la\nposition de sa **première** occurrence.\n"
            },
            {
              "text": "`9`, la valeur du maximum",
              "correct": false,
              "feedback": "Erreur : `index` renvoie une position, pas une valeur.\n"
            },
            {
              "text": "`3`, l'indice de la dernière occurrence",
              "correct": false,
              "feedback": "Erreur : `index` s'arrête à la première occurrence trouvée.\n"
            },
            {
              "text": "Une erreur, le maximum apparaissant plusieurs fois",
              "correct": false,
              "feedback": "Erreur : `index` accepte les répétitions ; il renvoie la\npremière position.\n"
            }
          ],
          "explanation": "`max` donne la valeur, `index` sa première position : combinés, ils\nlocalisent le maximum."
        },
        {
          "statement": "Avec `L = [7, 3, 8, 1, 8]`, que vaut `L.index(max(L))` ?",
          "options": [
            {
              "text": "`2`, l'indice de la première occurrence de $8$",
              "correct": true,
              "feedback": "Bonne réponse : `max(L)` vaut $8$ et `index` renvoie la\nposition de sa **première** occurrence.\n"
            },
            {
              "text": "`8`, la valeur du maximum",
              "correct": false,
              "feedback": "Erreur : `index` renvoie une position, pas une valeur.\n"
            },
            {
              "text": "`4`, l'indice de la dernière occurrence",
              "correct": false,
              "feedback": "Erreur : `index` s'arrête à la première occurrence trouvée.\n"
            },
            {
              "text": "Une erreur, le maximum apparaissant plusieurs fois",
              "correct": false,
              "feedback": "Erreur : `index` accepte les répétitions ; il renvoie la\npremière position.\n"
            }
          ],
          "explanation": "`max` donne la valeur, `index` sa première position : combinés, ils\nlocalisent le maximum."
        },
        {
          "statement": "Avec `L = [5, 5, 2]`, que vaut `L.index(max(L))` ?",
          "options": [
            {
              "text": "`0`, l'indice de la première occurrence de $5$",
              "correct": true,
              "feedback": "Bonne réponse : `max(L)` vaut $5$ et `index` renvoie la\nposition de sa **première** occurrence.\n"
            },
            {
              "text": "`5`, la valeur du maximum",
              "correct": false,
              "feedback": "Erreur : `index` renvoie une position, pas une valeur.\n"
            },
            {
              "text": "`1`, l'indice de la dernière occurrence",
              "correct": false,
              "feedback": "Erreur : `index` s'arrête à la première occurrence trouvée.\n"
            },
            {
              "text": "Une erreur, le maximum apparaissant plusieurs fois",
              "correct": false,
              "feedback": "Erreur : `index` accepte les répétitions ; il renvoie la\npremière position.\n"
            }
          ],
          "explanation": "`max` donne la valeur, `index` sa première position : combinés, ils\nlocalisent le maximum."
        }
      ]
    },
    {
      "id": "q36",
      "difficulty": 2,
      "skills": [
        "listes",
        "tri",
        "sorted"
      ],
      "title": "Trier sans modifier la liste",
      "partie": "listes",
      "statement": "Qu'affiche ce programme ?\n```python\nL = [5, 2, 8]\nM = sorted(L)\nprint(L, M)\n```",
      "options": [
        {
          "text": "`[5, 2, 8] [2, 5, 8]`, `sorted` renvoyant une copie triée",
          "correct": true,
          "feedback": "Bonne réponse : `sorted(L)` construit une nouvelle liste triée\net laisse `L` intacte.\n"
        },
        {
          "text": "`[2, 5, 8] [2, 5, 8]`, les deux listes triées",
          "correct": false,
          "feedback": "Erreur : c'est `L.sort()` qui trie `L` sur place.\n"
        },
        {
          "text": "`[5, 2, 8] None`, le tri ne renvoyant rien",
          "correct": false,
          "feedback": "Erreur : `L.sort()` renvoie `None`, mais `sorted(L)` renvoie\nla liste triée.\n"
        },
        {
          "text": "Une erreur, `sorted` s'appliquant seulement aux nombres triés",
          "correct": false,
          "feedback": "Erreur : `sorted` accepte toute liste de nombres.\n"
        }
      ],
      "explanation": "`sorted(L)` renvoie une copie triée ; `L.sort()` trie la liste\nelle-même et renvoie `None`."
    },
    {
      "id": "q37",
      "difficulty": 2,
      "skills": [
        "listes",
        "indices",
        "somme"
      ],
      "title": "Somme des éléments d'indice pair",
      "partie": "listes",
      "statement": "Avec `L = [3, 1, 4, 1, 5]`, que vaut `sum(L[i] for i in range(0, len(L), 2))` ?",
      "options": [
        {
          "text": "`12`, la somme des éléments d'indices $0$, $2$ et $4$",
          "correct": true,
          "feedback": "Bonne réponse : `range(0, 5, 2)` parcourt $0$, $2$ et $4$, et\nla somme porte sur ces trois éléments.\n"
        },
        {
          "text": "`2`, la somme des éléments d'indices $1$ et $3$",
          "correct": false,
          "feedback": "Erreur : le parcours commence à l'indice $0$.\n"
        },
        {
          "text": "`14`, la somme de tous les éléments",
          "correct": false,
          "feedback": "Erreur : le pas $2$ saute un élément sur deux.\n"
        },
        {
          "text": "`6`, la somme des indices pairs",
          "correct": false,
          "feedback": "Erreur : on additionne `L[i]`, pas `i`.\n"
        }
      ],
      "explanation": "Le troisième argument de `range` fixe le pas du parcours.",
      "variants": [
        {
          "statement": "Avec `L = [3, 1, 4, 1, 5]`, que vaut `sum(L[i] for i in range(0, len(L), 2))` ?",
          "options": [
            {
              "text": "`12`, la somme des éléments d'indices $0$, $2$ et $4$",
              "correct": true,
              "feedback": "Bonne réponse : `range(0, 5, 2)` parcourt $0$, $2$ et $4$, et\nla somme porte sur ces trois éléments.\n"
            },
            {
              "text": "`2`, la somme des éléments d'indices $1$ et $3$",
              "correct": false,
              "feedback": "Erreur : le parcours commence à l'indice $0$.\n"
            },
            {
              "text": "`14`, la somme de tous les éléments",
              "correct": false,
              "feedback": "Erreur : le pas $2$ saute un élément sur deux.\n"
            },
            {
              "text": "`6`, la somme des indices pairs",
              "correct": false,
              "feedback": "Erreur : on additionne `L[i]`, pas `i`.\n"
            }
          ],
          "explanation": "Le troisième argument de `range` fixe le pas du parcours."
        },
        {
          "statement": "Avec `L = [2, 7, 1, 8, 2]`, que vaut `sum(L[i] for i in range(0, len(L), 2))` ?",
          "options": [
            {
              "text": "`5`, la somme des éléments d'indices $0$, $2$ et $4$",
              "correct": true,
              "feedback": "Bonne réponse : `range(0, 5, 2)` parcourt $0$, $2$ et $4$, et\nla somme porte sur ces trois éléments.\n"
            },
            {
              "text": "`15`, la somme des éléments d'indices $1$ et $3$",
              "correct": false,
              "feedback": "Erreur : le parcours commence à l'indice $0$.\n"
            },
            {
              "text": "`20`, la somme de tous les éléments",
              "correct": false,
              "feedback": "Erreur : le pas $2$ saute un élément sur deux.\n"
            },
            {
              "text": "`6`, la somme des indices pairs",
              "correct": false,
              "feedback": "Erreur : on additionne `L[i]`, pas `i`.\n"
            }
          ],
          "explanation": "Le troisième argument de `range` fixe le pas du parcours."
        },
        {
          "statement": "Avec `L = [6, 3, 5, 9, 0]`, que vaut `sum(L[i] for i in range(0, len(L), 2))` ?",
          "options": [
            {
              "text": "`11`, la somme des éléments d'indices $0$, $2$ et $4$",
              "correct": true,
              "feedback": "Bonne réponse : `range(0, 5, 2)` parcourt $0$, $2$ et $4$, et\nla somme porte sur ces trois éléments.\n"
            },
            {
              "text": "`12`, la somme des éléments d'indices $1$ et $3$",
              "correct": false,
              "feedback": "Erreur : le parcours commence à l'indice $0$.\n"
            },
            {
              "text": "`23`, la somme de tous les éléments",
              "correct": false,
              "feedback": "Erreur : le pas $2$ saute un élément sur deux.\n"
            },
            {
              "text": "`6`, la somme des indices pairs",
              "correct": false,
              "feedback": "Erreur : on additionne `L[i]`, pas `i`.\n"
            }
          ],
          "explanation": "Le troisième argument de `range` fixe le pas du parcours."
        }
      ]
    },
    {
      "id": "q38",
      "difficulty": 3,
      "skills": [
        "listes",
        "comprehension",
        "couples",
        "denombrement"
      ],
      "title": "Compter les couples ordonnés",
      "partie": "listes",
      "statement": "Que vaut `len([(i, j) for i in range(4) for j in range(4) if i < j])` ?",
      "options": [
        {
          "text": "`6`, le nombre de couples $(i, j)$ avec $i < j$",
          "correct": true,
          "feedback": "Bonne réponse : $(0,1)$, $(0,2)$, $(0,3)$, $(1,2)$, $(1,3)$,\n$(2,3)$, soit $\\binom{4}{2} = 6$.\n"
        },
        {
          "text": "`16`, le nombre total de couples",
          "correct": false,
          "feedback": "Erreur : la condition `if i < j` n'en garde qu'une partie.\n"
        },
        {
          "text": "`12`, les couples d'éléments distincts",
          "correct": false,
          "feedback": "Erreur : `i < j` élimine aussi les couples avec $i > j$, pas\nseulement $i = j$.\n"
        },
        {
          "text": "`4`, une valeur par `i`",
          "correct": false,
          "feedback": "Erreur : chaque `i` se combine avec plusieurs `j`.\n"
        }
      ],
      "explanation": "Une double compréhension avec `i < j` énumère les paires, sans\nordre ni répétition."
    },
    {
      "id": "q39",
      "difficulty": 3,
      "skills": [
        "listes",
        "parcours",
        "signe"
      ],
      "title": "Compter les changements de signe",
      "partie": "listes",
      "statement": "Qu'affiche ce programme ?\n```python\nL = [-3, -1, 2, 5, -2]\nc = 0\nfor i in range(len(L) - 1):\n    if L[i] * L[i + 1] < 0:\n        c = c + 1\nprint(c)\n```",
      "options": [
        {
          "text": "`2`, le nombre de changements de signe entre voisins",
          "correct": true,
          "feedback": "Bonne réponse : un produit négatif signale deux voisins de\nsignes contraires ; cela arrive entre $-1$ et $2$, puis entre\n$5$ et $-2$.\n"
        },
        {
          "text": "`4`, le nombre de paires de voisins",
          "correct": false,
          "feedback": "Erreur : seules les paires de signes contraires comptent.\n"
        },
        {
          "text": "`3`, le nombre de valeurs négatives",
          "correct": false,
          "feedback": "Erreur : le test porte sur un produit de voisins, pas sur le\nsigne d'une valeur.\n"
        },
        {
          "text": "`1`, un seul passage du négatif au positif",
          "correct": false,
          "feedback": "Erreur : le passage du positif au négatif compte aussi.\n"
        }
      ],
      "explanation": "Compter les changements de signe d'une liste de valeurs d'une\nfonction localise les intervalles où elle s'annule."
    },
    {
      "id": "q40",
      "difficulty": 2,
      "skills": [
        "euler",
        "equation-differentielle"
      ],
      "title": "Deux pas de la méthode d'Euler",
      "partie": "analyse",
      "statement": "On applique la méthode d'Euler à $y' = y$ avec $y(0) = 1$ et un\npas $h = 0{,}5$. Qu'affiche ce programme ?\n```python\ny = 1\nh = 0.5\nfor i in range(2):\n    y = y + h * y\nprint(y)\n```",
      "options": [
        {
          "text": "`2.25`, soit $1{,}5^2$",
          "correct": true,
          "feedback": "Bonne réponse : chaque pas multiplie `y` par $1 + h = 1{,}5$ ;\ndeux pas donnent $1{,}5^2$.\n"
        },
        {
          "text": "`2.0`, soit $1 + 2 \\times 0{,}5$",
          "correct": false,
          "feedback": "Erreur : le second pas utilise la valeur $1{,}5$, pas $1$.\n"
        },
        {
          "text": "`1.5`, un seul pas",
          "correct": false,
          "feedback": "Erreur : `range(2)` fait deux tours.\n"
        },
        {
          "text": "`2.718…`, la valeur exacte $\\mathrm{e}$",
          "correct": false,
          "feedback": "Erreur : Euler donne une valeur approchée de $y(1) =\n\\mathrm{e}$, ici par défaut.\n"
        }
      ],
      "explanation": "Pour $y' = y$, un pas d'Euler multiplie la valeur par $1 + h$ ; la\nméthode approche $\\mathrm{e}$ quand $h$ tend vers $0$."
    },
    {
      "id": "q41",
      "difficulty": 3,
      "skills": [
        "suite-geometrique",
        "somme",
        "seuil",
        "while"
      ],
      "title": "Somme géométrique à un centième de sa limite",
      "partie": "analyse",
      "statement": "Qu'affiche ce programme ?\n```python\ns = 0\nn = 0\nwhile 2 - s > 0.01:\n    s = s + 0.5 ** n\n    n = n + 1\nprint(n)\n```",
      "options": [
        {
          "text": "`8`, nombre de termes pour approcher $2$ à $0{,}01$ près",
          "correct": true,
          "feedback": "Bonne réponse : après $n$ termes, $2 - s = 0{,}5^{n-1}$ ; il\nfaut $0{,}5^{n-1} \\leq 0{,}01$, soit $n - 1 \\geq 7$.\n"
        },
        {
          "text": "`7`, le dernier rang où l'écart dépasse $0{,}01$",
          "correct": false,
          "feedback": "Erreur : avec $7$ termes l'écart vaut $0{,}5^6 \\approx 0{,}016$,\nla boucle continue.\n"
        },
        {
          "text": "`2`, la limite de la somme",
          "correct": false,
          "feedback": "Erreur : le programme affiche le nombre de termes, pas la\nlimite.\n"
        },
        {
          "text": "`100`, l'inverse de la précision",
          "correct": false,
          "feedback": "Erreur : la convergence géométrique demande bien moins de\ntermes.\n"
        }
      ],
      "explanation": "La somme $1 + 0{,}5 + \\ldots + 0{,}5^{n-1}$ vaut $2 - 0{,}5^{n-1}$\net converge vers $2$."
    },
    {
      "id": "q42",
      "difficulty": 2,
      "skills": [
        "simulation",
        "binomiale",
        "fonction"
      ],
      "title": "Simuler une variable binomiale",
      "partie": "probabilites",
      "statement": "Que renvoie l'appel `binom(10, 0.5)` ?\n```python\nfrom random import random\n\ndef binom(n, p):\n    s = 0\n    for i in range(n):\n        if random() < p:\n            s = s + 1\n    return s\n```",
      "options": [
        {
          "text": "Un entier entre `0` et `10`, le nombre de succès simulés",
          "correct": true,
          "feedback": "Bonne réponse : chaque tour simule une épreuve de probabilité\n$0{,}5$ ; `s` compte les succès et suit la loi binomiale de\nparamètres $10$ et $0{,}5$.\n"
        },
        {
          "text": "Toujours `5`, l'espérance de la loi",
          "correct": false,
          "feedback": "Erreur : la valeur varie d'un appel à l'autre, $5$ n'est que\nla moyenne attendue.\n"
        },
        {
          "text": "Un flottant entre `0` et `1`, la fréquence des succès",
          "correct": false,
          "feedback": "Erreur : la fonction renvoie `s`, pas `s / n`.\n"
        },
        {
          "text": "`10`, le nombre d'épreuves",
          "correct": false,
          "feedback": "Erreur : `s` ne compte que les tours où `random() < p`.\n"
        }
      ],
      "explanation": "Une variable binomiale est une somme de variables de Bernoulli\nindépendantes : la boucle les simule une à une."
    },
    {
      "id": "q43",
      "difficulty": 2,
      "skills": [
        "comb",
        "denombrement",
        "binomiale"
      ],
      "title": "Compter les chemins de l'arbre avec comb",
      "partie": "probabilites",
      "statement": "Dans un schéma de Bernoulli à $6$ épreuves, combien de chemins\ncomportent exactement $2$ succès ? Quelle instruction le calcule ?",
      "options": [
        {
          "text": "`15`, donné par `comb(6, 2)`",
          "correct": true,
          "feedback": "Bonne réponse : $\\binom{6}{2} = 15$ chemins, calculé par\n`comb` du module `math`.\n"
        },
        {
          "text": "`30`, donné par `6 * 5`",
          "correct": false,
          "feedback": "Erreur : $6 \\times 5$ compte deux fois chaque chemin, l'ordre\ndes deux succès n'important pas.\n"
        },
        {
          "text": "`12`, donné par `6 * 2`",
          "correct": false,
          "feedback": "Erreur : le produit $6 \\times 2$ ne compte aucun chemin.\n"
        },
        {
          "text": "`720`, donné par `factorial(6)`",
          "correct": false,
          "feedback": "Erreur : $6!$ compte les ordres de six objets distincts.\n"
        }
      ],
      "explanation": "Le coefficient binomial $\\binom{n}{k}$ compte les chemins à $k$\nsuccès ; `math.comb(n, k)` le calcule."
    },
    {
      "id": "q44",
      "difficulty": 3,
      "skills": [
        "binomiale",
        "contraire",
        "boucle"
      ],
      "title": "Un « au moins » par l'événement contraire",
      "partie": "probabilites",
      "statement": "$X$ suit la loi binomiale de paramètres $10$ et $0{,}2$. Que\ncalcule ce programme ?\n```python\nfrom math import comb\n\ndef p(n, k, q):\n    return comb(n, k) * q ** k * (1 - q) ** (n - k)\n\ns = 0\nfor k in range(3):\n    s = s + p(10, k, 0.2)\nprint(1 - s)\n```",
      "options": [
        {
          "text": "$P(X \\geq 3) \\approx 0{,}322$",
          "correct": true,
          "feedback": "Bonne réponse : la boucle somme $P(X = 0)$, $P(X = 1)$ et\n$P(X = 2)$, soit $P(X \\leq 2)$ ; le complément est\n$P(X \\geq 3)$.\n"
        },
        {
          "text": "$P(X \\leq 2) \\approx 0{,}678$",
          "correct": false,
          "feedback": "Erreur : c'est la valeur de `s`, pas de `1 - s`.\n"
        },
        {
          "text": "$P(X > 3) \\approx 0{,}121$",
          "correct": false,
          "feedback": "Erreur : `range(3)` s'arrête à $k = 2$, donc $k = 3$ fait\npartie du complément.\n"
        },
        {
          "text": "$P(X = 3) \\approx 0{,}201$",
          "correct": false,
          "feedback": "Erreur : le programme somme plusieurs probabilités avant de\npasser au complément.\n"
        }
      ],
      "explanation": "$P(X \\geq k)$ se calcule par $1 - P(X \\leq k - 1)$, la somme\nportant sur $k$ termes."
    },
    {
      "id": "q45",
      "difficulty": 3,
      "skills": [
        "simulation",
        "echantillon",
        "fluctuation"
      ],
      "title": "Part des échantillons hors de l'intervalle",
      "partie": "probabilites",
      "statement": "Qu'affiche ce programme ?\n```python\nfrom random import random\n\ndef frequence(n, p):\n    c = 0\n    for i in range(n):\n        if random() < p:\n            c = c + 1\n    return c / n\n\nnb = 0\nfor j in range(1000):\n    if abs(frequence(100, 0.5) - 0.5) > 0.1:\n        nb = nb + 1\nprint(nb / 1000)\n```",
      "options": [
        {
          "text": "Un nombre inférieur à `0.1`, une petite minorité d'échantillons",
          "correct": true,
          "feedback": "Bonne réponse : pour $n = 100$, $\\frac{1}{\\sqrt{n}} = 0{,}1$ ;\nla fréquence sort de $[0{,}4 ; 0{,}6]$ dans environ $5\\ \\%$\ndes échantillons.\n"
        },
        {
          "text": "Un nombre proche de `0.5`, la moitié des échantillons",
          "correct": false,
          "feedback": "Erreur : la plupart des fréquences restent à moins de\n$\\frac{1}{\\sqrt{n}}$ de $p$.\n"
        },
        {
          "text": "`0.0`, la fréquence restant toujours dans l'intervalle",
          "correct": false,
          "feedback": "Erreur : l'intervalle n'est pas une certitude, quelques\néchantillons en sortent.\n"
        },
        {
          "text": "Un nombre proche de `0.95`, la plupart des échantillons",
          "correct": false,
          "feedback": "Erreur : le programme compte les échantillons qui sortent de\nl'intervalle, pas ceux qui y restent.\n"
        }
      ],
      "explanation": "La proportion d'échantillons dont la fréquence s'écarte de $p$ de\nplus de $\\frac{1}{\\sqrt{n}}$ est faible, de l'ordre de $5\\ \\%$."
    }
  ]
}