{
  "chapter": {
    "id": "diviser-pour-regner",
    "level": "terminale",
    "theme": "Algorithmique",
    "title": "Diviser pour régner",
    "description": "Paradigme diviser pour régner (étapes diviser, régner, combiner),\nrecherche dichotomique, tri fusion et tri rapide, exponentiation\nrapide, complexité par récurrence et théorème maître.",
    "parties": [
      {
        "id": "principe",
        "title": "Principe et complexité"
      },
      {
        "id": "tri-fusion",
        "title": "Tri fusion"
      },
      {
        "id": "autres",
        "title": "Dichotomie et exponentiation rapide"
      }
    ],
    "prerequisites": [],
    "references": []
  },
  "questions": [
    {
      "id": "q01",
      "difficulty": 1,
      "skills": [
        "paradigme",
        "definition"
      ],
      "title": "Étapes du paradigme diviser pour régner",
      "partie": "principe",
      "statement": "Quelles sont les **trois étapes** du paradigme diviser pour\nrégner ?",
      "options": [
        {
          "text": "Initialiser, itérer, terminer",
          "correct": false,
          "feedback": "Erreur : ces étapes décrivent une boucle, pas le paradigme\ndiviser pour régner qui est typiquement récursif.\n"
        },
        {
          "text": "Diviser, régner, combiner",
          "correct": true,
          "feedback": "Bonne réponse : on divise le problème en sous-problèmes\nplus petits, on les résout (récursivement), puis on\ncombine les solutions partielles pour obtenir la solution\ndu problème initial.\n"
        },
        {
          "text": "Trier, fusionner, comparer",
          "correct": false,
          "feedback": "Erreur : ces opérations apparaissent dans le tri fusion\n(un cas particulier), mais ne sont pas les trois étapes\ngénérales du paradigme.\n"
        },
        {
          "text": "Identifier, calculer, vérifier",
          "correct": false,
          "feedback": "Erreur : ces verbes décrivent une démarche scientifique\ngénérale, pas la stratégie diviser pour régner.\n"
        }
      ],
      "explanation": "Le paradigme repose sur l'idée que résoudre un sous-problème\nplus petit est plus simple, et que combiner les solutions\npartielles donne efficacement la solution complète. C'est\nl'idée mère de la recherche dichotomique, du tri fusion, de\nl'exponentiation rapide, etc."
    },
    {
      "id": "q02",
      "difficulty": 1,
      "skills": [
        "dichotomie",
        "complexite"
      ],
      "title": "Complexité de la recherche dichotomique",
      "partie": "autres",
      "statement": "Quelle est la complexité au pire de la recherche dichotomique\nsur un tableau trié de $n$ éléments ?",
      "options": [
        {
          "text": "$O(\\log n)$",
          "correct": true,
          "feedback": "Bonne réponse : à chaque étape, l'intervalle de recherche\nest divisé par deux. Le nombre d'étapes est donc le\nlogarithme en base $2$ de $n$.\n"
        },
        {
          "text": "$O(n \\log n)$",
          "correct": false,
          "feedback": "Erreur : c'est la complexité du tri fusion, pas d'une\nrecherche.\n"
        },
        {
          "text": "$O(n)$",
          "correct": false,
          "feedback": "Erreur : c'est la complexité de la recherche **linéaire**.\nLa dichotomie est plus rapide grâce au tri préalable.\n"
        },
        {
          "text": "$O(1)$",
          "correct": false,
          "feedback": "Erreur : ce serait une recherche en temps constant, ce\nqui n'est pas réaliste pour rechercher un élément dans\nun tableau de taille variable.\n"
        }
      ],
      "explanation": "Pour $n = 10^9$, la dichotomie effectue au plus $30$\ncomparaisons. C'est l'un des gains algorithmiques les plus\nspectaculaires : passer de linéaire à logarithmique."
    },
    {
      "id": "q03",
      "difficulty": 1,
      "skills": [
        "tri-fusion",
        "principe"
      ],
      "title": "Principe du tri fusion",
      "partie": "tri-fusion",
      "statement": "Quel est le principe du **tri fusion** ?",
      "options": [
        {
          "text": "Chercher le plus petit élément, le placer en début, recommencer",
          "correct": false,
          "feedback": "Erreur : c'est le principe du tri par sélection.\n"
        },
        {
          "text": "Couper en deux moitiés, trier chacune récursivement, puis les fusionner",
          "correct": true,
          "feedback": "Bonne réponse : c'est l'application directe du paradigme\ndiviser pour régner. La fusion de deux tableaux triés\nse fait en temps linéaire en parcourant les deux\nsimultanément.\n"
        },
        {
          "text": "Insérer chaque élément à sa place dans la portion déjà triée",
          "correct": false,
          "feedback": "Erreur : c'est le principe du tri par insertion.\n"
        },
        {
          "text": "Comparer chaque paire d'éléments adjacents et les permuter si nécessaire",
          "correct": false,
          "feedback": "Erreur : c'est le principe du tri à bulles, en $O(n^2)$.\n"
        }
      ],
      "explanation": "Le tri fusion est l'archétype du tri par diviser pour régner.\nSa complexité $O(n \\log n)$ ne dépend pas de l'ordre initial,\nce qui en fait un tri à comportement **prévisible**."
    },
    {
      "id": "q04",
      "difficulty": 1,
      "skills": [
        "tri-fusion",
        "complexite"
      ],
      "title": "Complexité du tri fusion",
      "partie": "tri-fusion",
      "statement": "Quelle est la complexité du tri fusion sur un tableau de $n$\néléments ?",
      "options": [
        {
          "text": "$O(n \\log n)$",
          "correct": true,
          "feedback": "Bonne réponse : il y a $\\log n$ niveaux de récursion (on\ndivise par deux à chaque niveau). À chaque niveau, on\nparcourt l'ensemble des $n$ éléments lors des fusions.\nTotal : $n \\log n$.\n"
        },
        {
          "text": "$O(n^2)$",
          "correct": false,
          "feedback": "Erreur : c'est la complexité des tris naïfs (sélection,\ninsertion, bulles). Le tri fusion est meilleur grâce au\nparadigme DPR.\n"
        },
        {
          "text": "$O(2^n)$",
          "correct": false,
          "feedback": "Erreur : aucun tri usuel n'est exponentiel.\n"
        },
        {
          "text": "$O(n)$",
          "correct": false,
          "feedback": "Erreur : la fusion seule est en $O(n)$, mais on la\nrépète sur $\\log n$ niveaux de récursion, ce qui donne\n$O(n \\log n)$ au total.\n"
        }
      ],
      "explanation": "Le tri fusion est **stable** (préserve l'ordre des éléments\négaux) et a une complexité **garantie** $O(n \\log n)$ dans\ntous les cas, ce qui le rend prédictible. Son inconvénient\nprincipal : il n'est **pas en place**."
    },
    {
      "id": "q05",
      "difficulty": 1,
      "skills": [
        "tri-fusion",
        "base"
      ],
      "title": "Cas de base du tri fusion",
      "partie": "tri-fusion",
      "statement": "Quel est le **cas de base** du tri fusion ?",
      "options": [
        {
          "text": "Un tableau de deux éléments",
          "correct": false,
          "feedback": "Erreur : un tableau de deux éléments peut être mal\ntrié. Il faut soit le diviser à nouveau, soit le trier\ndirectement (cas particulier optimisé).\n"
        },
        {
          "text": "Un tableau trié",
          "correct": false,
          "feedback": "Erreur : on ne sait pas a priori si le tableau est trié\n(sans le parcourir). Le cas de base du tri fusion est\nbasé sur la **taille**, pas sur l'ordre.\n"
        },
        {
          "text": "Un tableau de longueur paire",
          "correct": false,
          "feedback": "Erreur : la parité ne garantit pas qu'un tableau soit\ntrié. Le tri fusion fonctionne pour toute parité.\n"
        },
        {
          "text": "Un tableau de zéro ou un élément",
          "correct": true,
          "feedback": "Bonne réponse : un tableau vide ou de longueur $1$ est\ndéjà trié par définition. La récursion s'arrête à ce\nniveau, sans nouvelle découpe ni fusion.\n"
        }
      ],
      "explanation": "Choisir un cas de base à $0$ ou $1$ élément simplifie le\ncode : on n'a même pas besoin de gérer la division pour ces\ncas. Cela rend la fonction parfaitement récursive."
    },
    {
      "id": "q06",
      "difficulty": 1,
      "skills": [
        "exponentiation-rapide"
      ],
      "title": "Principe de l'exponentiation rapide",
      "partie": "autres",
      "statement": "L'**exponentiation rapide** calcule $a^n$ en exploitant\nquelle propriété mathématique ?",
      "options": [
        {
          "text": "$a^n = a^{n-1} \\cdot a$ si $n \\geq 1$, avec $a^0 = 1$",
          "correct": false,
          "feedback": "Erreur : c'est la définition récursive **naïve** de la\npuissance, en $O(n)$. L'exponentiation rapide va beaucoup\nplus vite.\n"
        },
        {
          "text": "$a^n = a + a + \\cdots + a$ ($n$ fois)",
          "correct": false,
          "feedback": "Erreur : c'est la définition de la multiplication, pas\nde la puissance. L'exponentiation rapide ne peut pas\npartir d'une somme.\n"
        },
        {
          "text": "$a^n = (a^{n/2})^2$ si $n$ est pair, et $a^n = a \\cdot (a^{(n-1)/2})^2$ si $n$ est impair",
          "correct": true,
          "feedback": "Bonne réponse : on divise l'exposant par deux à chaque\nétape (au lieu de soustraire $1$). Cela amène la\ncomplexité de $O(n)$ à $O(\\log n)$.\n"
        },
        {
          "text": "$a^n = (a^2)^{n/2}$ si $n$ est pair, et $a^n = (a^2)^{(n-1)/2}$ si $n$ est impair",
          "correct": false,
          "feedback": "Erreur : le cas pair est juste, mais le cas impair oublie\nle facteur $a$ restant : $(a^2)^{(n-1)/2} = a^{n-1}$, pas\n$a^n$. Il faut multiplier par $a$ une dernière fois.\n"
        }
      ],
      "explanation": "Pour calculer $a^{20}$ : la méthode naïve fait $19$\nmultiplications, l'exponentiation rapide en fait environ\n$\\log_2(20) \\approx 5$. Le gain devient énorme pour de\ngrands exposants (cryptographie, arithmétique modulaire)."
    },
    {
      "id": "q07",
      "difficulty": 1,
      "skills": [
        "tri-fusion",
        "place"
      ],
      "title": "Tri fusion en place ?",
      "partie": "tri-fusion",
      "statement": "Le tri fusion est-il un tri **en place** ?",
      "options": [
        {
          "text": "Oui, il modifie le tableau d'origine sans mémoire supplémentaire",
          "correct": false,
          "feedback": "Erreur : le tri fusion utilise des tableaux auxiliaires\n(les moitiés gauche et droite, puis le résultat fusionné).\nSa mémoire supplémentaire est en $O(n)$.\n"
        },
        {
          "text": "Non, il utilise une mémoire supplémentaire proportionnelle à $n$",
          "correct": true,
          "feedback": "Bonne réponse : à chaque niveau de récursion, on crée des\ntableaux pour les moitiés et la fusion. C'est l'un des\ninconvénients du tri fusion, contrairement au tri par\ninsertion ou au tri par sélection.\n"
        },
        {
          "text": "Oui, mais seulement pour des listes de taille paire",
          "correct": false,
          "feedback": "Erreur : la parité n'a aucune influence sur le caractère\nen place ou non.\n"
        },
        {
          "text": "Non, mais il utilise une mémoire constante",
          "correct": false,
          "feedback": "Erreur : la mémoire supplémentaire n'est pas constante,\nelle est proportionnelle à la taille du tableau.\n"
        }
      ],
      "explanation": "Tris en place : par sélection, par insertion. Tri **non en\nplace** : tri fusion (mémoire $O(n)$). Cette mémoire\nsupplémentaire est le prix de son coût en $O(n \\log n)$."
    },
    {
      "id": "q08",
      "difficulty": 1,
      "skills": [
        "dichotomie",
        "prerequis"
      ],
      "title": "Pré-requis de la recherche dichotomique",
      "partie": "autres",
      "statement": "Quelle est la condition **indispensable** pour appliquer la\nrecherche dichotomique ?",
      "options": [
        {
          "text": "Le tableau doit être trié",
          "correct": true,
          "feedback": "Bonne réponse : la dichotomie compare l'élément cherché\nau milieu pour décider d'aller à gauche ou à droite. Si\nle tableau n'est pas trié, cette comparaison ne donne\naucune information utile, et l'algorithme peut renvoyer\nun faux négatif.\n"
        },
        {
          "text": "Le tableau doit être de taille puissance de $2$",
          "correct": false,
          "feedback": "Erreur : la taille n'a pas besoin d'être une puissance\nde $2$. La dichotomie fonctionne pour toute taille\n$\\geq 0$.\n"
        },
        {
          "text": "Le tableau doit avoir une taille connue à l'avance",
          "correct": false,
          "feedback": "Erreur : c'est une caractéristique des tableaux Python\nou C en général, pas une contrainte de la dichotomie.\n"
        },
        {
          "text": "Le tableau doit contenir uniquement des entiers",
          "correct": false,
          "feedback": "Erreur : la dichotomie fonctionne sur tout type\ncomparable (entiers, flottants, chaînes, dates, etc.).\n"
        }
      ],
      "explanation": "Si la liste n'est pas triée et que les recherches sont\noccasionnelles, mieux vaut faire une recherche linéaire\nqu'un tri préalable. La dichotomie est rentable quand on\nprévoit de très nombreuses recherches sur la même liste."
    },
    {
      "id": "q09",
      "difficulty": 1,
      "skills": [
        "recursivite-lien"
      ],
      "title": "Récursivité et diviser pour régner",
      "partie": "principe",
      "statement": "Pourquoi le paradigme diviser pour régner s'implémente-t-il\nnaturellement par **récursivité** ?",
      "options": [
        {
          "text": "Parce que la récursivité est le seul moyen de coder une boucle en Python",
          "correct": false,
          "feedback": "Erreur : Python permet aussi des boucles `for` et\n`while`. La récursivité est un choix, pas une\nobligation.\n"
        },
        {
          "text": "Parce que ce paradigme nécessite obligatoirement le recours à la mémoïsation",
          "correct": false,
          "feedback": "Erreur : la mémoïsation concerne la programmation\ndynamique, pas le diviser pour régner classique.\n"
        },
        {
          "text": "Parce que la récursivité est plus rapide que l'itération",
          "correct": false,
          "feedback": "Erreur : la récursivité est en réalité souvent un peu\n**plus lente** (surcoût des appels) en Python. Son\nintérêt est la lisibilité, pas la vitesse.\n"
        },
        {
          "text": "Parce que les sous-problèmes sont de même nature, ce qui s'exprime par récursivité",
          "correct": true,
          "feedback": "Bonne réponse : la définition même du paradigme implique\nque les sous-problèmes sont de même structure que le\nproblème principal. Une fonction qui s'appelle\nelle-même sur le sous-problème est l'expression la plus\ndirecte.\n"
        }
      ],
      "explanation": "Certains algorithmes DPR ont des versions itératives plus\nefficaces (recherche dichotomique itérative, exponentiation\nrapide itérative), mais la version récursive est souvent\nplus claire pédagogiquement."
    },
    {
      "id": "q10",
      "difficulty": 1,
      "skills": [
        "tri-fusion",
        "fusion"
      ],
      "title": "Fusion de deux listes triées",
      "partie": "tri-fusion",
      "statement": "Pour fusionner deux listes **déjà triées** de longueur $n$\nchacune en une seule liste triée, quelle est la complexité\nde l'opération ?",
      "options": [
        {
          "text": "$O(n^2)$",
          "correct": false,
          "feedback": "Erreur : on n'a pas besoin de comparer chaque élément à\ntous les autres, seulement aux candidats en tête de\nchaque liste.\n"
        },
        {
          "text": "$O(n \\log n)$",
          "correct": false,
          "feedback": "Erreur : c'est la complexité du tri fusion **complet**,\npas de la seule fusion. La fusion est l'étape\n« combiner » du paradigme.\n"
        },
        {
          "text": "$O(n)$",
          "correct": true,
          "feedback": "Bonne réponse : on parcourt les deux listes\nsimultanément avec un index pour chacune. Chaque\ncomparaison fait avancer l'un des deux index. Au total,\non fait $2n$ pas, soit $O(n)$.\n"
        },
        {
          "text": "$O(1)$",
          "correct": false,
          "feedback": "Erreur : il faut quand même parcourir les éléments des\ndeux listes au moins une fois pour les disposer dans\nl'ordre.\n"
        }
      ],
      "explanation": "C'est précisément cette fusion en $O(n)$ par niveau, répétée\nsur $\\log n$ niveaux, qui donne la complexité globale en\n$O(n \\log n)$ du tri fusion."
    },
    {
      "id": "q11",
      "difficulty": 2,
      "skills": [
        "dichotomie",
        "evaluation"
      ],
      "title": "Nombre de comparaisons en dichotomie",
      "partie": "autres",
      "statement": "Combien de comparaisons effectue **au pire** une recherche\ndichotomique sur un tableau de $1\\ 000$ éléments ?",
      "options": [
        {
          "text": "$1$",
          "correct": false,
          "feedback": "Erreur : on ne peut pas garantir une seule comparaison\ndans le pire cas. Le pire cas atteint $\\lceil \\log_2 n \\rceil$\ncomparaisons.\n"
        },
        {
          "text": "$500$",
          "correct": false,
          "feedback": "Erreur : la première étape de la dichotomie élimine la\nmoitié des candidats, mais on continue à diviser\nensuite. Le total est bien plus faible que $500$.\n"
        },
        {
          "text": "$1\\ 000$",
          "correct": false,
          "feedback": "Erreur : c'est le nombre maximal de comparaisons d'une\nrecherche **linéaire**. La dichotomie est bien plus\nrapide.\n"
        },
        {
          "text": "$10$",
          "correct": true,
          "feedback": "Bonne réponse : $\\log_2(1\\ 000) \\approx 9{,}97$, soit\nenviron $10$. Au pire, $10$ comparaisons suffisent pour\ntrouver l'élément ou conclure à son absence.\n"
        }
      ],
      "explanation": "Repère utile : doubler la taille n'ajoute qu'**une**\ncomparaison. Pour passer de $1\\ 000$ à $2\\ 000$, on passe de\n$10$ à $11$ comparaisons. C'est ce qui rend les algorithmes\nlogarithmiques exceptionnellement rapides à grande échelle.",
      "variants": [
        {
          "statement": "Combien de comparaisons effectue **au pire** une recherche\ndichotomique sur un tableau de $1\\ 000$ éléments ?",
          "options": [
            {
              "text": "$1$",
              "correct": false,
              "feedback": "Erreur : on ne peut pas garantir une seule comparaison\ndans le pire cas. Le pire cas atteint $\\lceil \\log_2 n \\rceil$\ncomparaisons.\n"
            },
            {
              "text": "$500$",
              "correct": false,
              "feedback": "Erreur : la première étape de la dichotomie élimine la\nmoitié des candidats, mais on continue à diviser\nensuite. Le total est bien plus faible que $500$.\n"
            },
            {
              "text": "$1\\ 000$",
              "correct": false,
              "feedback": "Erreur : c'est le nombre maximal de comparaisons d'une\nrecherche **linéaire**. La dichotomie est bien plus\nrapide.\n"
            },
            {
              "text": "$10$",
              "correct": true,
              "feedback": "Bonne réponse : $\\log_2(1\\ 000) \\approx 9{,}97$, soit\nenviron $10$. Au pire, $10$ comparaisons suffisent pour\ntrouver l'élément ou conclure à son absence.\n"
            }
          ],
          "explanation": "Repère utile : doubler la taille n'ajoute qu'**une**\ncomparaison. Pour passer de $1\\ 000$ à $2\\ 000$, on passe de\n$10$ à $11$ comparaisons. C'est ce qui rend les algorithmes\nlogarithmiques exceptionnellement rapides à grande échelle."
        },
        {
          "statement": "Combien de comparaisons effectue **au pire** une recherche\ndichotomique sur un tableau de $1\\ 000\\ 000$ éléments ?",
          "options": [
            {
              "text": "$1$",
              "correct": false,
              "feedback": "Erreur : on ne peut pas garantir une seule comparaison\ndans le pire cas. Le pire cas atteint $\\lceil \\log_2 n \\rceil$\ncomparaisons.\n"
            },
            {
              "text": "$500\\ 000$",
              "correct": false,
              "feedback": "Erreur : la première étape de la dichotomie élimine la\nmoitié des candidats, mais on continue à diviser\nensuite. Le total est bien plus faible que $500\\ 000$.\n"
            },
            {
              "text": "$1\\ 000\\ 000$",
              "correct": false,
              "feedback": "Erreur : c'est le nombre maximal de comparaisons d'une\nrecherche **linéaire**. La dichotomie est bien plus\nrapide.\n"
            },
            {
              "text": "$20$",
              "correct": true,
              "feedback": "Bonne réponse : $\\log_2(1\\ 000\\ 000) \\approx 19{,}93$, soit\nenviron $20$. Au pire, $20$ comparaisons suffisent pour\ntrouver l'élément ou conclure à son absence.\n"
            }
          ],
          "explanation": "Repère utile : doubler la taille n'ajoute qu'**une**\ncomparaison. Pour passer de $1\\ 000\\ 000$ à $2\\ 000\\ 000$, on passe de\n$20$ à $21$ comparaisons. C'est ce qui rend les algorithmes\nlogarithmiques exceptionnellement rapides à grande échelle."
        },
        {
          "statement": "Combien de comparaisons effectue **au pire** une recherche\ndichotomique sur un tableau de $100$ éléments ?",
          "options": [
            {
              "text": "$1$",
              "correct": false,
              "feedback": "Erreur : on ne peut pas garantir une seule comparaison\ndans le pire cas. Le pire cas atteint $\\lceil \\log_2 n \\rceil$\ncomparaisons.\n"
            },
            {
              "text": "$50$",
              "correct": false,
              "feedback": "Erreur : la première étape de la dichotomie élimine la\nmoitié des candidats, mais on continue à diviser\nensuite. Le total est bien plus faible que $50$.\n"
            },
            {
              "text": "$100$",
              "correct": false,
              "feedback": "Erreur : c'est le nombre maximal de comparaisons d'une\nrecherche **linéaire**. La dichotomie est bien plus\nrapide.\n"
            },
            {
              "text": "$7$",
              "correct": true,
              "feedback": "Bonne réponse : $\\log_2(100) \\approx 6{,}64$, soit\nenviron $7$. Au pire, $7$ comparaisons suffisent pour\ntrouver l'élément ou conclure à son absence.\n"
            }
          ],
          "explanation": "Repère utile : doubler la taille n'ajoute qu'**une**\ncomparaison. Pour passer de $100$ à $200$, on passe de\n$7$ à $8$ comparaisons. C'est ce qui rend les algorithmes\nlogarithmiques exceptionnellement rapides à grande échelle."
        }
      ]
    },
    {
      "id": "q12",
      "difficulty": 2,
      "skills": [
        "tri-fusion",
        "deroulement"
      ],
      "title": "Tri fusion sur un exemple",
      "partie": "tri-fusion",
      "statement": "Si l'on applique le tri fusion à la liste $[5, 2, 8, 3, 9, 1]$,\nquelle est la première étape ?",
      "options": [
        {
          "text": "Diviser la liste en $[5, 2, 8]$ et $[3, 9, 1]$",
          "correct": true,
          "feedback": "Bonne réponse : on coupe la liste au milieu en deux\nsous-listes de taille (presque) égale. Chaque moitié\nsera triée récursivement avant la fusion finale.\n"
        },
        {
          "text": "Trouver le plus petit élément ($1$) et le placer en début",
          "correct": false,
          "feedback": "Erreur : c'est le tri par sélection. Le tri fusion ne\ncherche pas le minimum, il découpe la liste en deux.\n"
        },
        {
          "text": "Trier la liste avec une fonction `sorted` intégrée",
          "correct": false,
          "feedback": "Erreur : utiliser `sorted` éviterait l'algorithme\nétudié. La question porte sur le déroulement du tri\nfusion lui-même.\n"
        },
        {
          "text": "Comparer $5$ et $2$, les permuter",
          "correct": false,
          "feedback": "Erreur : c'est l'opération du tri à bulles. Le tri\nfusion ne fait pas de comparaisons adjacentes au début.\n"
        }
      ],
      "explanation": "Après division récursive, on obtient des sous-listes de\ntaille $1$ (déjà triées). Puis les fusions remontent en\nreconstituant des sous-listes triées de plus en plus\ngrandes : $[2, 5]$, $[2, 5, 8]$, etc. jusqu'au tableau\ncomplet trié."
    },
    {
      "id": "q13",
      "difficulty": 2,
      "skills": [
        "exponentiation-rapide",
        "complexite"
      ],
      "title": "Complexité de l'exponentiation rapide",
      "partie": "autres",
      "statement": "Quelle est la complexité de l'exponentiation rapide pour\ncalculer $a^n$ ?",
      "options": [
        {
          "text": "$O(1)$",
          "correct": false,
          "feedback": "Erreur : la complexité dépend bien de $n$. Pour $n$\ntrès grand, le calcul nécessite plusieurs étapes.\n"
        },
        {
          "text": "$O(n)$",
          "correct": false,
          "feedback": "Erreur : c'est la complexité de la méthode **naïve**\n($a^n = a \\cdot a^{n-1}$, $n - 1$ multiplications).\nL'exponentiation rapide divise par deux au lieu de\ndécrémenter de $1$.\n"
        },
        {
          "text": "$O(\\log n)$",
          "correct": true,
          "feedback": "Bonne réponse : à chaque appel récursif, on divise\nl'exposant par deux. Il y a donc environ $\\log_2 n$\nniveaux d'appels, donc autant de multiplications.\n"
        },
        {
          "text": "$O(n^2)$",
          "correct": false,
          "feedback": "Erreur : aucune raison d'avoir une complexité quadratique\npour ce calcul.\n"
        }
      ],
      "explanation": "Pour $n = 10^{18}$, la méthode naïve ferait $10^{18} - 1$\nmultiplications (impossible). L'exponentiation rapide n'en\nfait qu'une soixantaine. Indispensable en cryptographie\nasymétrique (RSA)."
    },
    {
      "id": "q14",
      "difficulty": 2,
      "skills": [
        "cout",
        "tri-fusion"
      ],
      "title": "Les recopies de toutes les fusions",
      "partie": "principe",
      "statement": "Le tri fusion d'un tableau de $8$ éléments découpe le tableau jusqu'à des\ntableaux d'un seul élément, puis fusionne les moitiés triées. Fusionner\ndeux tableaux de tailles $a$ et $b$ recopie $a + b$ éléments dans le\nrésultat. Combien d'éléments sont recopiés au total par toutes les\nfusions du tri ?",
      "options": [
        {
          "text": "$8$",
          "correct": false,
          "feedback": "Erreur : $8$ est le travail de la seule dernière fusion. Les niveaux\nprécédents fusionnent aussi, chaque fois, l'ensemble des $8$ éléments\nrépartis en tableaux plus petits.\n"
        },
        {
          "text": "$7$",
          "correct": false,
          "feedback": "Erreur : $7$ est le nombre de fusions ($4 + 2 + 1$), pas le nombre\nd'éléments recopiés. Une fusion recopie tous les éléments des deux\ntableaux qu'elle réunit.\n"
        },
        {
          "text": "$24$",
          "correct": true,
          "feedback": "Bonne réponse : on effectue 4 fusions de tableaux de 1 élément (8 recopies), puis 2 fusions de tableaux de 2 éléments (8 recopies), puis 1 fusion de tableaux de 4 éléments (8 recopies). $3$ niveaux\nde $8$ recopies donnent $24$, soit $n \\log_2 n$ pour $n = 8$.\n"
        },
        {
          "text": "$64$",
          "correct": false,
          "feedback": "Erreur : $64$ vaut $n^2$, l'ordre de grandeur du tri par insertion dans\nle pire des cas. Le tri fusion ne recopie les $8$ éléments qu'une fois\npar niveau, sur $3$ niveaux.\n"
        }
      ],
      "explanation": "Le coût du tri fusion se compte niveau par niveau : chaque niveau de\nfusions traite les $n$ éléments, et il y a $\\log_2 n$ niveaux de\ndécoupage. D'où un coût de l'ordre de $n \\log_2 n$, contre $n^2$ pour le\ntri par insertion dans le pire des cas.",
      "variants": [
        {
          "statement": "Le tri fusion d'un tableau de $8$ éléments découpe le tableau jusqu'à des\ntableaux d'un seul élément, puis fusionne les moitiés triées. Fusionner\ndeux tableaux de tailles $a$ et $b$ recopie $a + b$ éléments dans le\nrésultat. Combien d'éléments sont recopiés au total par toutes les\nfusions du tri ?",
          "options": [
            {
              "text": "$8$",
              "correct": false,
              "feedback": "Erreur : $8$ est le travail de la seule dernière fusion. Les niveaux\nprécédents fusionnent aussi, chaque fois, l'ensemble des $8$ éléments\nrépartis en tableaux plus petits.\n"
            },
            {
              "text": "$7$",
              "correct": false,
              "feedback": "Erreur : $7$ est le nombre de fusions ($4 + 2 + 1$), pas le nombre\nd'éléments recopiés. Une fusion recopie tous les éléments des deux\ntableaux qu'elle réunit.\n"
            },
            {
              "text": "$24$",
              "correct": true,
              "feedback": "Bonne réponse : on effectue 4 fusions de tableaux de 1 élément (8 recopies), puis 2 fusions de tableaux de 2 éléments (8 recopies), puis 1 fusion de tableaux de 4 éléments (8 recopies). $3$ niveaux\nde $8$ recopies donnent $24$, soit $n \\log_2 n$ pour $n = 8$.\n"
            },
            {
              "text": "$64$",
              "correct": false,
              "feedback": "Erreur : $64$ vaut $n^2$, l'ordre de grandeur du tri par insertion dans\nle pire des cas. Le tri fusion ne recopie les $8$ éléments qu'une fois\npar niveau, sur $3$ niveaux.\n"
            }
          ],
          "explanation": "Le coût du tri fusion se compte niveau par niveau : chaque niveau de\nfusions traite les $n$ éléments, et il y a $\\log_2 n$ niveaux de\ndécoupage. D'où un coût de l'ordre de $n \\log_2 n$, contre $n^2$ pour le\ntri par insertion dans le pire des cas."
        },
        {
          "statement": "Le tri fusion d'un tableau de $16$ éléments découpe le tableau jusqu'à des\ntableaux d'un seul élément, puis fusionne les moitiés triées. Fusionner\ndeux tableaux de tailles $a$ et $b$ recopie $a + b$ éléments dans le\nrésultat. Combien d'éléments sont recopiés au total par toutes les\nfusions du tri ?",
          "options": [
            {
              "text": "$16$",
              "correct": false,
              "feedback": "Erreur : $16$ est le travail de la seule dernière fusion. Les niveaux\nprécédents fusionnent aussi, chaque fois, l'ensemble des $16$ éléments\nrépartis en tableaux plus petits.\n"
            },
            {
              "text": "$15$",
              "correct": false,
              "feedback": "Erreur : $15$ est le nombre de fusions ($8 + 4 + 2 + 1$), pas le nombre\nd'éléments recopiés. Une fusion recopie tous les éléments des deux\ntableaux qu'elle réunit.\n"
            },
            {
              "text": "$64$",
              "correct": true,
              "feedback": "Bonne réponse : on effectue 8 fusions de tableaux de 1 élément (16 recopies), puis 4 fusions de tableaux de 2 éléments (16 recopies), puis 2 fusions de tableaux de 4 éléments (16 recopies), puis 1 fusion de tableaux de 8 éléments (16 recopies). $4$ niveaux\nde $16$ recopies donnent $64$, soit $n \\log_2 n$ pour $n = 16$.\n"
            },
            {
              "text": "$256$",
              "correct": false,
              "feedback": "Erreur : $256$ vaut $n^2$, l'ordre de grandeur du tri par insertion dans\nle pire des cas. Le tri fusion ne recopie les $16$ éléments qu'une fois\npar niveau, sur $4$ niveaux.\n"
            }
          ],
          "explanation": "Le coût du tri fusion se compte niveau par niveau : chaque niveau de\nfusions traite les $n$ éléments, et il y a $\\log_2 n$ niveaux de\ndécoupage. D'où un coût de l'ordre de $n \\log_2 n$, contre $n^2$ pour le\ntri par insertion dans le pire des cas."
        },
        {
          "statement": "Le tri fusion d'un tableau de $32$ éléments découpe le tableau jusqu'à des\ntableaux d'un seul élément, puis fusionne les moitiés triées. Fusionner\ndeux tableaux de tailles $a$ et $b$ recopie $a + b$ éléments dans le\nrésultat. Combien d'éléments sont recopiés au total par toutes les\nfusions du tri ?",
          "options": [
            {
              "text": "$32$",
              "correct": false,
              "feedback": "Erreur : $32$ est le travail de la seule dernière fusion. Les niveaux\nprécédents fusionnent aussi, chaque fois, l'ensemble des $32$ éléments\nrépartis en tableaux plus petits.\n"
            },
            {
              "text": "$31$",
              "correct": false,
              "feedback": "Erreur : $31$ est le nombre de fusions ($16 + 8 + 4 + 2 + 1$), pas le nombre\nd'éléments recopiés. Une fusion recopie tous les éléments des deux\ntableaux qu'elle réunit.\n"
            },
            {
              "text": "$160$",
              "correct": true,
              "feedback": "Bonne réponse : on effectue 16 fusions de tableaux de 1 élément (32 recopies), puis 8 fusions de tableaux de 2 éléments (32 recopies), puis 4 fusions de tableaux de 4 éléments (32 recopies), puis 2 fusions de tableaux de 8 éléments (32 recopies), puis 1 fusion de tableaux de 16 éléments (32 recopies). $5$ niveaux\nde $32$ recopies donnent $160$, soit $n \\log_2 n$ pour $n = 32$.\n"
            },
            {
              "text": "$1024$",
              "correct": false,
              "feedback": "Erreur : $1024$ vaut $n^2$, l'ordre de grandeur du tri par insertion dans\nle pire des cas. Le tri fusion ne recopie les $32$ éléments qu'une fois\npar niveau, sur $5$ niveaux.\n"
            }
          ],
          "explanation": "Le coût du tri fusion se compte niveau par niveau : chaque niveau de\nfusions traite les $n$ éléments, et il y a $\\log_2 n$ niveaux de\ndécoupage. D'où un coût de l'ordre de $n \\log_2 n$, contre $n^2$ pour le\ntri par insertion dans le pire des cas."
        }
      ]
    },
    {
      "id": "q16",
      "difficulty": 2,
      "skills": [
        "comparaison",
        "ordres-de-grandeur"
      ],
      "title": "Tri fusion vs tri par insertion",
      "partie": "principe",
      "statement": "Pour trier un tableau de $1\\ 000\\ 000$ éléments, le tri\nfusion ($O(n \\log n)$) est environ combien de fois plus\nrapide que le tri par insertion ($O(n^2)$) ?",
      "options": [
        {
          "text": "$50\\ 000$ fois",
          "correct": true,
          "feedback": "Bonne réponse : pour $n = 1\\ 000\\ 000$, $n^2 = 10^{12}$ et\n$n \\log_2 n \\approx 2 \\cdot 10^7$. Le rapport est\nenviron $50\\ 000$. C'est la différence entre une seconde et $14$ heures sur la même machine.\n"
        },
        {
          "text": "$1\\ 000\\ 000$ fois",
          "correct": false,
          "feedback": "Erreur : ce serait le rapport $n^2 / n = n$, mais on\ndivise par $n \\log n$, pas par $n$.\n"
        },
        {
          "text": "$2$ fois",
          "correct": false,
          "feedback": "Erreur : la différence est bien plus grande. $\\log_2 n$\nn'est qu'une fraction de $n$ pour de grandes valeurs.\n"
        },
        {
          "text": "$10$ fois",
          "correct": false,
          "feedback": "Erreur : la différence est de plusieurs ordres de\ngrandeur, pas un seul facteur $10$.\n"
        }
      ],
      "explanation": "Cette différence d'ordre de grandeur explique pourquoi le\nchoix de l'algorithme est crucial. Sur petites entrées, les\ntris simples sont compétitifs ; sur grandes entrées, les\ntris en $O(n \\log n)$ deviennent indispensables.",
      "variants": [
        {
          "statement": "Pour trier un tableau de $1\\ 000\\ 000$ éléments, le tri\nfusion ($O(n \\log n)$) est environ combien de fois plus\nrapide que le tri par insertion ($O(n^2)$) ?",
          "options": [
            {
              "text": "$50\\ 000$ fois",
              "correct": true,
              "feedback": "Bonne réponse : pour $n = 1\\ 000\\ 000$, $n^2 = 10^{12}$ et\n$n \\log_2 n \\approx 2 \\cdot 10^7$. Le rapport est\nenviron $50\\ 000$. C'est la différence entre une seconde et $14$ heures sur la même machine.\n"
            },
            {
              "text": "$1\\ 000\\ 000$ fois",
              "correct": false,
              "feedback": "Erreur : ce serait le rapport $n^2 / n = n$, mais on\ndivise par $n \\log n$, pas par $n$.\n"
            },
            {
              "text": "$2$ fois",
              "correct": false,
              "feedback": "Erreur : la différence est bien plus grande. $\\log_2 n$\nn'est qu'une fraction de $n$ pour de grandes valeurs.\n"
            },
            {
              "text": "$10$ fois",
              "correct": false,
              "feedback": "Erreur : la différence est de plusieurs ordres de\ngrandeur, pas un seul facteur $10$.\n"
            }
          ],
          "explanation": "Cette différence d'ordre de grandeur explique pourquoi le\nchoix de l'algorithme est crucial. Sur petites entrées, les\ntris simples sont compétitifs ; sur grandes entrées, les\ntris en $O(n \\log n)$ deviennent indispensables."
        },
        {
          "statement": "Pour trier un tableau de $10\\ 000$ éléments, le tri\nfusion ($O(n \\log n)$) est environ combien de fois plus\nrapide que le tri par insertion ($O(n^2)$) ?",
          "options": [
            {
              "text": "$750$ fois",
              "correct": true,
              "feedback": "Bonne réponse : pour $n = 10\\ 000$, $n^2 = 10^8$ et\n$n \\log_2 n \\approx 1{,}3 \\cdot 10^5$. Le rapport est\nenviron $750$. C'est la différence entre une seconde et un quart d'heure sur la même machine.\n"
            },
            {
              "text": "$10\\ 000$ fois",
              "correct": false,
              "feedback": "Erreur : ce serait le rapport $n^2 / n = n$, mais on\ndivise par $n \\log n$, pas par $n$.\n"
            },
            {
              "text": "$2$ fois",
              "correct": false,
              "feedback": "Erreur : la différence est bien plus grande. $\\log_2 n$\nn'est qu'une fraction de $n$ pour de grandes valeurs.\n"
            },
            {
              "text": "$10$ fois",
              "correct": false,
              "feedback": "Erreur : la différence est de plusieurs ordres de\ngrandeur, pas un seul facteur $10$.\n"
            }
          ],
          "explanation": "Cette différence d'ordre de grandeur explique pourquoi le\nchoix de l'algorithme est crucial. Sur petites entrées, les\ntris simples sont compétitifs ; sur grandes entrées, les\ntris en $O(n \\log n)$ deviennent indispensables."
        },
        {
          "statement": "Pour trier un tableau de $1\\ 000\\ 000\\ 000$ éléments, le tri\nfusion ($O(n \\log n)$) est environ combien de fois plus\nrapide que le tri par insertion ($O(n^2)$) ?",
          "options": [
            {
              "text": "$33\\ 000\\ 000$ fois",
              "correct": true,
              "feedback": "Bonne réponse : pour $n = 1\\ 000\\ 000\\ 000$, $n^2 = 10^{18}$ et\n$n \\log_2 n \\approx 3 \\cdot 10^{10}$. Le rapport est\nenviron $33\\ 000\\ 000$. C'est la différence entre une seconde et un an sur la même machine.\n"
            },
            {
              "text": "$1\\ 000\\ 000\\ 000$ fois",
              "correct": false,
              "feedback": "Erreur : ce serait le rapport $n^2 / n = n$, mais on\ndivise par $n \\log n$, pas par $n$.\n"
            },
            {
              "text": "$2$ fois",
              "correct": false,
              "feedback": "Erreur : la différence est bien plus grande. $\\log_2 n$\nn'est qu'une fraction de $n$ pour de grandes valeurs.\n"
            },
            {
              "text": "$10$ fois",
              "correct": false,
              "feedback": "Erreur : la différence est de plusieurs ordres de\ngrandeur, pas un seul facteur $10$.\n"
            }
          ],
          "explanation": "Cette différence d'ordre de grandeur explique pourquoi le\nchoix de l'algorithme est crucial. Sur petites entrées, les\ntris simples sont compétitifs ; sur grandes entrées, les\ntris en $O(n \\log n)$ deviennent indispensables."
        }
      ]
    },
    {
      "id": "q17",
      "difficulty": 2,
      "skills": [
        "exponentiation-rapide",
        "optimisation"
      ],
      "title": "Optimisation par mémoïsation",
      "partie": "autres",
      "statement": "Dans une implémentation **récursive** d'exponentiation\nrapide, est-il utile d'ajouter de la **mémoïsation** ?",
      "options": [
        {
          "text": "Oui, la mémoïsation accélère nettement le calcul récursif",
          "correct": false,
          "feedback": "Erreur : à chaque appel, on calcule une seule valeur\nintermédiaire (`demi = puissance(a, n // 2)`), pas la\nmême plusieurs fois. La mémoïsation n'apporterait rien.\n"
        },
        {
          "text": "Non, l'exponentiation rapide ne fait pas d'appels redondants",
          "correct": true,
          "feedback": "Bonne réponse : à chaque appel, le sous-problème est\nunique (un seul exposant intermédiaire est calculé). Il\nn'y a donc aucun calcul redondant, contrairement à\nFibonacci naïf.\n"
        },
        {
          "text": "Oui, mais seulement pour des exposants pairs",
          "correct": false,
          "feedback": "Erreur : la mémoïsation n'est utile que s'il y a des\nappels redondants, ce qui n'est pas le cas ici.\n"
        },
        {
          "text": "Cela rendrait l'algorithme plus lent",
          "correct": false,
          "feedback": "Erreur : la mémoïsation seule ne ralentit pas\nsignificativement, mais l'avantage est nul ici.\n"
        }
      ],
      "explanation": "La distinction est cruciale : le diviser pour régner peut\navoir des sous-problèmes redondants (cas de Fibonacci) ou\nuniques (cas de l'exponentiation rapide). Seul le premier\nbénéficie de la mémoïsation."
    },
    {
      "id": "q18",
      "difficulty": 2,
      "skills": [
        "dichotomie",
        "code"
      ],
      "title": "Détection d'une erreur dans la dichotomie",
      "partie": "autres",
      "statement": "Dans la fonction suivante :\n\n```python\ndef recherche(x, tab):\n    gauche, droite = 0, len(tab) - 1\n    while gauche < droite:        # ← ICI\n        milieu = (gauche + droite) // 2\n        if tab[milieu] == x:\n            return milieu\n        elif tab[milieu] < x:\n            gauche = milieu + 1\n        else:\n            droite = milieu - 1\n    return -1\n```\n\nQuel est le bug ?",
      "options": [
        {
          "text": "Il manque l'initialisation de la variable `milieu` juste avant la boucle",
          "correct": false,
          "feedback": "Erreur : `milieu` est défini à l'intérieur de la boucle,\nce qui est la convention habituelle.\n"
        },
        {
          "text": "La condition de boucle devrait être `gauche <= droite`, pas `<`",
          "correct": true,
          "feedback": "Bonne réponse : avec `<` strict, on n'examine pas le\ndernier élément quand `gauche == droite`. La fonction\npeut renvoyer $-1$ pour un élément qui est en réalité\nprésent.\n"
        },
        {
          "text": "Le calcul de `milieu` est incorrect",
          "correct": false,
          "feedback": "Erreur : le calcul `(gauche + droite) // 2` est\nstandard et correct. Le bug est ailleurs.\n"
        },
        {
          "text": "La fonction devrait être récursive pour fonctionner",
          "correct": false,
          "feedback": "Erreur : la dichotomie peut s'écrire en itératif comme\nen récursif. La forme itérative est même souvent\npréférée.\n"
        }
      ],
      "explanation": "Erreur subtile et classique. Test concret : avec\n`tab = [5]` et `x = 5`, on a `gauche = droite = 0`, la\ncondition `gauche < droite` est fausse, on sort\nimmédiatement et on renvoie $-1$ alors que $x$ est présent."
    },
    {
      "id": "q19",
      "difficulty": 2,
      "skills": [
        "rotation-image",
        "matrice"
      ],
      "title": "Où va un pixel après un quart de tour",
      "partie": "principe",
      "statement": "Une image carrée de $n \\times n$ pixels est stockée dans un tableau\nde tableaux : `image[i][j]` est le pixel de la ligne `i` et de la\ncolonne `j`, les indices allant de `0` à `n - 1`. On tourne l'image\nd'un quart de tour dans le sens des aiguilles d'une montre. Où\narrive le pixel `image[i][j]` ?",
      "options": [
        {
          "text": "Ligne `n - 1 - j`, colonne `i`",
          "correct": false,
          "feedback": "Erreur : cette formule correspond au quart de tour dans le sens\ninverse. Sur l'image `[[1, 2, 3], [4, 5, 6], [7, 8, 9]]`, elle\nenvoie le pixel `1` en bas à gauche au lieu d'en haut à droite.\n"
        },
        {
          "text": "Ligne `j`, colonne `n - 1 - i`",
          "correct": true,
          "feedback": "Bonne réponse : la première ligne devient la dernière colonne.\nL'image `[[1, 2, 3], [4, 5, 6], [7, 8, 9]]` devient\n`[[7, 4, 1], [8, 5, 2], [9, 6, 3]]` : le pixel `1`, en `[0][0]`,\narrive en `[0][2]`.\n"
        },
        {
          "text": "Ligne `j`, colonne `i`",
          "correct": false,
          "feedback": "Erreur : échanger ligne et colonne revient à retourner l'image\nautour de sa diagonale, ce qui n'est pas une rotation. Le pixel\n`1` resterait en `[0][0]`.\n"
        },
        {
          "text": "Ligne `n - 1 - i`, colonne `n - 1 - j`",
          "correct": false,
          "feedback": "Erreur : cette formule fait tourner l'image d'un demi-tour. Le\npixel `1`, en haut à gauche, arriverait en bas à droite.\n"
        }
      ],
      "explanation": "Pour tourner l'image sans créer de seconde image, on déplace les\npixels par groupes de quatre, qui s'échangent en cercle d'un\ncoin à l'autre : la mémoire utilisée reste constante. On peut\naussi raisonner par quarts de l'image, en appliquant le même\ntraitement à chacun."
    },
    {
      "id": "q20",
      "difficulty": 2,
      "skills": [
        "diviser",
        "decoupage"
      ],
      "title": "Découpage déséquilibré",
      "partie": "principe",
      "statement": "Que se passe-t-il si le découpage en sous-problèmes est très\n**déséquilibré** (par exemple, une moitié contenant $1$\nélément et l'autre $n-1$ éléments) ?",
      "options": [
        {
          "text": "La complexité reste $O(n)$",
          "correct": false,
          "feedback": "Erreur : un découpage déséquilibré ne réduit pas la\ntaille suffisamment vite pour rester en $O(n)$.\n"
        },
        {
          "text": "La complexité reste en $O(n \\log n)$",
          "correct": false,
          "feedback": "Erreur : la complexité $O(n \\log n)$ suppose un\ndécoupage **équilibré** (en deux moitiés de même taille).\nUn découpage déséquilibré dégrade fortement la\nperformance.\n"
        },
        {
          "text": "La complexité dégénère à $O(n^2)$",
          "correct": true,
          "feedback": "Bonne réponse : avec ce découpage, on a $n$ niveaux de\nrécursion (au lieu de $\\log n$), chacun coûtant $O(n)$.\nLe total devient $O(n^2)$, comme pour un tri par insertion.\n"
        },
        {
          "text": "L'algorithme ne termine pas",
          "correct": false,
          "feedback": "Erreur : tant que le découpage diminue strictement la\ntaille du sous-problème, l'algorithme termine. Le\nproblème est la **performance**, pas la terminaison.\n"
        }
      ],
      "explanation": "C'est pour cette raison qu'un algorithme « diviser pour\nrégner » cherche des sous-problèmes de tailles comparables :\nle tri fusion coupe toujours au milieu, ce qui lui garantit\n$\\log_2 n$ niveaux et un coût en $O(n \\log n)$ dans tous\nles cas."
    },
    {
      "id": "q22",
      "difficulty": 3,
      "skills": [
        "recursivite",
        "pile"
      ],
      "title": "Profondeur de la pile en tri fusion",
      "partie": "principe",
      "statement": "Pour trier un tableau de $1\\ 000$ éléments par tri fusion\nrécursif, quelle est la **profondeur maximale** de la pile\nd'appels ?",
      "options": [
        {
          "text": "$500$",
          "correct": false,
          "feedback": "Erreur : confusion possible avec « la moitié ». La\nprofondeur n'est pas $n/2$ mais bien $\\log n$.\n"
        },
        {
          "text": "$10$",
          "correct": true,
          "feedback": "Bonne réponse : $\\log_2(1\\ 000) \\approx 10$ (environ).\nLa pile d'appels reste donc très peu profonde, ce qui\névite les `RecursionError` même pour de grandes entrées.\n"
        },
        {
          "text": "$1$",
          "correct": false,
          "feedback": "Erreur : un seul appel ne suffit pas à diviser\n$1\\ 000$ éléments jusqu'au cas de base.\n"
        },
        {
          "text": "$1\\ 000$",
          "correct": false,
          "feedback": "Erreur : on ne descend pas $1\\ 000$ niveaux. Le\ndécoupage divise par deux à chaque niveau, donc la\nprofondeur croît comme $\\log n$.\n"
        }
      ],
      "explanation": "C'est une autre force du diviser pour régner avec\ndécoupage équilibré : la profondeur logarithmique évite\ntout problème de débordement de pile, même pour des\nmilliards d'éléments.",
      "variants": [
        {
          "statement": "Pour trier un tableau de $1\\ 000$ éléments par tri fusion\nrécursif, quelle est la **profondeur maximale** de la pile\nd'appels ?",
          "options": [
            {
              "text": "$500$",
              "correct": false,
              "feedback": "Erreur : confusion possible avec « la moitié ». La\nprofondeur n'est pas $n/2$ mais bien $\\log n$.\n"
            },
            {
              "text": "$10$",
              "correct": true,
              "feedback": "Bonne réponse : $\\log_2(1\\ 000) \\approx 10$ (environ).\nLa pile d'appels reste donc très peu profonde, ce qui\névite les `RecursionError` même pour de grandes entrées.\n"
            },
            {
              "text": "$1$",
              "correct": false,
              "feedback": "Erreur : un seul appel ne suffit pas à diviser\n$1\\ 000$ éléments jusqu'au cas de base.\n"
            },
            {
              "text": "$1\\ 000$",
              "correct": false,
              "feedback": "Erreur : on ne descend pas $1\\ 000$ niveaux. Le\ndécoupage divise par deux à chaque niveau, donc la\nprofondeur croît comme $\\log n$.\n"
            }
          ],
          "explanation": "C'est une autre force du diviser pour régner avec\ndécoupage équilibré : la profondeur logarithmique évite\ntout problème de débordement de pile, même pour des\nmilliards d'éléments."
        },
        {
          "statement": "Pour trier un tableau de $1\\ 000\\ 000$ éléments par tri fusion\nrécursif, quelle est la **profondeur maximale** de la pile\nd'appels ?",
          "options": [
            {
              "text": "$500\\ 000$",
              "correct": false,
              "feedback": "Erreur : confusion possible avec « la moitié ». La\nprofondeur n'est pas $n/2$ mais bien $\\log n$.\n"
            },
            {
              "text": "$20$",
              "correct": true,
              "feedback": "Bonne réponse : $\\log_2(1\\ 000\\ 000) \\approx 20$ (environ).\nLa pile d'appels reste donc très peu profonde, ce qui\névite les `RecursionError` même pour de grandes entrées.\n"
            },
            {
              "text": "$1$",
              "correct": false,
              "feedback": "Erreur : un seul appel ne suffit pas à diviser\n$1\\ 000\\ 000$ éléments jusqu'au cas de base.\n"
            },
            {
              "text": "$1\\ 000\\ 000$",
              "correct": false,
              "feedback": "Erreur : on ne descend pas $1\\ 000\\ 000$ niveaux. Le\ndécoupage divise par deux à chaque niveau, donc la\nprofondeur croît comme $\\log n$.\n"
            }
          ],
          "explanation": "C'est une autre force du diviser pour régner avec\ndécoupage équilibré : la profondeur logarithmique évite\ntout problème de débordement de pile, même pour des\nmilliards d'éléments."
        },
        {
          "statement": "Pour trier un tableau de $128$ éléments par tri fusion\nrécursif, quelle est la **profondeur maximale** de la pile\nd'appels ?",
          "options": [
            {
              "text": "$64$",
              "correct": false,
              "feedback": "Erreur : confusion possible avec « la moitié ». La\nprofondeur n'est pas $n/2$ mais bien $\\log n$.\n"
            },
            {
              "text": "$7$",
              "correct": true,
              "feedback": "Bonne réponse : $\\log_2(128) \\approx 7$ (environ).\nLa pile d'appels reste donc très peu profonde, ce qui\névite les `RecursionError` même pour de grandes entrées.\n"
            },
            {
              "text": "$1$",
              "correct": false,
              "feedback": "Erreur : un seul appel ne suffit pas à diviser\n$128$ éléments jusqu'au cas de base.\n"
            },
            {
              "text": "$128$",
              "correct": false,
              "feedback": "Erreur : on ne descend pas $128$ niveaux. Le\ndécoupage divise par deux à chaque niveau, donc la\nprofondeur croît comme $\\log n$.\n"
            }
          ],
          "explanation": "C'est une autre force du diviser pour régner avec\ndécoupage équilibré : la profondeur logarithmique évite\ntout problème de débordement de pile, même pour des\nmilliards d'éléments."
        }
      ]
    },
    {
      "id": "q23",
      "difficulty": 3,
      "skills": [
        "exponentiation",
        "application"
      ],
      "title": "Exponentiation modulaire",
      "partie": "autres",
      "statement": "Pour calculer $a^n \\mod m$ avec de très grands entiers\n(cryptographie), la méthode efficace est :",
      "options": [
        {
          "text": "Appliquer l'exponentiation rapide en réduisant modulo $m$ à chaque étape",
          "correct": true,
          "feedback": "Bonne réponse : $(a \\cdot b) \\mod m = ((a \\mod m) \\cdot (b \\mod m)) \\mod m$,\ndonc on peut réduire à chaque étape sans changer le\nrésultat final. Cela maintient les entiers\nintermédiaires petits ($< m^2$), tout en bénéficiant\nde la complexité $O(\\log n)$.\n"
        },
        {
          "text": "Calculer $a^n$ entièrement, puis prendre le modulo",
          "correct": false,
          "feedback": "Erreur : pour $a = 1024$ et $n = 10^9$, $a^n$ a plus\nd'un milliard de chiffres et n'est pas calculable en\npratique. Il faut prendre le modulo à chaque étape.\n"
        },
        {
          "text": "Utiliser une recherche dichotomique sur les diviseurs de $m$",
          "correct": false,
          "feedback": "Erreur : la recherche dichotomique n'a aucun rapport\navec ce calcul.\n"
        },
        {
          "text": "Utiliser un tri fusion appliqué aux chiffres décimaux du nombre",
          "correct": false,
          "feedback": "Erreur : aucun rapport entre tri et exponentiation\nmodulaire.\n"
        }
      ],
      "explanation": "L'exponentiation modulaire rapide est l'opération\nfondamentale du chiffrement RSA. Elle permet de calculer\n$a^n \\mod m$ pour des entiers de plusieurs milliers de\nbits, en quelques millisecondes."
    },
    {
      "id": "q24",
      "difficulty": 3,
      "skills": [
        "analyse"
      ],
      "title": "Analyse d'un nouvel algorithme DPR",
      "partie": "principe",
      "statement": "On invente un algorithme qui, pour un tableau de $n$\néléments, le découpe en **trois tiers**, traite chaque tiers\nrécursivement, puis fait un travail $O(n)$ pour combiner.\nQuelle est sa complexité ?",
      "options": [
        {
          "text": "$O(n^3)$",
          "correct": false,
          "feedback": "Erreur : on découpe en trois, mais chaque sous-problème\nfait $1/3$ de la taille originale, pas $n/2$. Le\nrésultat reste $O(n \\log n)$.\n"
        },
        {
          "text": "$O(n)$",
          "correct": false,
          "feedback": "Erreur : la combinaison à elle seule est en $O(n)$, mais\nil y a aussi $\\log_3 n$ niveaux à parcourir.\n"
        },
        {
          "text": "$O(3^n)$",
          "correct": false,
          "feedback": "Erreur : la complexité exponentielle apparaît avec des\nappels qui ne réduisent pas la taille. Ici, on divise\nla taille à chaque étape.\n"
        },
        {
          "text": "$O(n \\log_3 n)$",
          "correct": true,
          "feedback": "Bonne réponse : chaque niveau d'appels traite en tout les\n$n$ éléments, donc coûte $O(n)$, et la taille est divisée\npar trois à chaque niveau, ce qui donne environ $\\log_3 n$\nniveaux. Comme $\\log_3 n$ et $\\log_2 n$ ne diffèrent que\nd'un facteur constant, c'est un coût en $O(n \\log n)$.\n"
        }
      ],
      "explanation": "Pour évaluer le coût d'un algorithme « diviser pour\nrégner », on compte le travail de chaque niveau d'appels et\nle nombre de niveaux : ici $O(n)$ par niveau sur environ\n$\\log_3 n$ niveaux. C'est le même raisonnement que pour le\ntri fusion."
    },
    {
      "id": "q25",
      "difficulty": 3,
      "skills": [
        "synthese"
      ],
      "title": "Reconnaître un algorithme DPR",
      "partie": "principe",
      "statement": "Parmi les algorithmes suivants, lequel **n'est pas** un\nalgorithme diviser pour régner ?",
      "options": [
        {
          "text": "Le tri par insertion",
          "correct": true,
          "feedback": "Bonne réponse : le tri par insertion ne divise pas le\nproblème. Il itère sur les éléments et place chacun à\nsa place dans la portion déjà triée. C'est un\nalgorithme **itératif** classique, pas un DPR.\n"
        },
        {
          "text": "L'exponentiation rapide",
          "correct": false,
          "feedback": "Erreur : c'est un DPR. On réduit l'exposant de moitié\nà chaque appel.\n"
        },
        {
          "text": "La recherche dichotomique",
          "correct": false,
          "feedback": "Erreur : c'est aussi un DPR. On divise l'intervalle de\nrecherche par deux à chaque étape.\n"
        },
        {
          "text": "Le tri fusion",
          "correct": false,
          "feedback": "Erreur : c'est un cas d'école du paradigme. On découpe\nen deux moitiés, on trie chaque moitié récursivement,\non fusionne.\n"
        }
      ],
      "explanation": "Pour identifier un DPR, chercher : (1) un découpage en\nsous-problèmes plus petits de même nature, (2) une\nrésolution récursive, (3) une étape de combinaison. Le tri\npar insertion ne fait pas de découpage récursif, donc ce\nn'est pas un DPR."
    },
    {
      "id": "q26",
      "difficulty": 2,
      "skills": [
        "exponentiation-rapide",
        "code"
      ],
      "title": "Code de l'exponentiation rapide",
      "partie": "autres",
      "statement": "Quel code Python implémente correctement\nl'exponentiation rapide récursive de $a$ à la\npuissance $n$ (avec $n \\geq 0$) ?",
      "options": [
        {
          "text": "```python\ndef puissance(a, n):\n    if n == 0:\n        return 1\n    if n % 2 == 0:\n        return puissance(a, n // 2) * puissance(a, n // 2)\n    return a * puissance(a, n // 2) * puissance(a, n // 2)\n```\n",
          "correct": false,
          "feedback": "Erreur : on calcule **deux fois** la même puissance\nau lieu de la stocker dans une variable. La\ncomplexité retombe à $O(n)$, ce qui annule l'avantage\nde l'exponentiation rapide. Bug classique du\ndébutant.\n"
        },
        {
          "text": "```python\ndef puissance(a, n):\n    if n == 0:\n        return 1\n    return a * puissance(a, n - 1)\n```\n",
          "correct": false,
          "feedback": "Erreur : c'est l'exponentiation **naïve**, en\n$O(n)$ multiplications. Elle décrémente l'exposant\nde $1$ à chaque étape au lieu de le diviser par\ndeux. La question demandait l'exponentiation\n**rapide**.\n"
        },
        {
          "text": "```python\ndef puissance(a, n):\n    return a ** n\n```\n",
          "correct": false,
          "feedback": "Erreur : on utilise l'opérateur Python intégré, ce\nqui n'illustre pas le paradigme étudié. La question\nportait sur l'écriture **explicite** de\nl'exponentiation rapide.\n"
        },
        {
          "text": "```python\ndef puissance(a, n):\n    if n == 0:\n        return 1\n    demi = puissance(a, n // 2)\n    if n % 2 == 0:\n        return demi * demi\n    return a * demi * demi\n```\n",
          "correct": true,
          "feedback": "Bonne réponse : on calcule **une seule fois** la\npuissance pour la moitié de l'exposant, puis on\nmultiplie ce résultat par lui-même (et par `a`\nsupplémentaire si `n` est impair). Complexité\n$O(\\log n)$ multiplications.\n"
        }
      ],
      "explanation": "Idée centrale : sauvegarder le résultat de\n`puissance(a, n // 2)` dans une variable. Sans cette\nmémorisation, l'algorithme dégénère en\nexponentiation naïve. C'est l'illustration la plus\nsimple du diviser pour régner sur un seul\nsous-problème."
    },
    {
      "id": "q27",
      "difficulty": 2,
      "skills": [
        "diviser-pour-regner",
        "recursivite"
      ],
      "title": "Somme d'un tableau par diviser pour régner",
      "partie": "principe",
      "statement": "On veut calculer la somme des éléments de `t` compris entre les\nindices `debut` et `fin` inclus, en coupant l'intervalle en deux :\n\n```python\ndef somme(t, debut, fin):\n    if debut == fin:\n        return t[debut]\n    milieu = (debut + fin) // 2\n    return ...\n```\n\nPar quoi remplacer les points de suspension pour que\n`somme([4, 7, 1, 3], 0, 3)` renvoie `15` ?",
      "options": [
        {
          "text": "`somme(t, debut, milieu) + somme(t, milieu, fin)`",
          "correct": false,
          "feedback": "Erreur : les deux moitiés partagent la case `milieu`. Pour\n`somme(t, 0, 1)`, `milieu` vaut `0` et le second appel est de\nnouveau `somme(t, 0, 1)` : la récursion ne s'arrête pas et Python\nlève une `RecursionError`.\n"
        },
        {
          "text": "`somme(t, debut, milieu) + somme(t, milieu + 1, fin)`",
          "correct": true,
          "feedback": "Bonne réponse : les deux moitiés, de `debut` à `milieu` et de\n`milieu + 1` à `fin`, couvrent chaque case une seule fois et sont\nstrictement plus petites. On obtient $4 + 7 + 1 + 3 = 15$.\n"
        },
        {
          "text": "`t[milieu] + somme(t, milieu + 1, fin)`",
          "correct": false,
          "feedback": "Erreur : les cases situées avant `milieu` ne sont jamais\nadditionnées. L'appel renvoie `11`, soit $7 + 1 + 3$ : la valeur\n`4` est perdue.\n"
        },
        {
          "text": "`somme(t, debut, milieu) + somme(t, milieu + 1, fin) + t[milieu]`",
          "correct": false,
          "feedback": "Erreur : la case `milieu` est déjà comptée dans la moitié\ngauche. Elle est ajoutée une seconde fois à chaque découpage, et\nl'appel renvoie `27`.\n"
        }
      ],
      "explanation": "Un découpage correct répartit les cases en deux intervalles\ndisjoints qui les couvrent toutes, chacun strictement plus petit\nque l'intervalle de départ : la récursion atteint alors toujours\nle cas de base `debut == fin`."
    },
    {
      "id": "q28",
      "difficulty": 3,
      "skills": [
        "theoreme-maitre",
        "application"
      ],
      "title": "DPR sans combinaison coûteuse",
      "partie": "principe",
      "statement": "La recherche dichotomique satisfait la récurrence\n$T(n) = T(n/2) + O(1)$. Pourquoi obtient-on\n$O(\\log n)$ et non $O(n \\log n)$ comme dans le tri\nfusion ?",
      "options": [
        {
          "text": "Parce qu'il n'y a qu'un seul sous-problème par\nappel et que la combinaison est en temps constant\n",
          "correct": true,
          "feedback": "Bonne réponse : la dichotomie ne fait qu'**un seul**\nappel récursif (sur la moitié pertinente, au lieu\nde deux) et la combinaison se résume à un test\nd'égalité ou de comparaison, en $O(1)$ au lieu de\n$O(n)$. On compte environ $\\log_2 n$ appels de coût\nconstant, d'où $O(\\log n)$. Au tri fusion, on a deux\nappels et une fusion en $O(n)$, ce qui donne\n$O(n \\log n)$.\n"
        },
        {
          "text": "Parce que la recherche dichotomique ne relève pas\ndu paradigme diviser pour régner\n",
          "correct": false,
          "feedback": "Erreur : elle relève bien du paradigme. Elle\ndivise l'espace de recherche par deux à chaque\nappel, illustration classique du DPR.\n"
        },
        {
          "text": "Parce que la recherche dichotomique fonctionne\nuniquement sur des tableaux de taille puissance de\ndeux\n",
          "correct": false,
          "feedback": "Erreur : la recherche dichotomique fonctionne pour\ntoute taille. Cette propriété n'a aucun rapport\navec sa complexité.\n"
        },
        {
          "text": "Parce que les comparaisons entre éléments sont\ngratuites en Python et ne comptent pas dans la\ncomplexité\n",
          "correct": false,
          "feedback": "Erreur : les comparaisons coûtent du temps comme\ntoute opération et comptent bien dans la\ncomplexité. Mais elles sont en nombre constant à\nchaque appel récursif, ce qui fait la différence\navec une fusion en $O(n)$.\n"
        }
      ],
      "explanation": "Chaque appel de la dichotomie fait un nombre constant\nd'opérations, et la taille de l'intervalle est\ndivisée par deux à chaque appel : il y a donc environ\n$\\log_2 n$ appels. Le tri fusion, lui, traite les deux\nmoitiés et fusionne en $O(n)$ : chacun de ses\n$\\log_2 n$ niveaux coûte $O(n)$."
    },
    {
      "id": "q29",
      "difficulty": 3,
      "skills": [
        "trace-tri-fusion"
      ],
      "title": "Trace du tri fusion",
      "partie": "tri-fusion",
      "statement": "On applique le tri fusion à la liste\n`[5, 2, 8, 3]`. Quelles sont les listes\npassées à la fusion finale (la dernière\nétape, qui produit la liste triée\ncomplète) ?",
      "options": [
        {
          "text": "`[2, 3, 5, 8]` et `[]`\n",
          "correct": false,
          "feedback": "Erreur : la fusion combine deux\nmoitiés non vides. Une moitié vide\nsignifierait qu'on a fait un seul tri\nrécursif suivi d'une fusion sans\ncontrepartie, ce qui n'est pas le\ntri fusion.\n"
        },
        {
          "text": "`[5]`, `[2]`, `[8]`, `[3]`\n",
          "correct": false,
          "feedback": "Erreur : ce sont les listes singletons\nobtenues à la fin du découpage. La\nfusion finale ne combine que **deux**\nlistes, pas quatre. Quatre singletons\nimpliqueraient deux fusions\nintermédiaires avant la fusion finale.\n"
        },
        {
          "text": "`[5, 2]` et `[8, 3]`\n",
          "correct": false,
          "feedback": "Erreur : ce sont les deux moitiés\nobtenues après le **premier** découpage,\nmais avant les tris récursifs. À la\nfusion finale, ces moitiés ont déjà\nété triées et sont devenues `[2, 5]`\net `[3, 8]`.\n"
        },
        {
          "text": "`[2, 5]` et `[3, 8]`\n",
          "correct": true,
          "feedback": "Bonne réponse : on découpe d'abord en\n`[5, 2]` et `[8, 3]`. On trie\nrécursivement chaque moitié : `[5, 2]`\ndevient `[2, 5]` après fusion de `[5]`\net `[2]` ; `[8, 3]` devient `[3, 8]`\naprès fusion de `[8]` et `[3]`. La\nfusion finale combine `[2, 5]` et\n`[3, 8]` pour produire `[2, 3, 5, 8]`.\n"
        }
      ],
      "explanation": "Schéma global du tri fusion : une phase\ndescendante de découpage récursif (jusqu'aux\nsingletons), suivie d'une phase remontante\nde fusions successives. Pour $n = 4$, la\nstructure d'appels forme un arbre binaire\ncomplet de hauteur $\\log_2 4 = 2$. À chaque\nniveau, le coût total des fusions est en\n$O(n)$, d'où la complexité globale en\n$O(n \\log n)$.",
      "variants": [
        {
          "statement": "On applique le tri fusion à la liste\n`[5, 2, 8, 3]`. Quelles sont les listes\npassées à la fusion finale (la dernière\nétape, qui produit la liste triée\ncomplète) ?",
          "options": [
            {
              "text": "`[2, 3, 5, 8]` et `[]`\n",
              "correct": false,
              "feedback": "Erreur : la fusion combine deux\nmoitiés non vides. Une moitié vide\nsignifierait qu'on a fait un seul tri\nrécursif suivi d'une fusion sans\ncontrepartie, ce qui n'est pas le\ntri fusion.\n"
            },
            {
              "text": "`[5]`, `[2]`, `[8]`, `[3]`\n",
              "correct": false,
              "feedback": "Erreur : ce sont les listes singletons\nobtenues à la fin du découpage. La\nfusion finale ne combine que **deux**\nlistes, pas quatre. Quatre singletons\nimpliqueraient deux fusions\nintermédiaires avant la fusion finale.\n"
            },
            {
              "text": "`[5, 2]` et `[8, 3]`\n",
              "correct": false,
              "feedback": "Erreur : ce sont les deux moitiés\nobtenues après le **premier** découpage,\nmais avant les tris récursifs. À la\nfusion finale, ces moitiés ont déjà\nété triées et sont devenues `[2, 5]`\net `[3, 8]`.\n"
            },
            {
              "text": "`[2, 5]` et `[3, 8]`\n",
              "correct": true,
              "feedback": "Bonne réponse : on découpe d'abord en\n`[5, 2]` et `[8, 3]`. On trie\nrécursivement chaque moitié : `[5, 2]`\ndevient `[2, 5]` après fusion de `[5]`\net `[2]` ; `[8, 3]` devient `[3, 8]`\naprès fusion de `[8]` et `[3]`. La\nfusion finale combine `[2, 5]` et\n`[3, 8]` pour produire `[2, 3, 5, 8]`.\n"
            }
          ],
          "explanation": "Schéma global du tri fusion : une phase\ndescendante de découpage récursif (jusqu'aux\nsingletons), suivie d'une phase remontante\nde fusions successives. Pour $n = 4$, la\nstructure d'appels forme un arbre binaire\ncomplet de hauteur $\\log_2 4 = 2$. À chaque\nniveau, le coût total des fusions est en\n$O(n)$, d'où la complexité globale en\n$O(n \\log n)$."
        },
        {
          "statement": "On applique le tri fusion à la liste\n`[7, 1, 6, 4]`. Quelles sont les listes\npassées à la fusion finale (la dernière\nétape, qui produit la liste triée\ncomplète) ?",
          "options": [
            {
              "text": "`[1, 4, 6, 7]` et `[]`\n",
              "correct": false,
              "feedback": "Erreur : la fusion combine deux\nmoitiés non vides. Une moitié vide\nsignifierait qu'on a fait un seul tri\nrécursif suivi d'une fusion sans\ncontrepartie, ce qui n'est pas le\ntri fusion.\n"
            },
            {
              "text": "`[7]`, `[1]`, `[6]`, `[4]`\n",
              "correct": false,
              "feedback": "Erreur : ce sont les listes singletons\nobtenues à la fin du découpage. La\nfusion finale ne combine que **deux**\nlistes, pas quatre. Quatre singletons\nimpliqueraient deux fusions\nintermédiaires avant la fusion finale.\n"
            },
            {
              "text": "`[7, 1]` et `[6, 4]`\n",
              "correct": false,
              "feedback": "Erreur : ce sont les deux moitiés\nobtenues après le **premier** découpage,\nmais avant les tris récursifs. À la\nfusion finale, ces moitiés ont déjà\nété triées et sont devenues `[1, 7]`\net `[4, 6]`.\n"
            },
            {
              "text": "`[1, 7]` et `[4, 6]`\n",
              "correct": true,
              "feedback": "Bonne réponse : on découpe d'abord en\n`[7, 1]` et `[6, 4]`. On trie\nrécursivement chaque moitié : `[7, 1]`\ndevient `[1, 7]` après fusion de `[7]`\net `[1]` ; `[6, 4]` devient `[4, 6]`\naprès fusion de `[6]` et `[4]`. La\nfusion finale combine `[1, 7]` et\n`[4, 6]` pour produire `[1, 4, 6, 7]`.\n"
            }
          ],
          "explanation": "Schéma global du tri fusion : une phase\ndescendante de découpage récursif (jusqu'aux\nsingletons), suivie d'une phase remontante\nde fusions successives. Pour $n = 4$, la\nstructure d'appels forme un arbre binaire\ncomplet de hauteur $\\log_2 4 = 2$. À chaque\nniveau, le coût total des fusions est en\n$O(n)$, d'où la complexité globale en\n$O(n \\log n)$."
        },
        {
          "statement": "On applique le tri fusion à la liste\n`[9, 3, 2, 8]`. Quelles sont les listes\npassées à la fusion finale (la dernière\nétape, qui produit la liste triée\ncomplète) ?",
          "options": [
            {
              "text": "`[2, 3, 8, 9]` et `[]`\n",
              "correct": false,
              "feedback": "Erreur : la fusion combine deux\nmoitiés non vides. Une moitié vide\nsignifierait qu'on a fait un seul tri\nrécursif suivi d'une fusion sans\ncontrepartie, ce qui n'est pas le\ntri fusion.\n"
            },
            {
              "text": "`[9]`, `[3]`, `[2]`, `[8]`\n",
              "correct": false,
              "feedback": "Erreur : ce sont les listes singletons\nobtenues à la fin du découpage. La\nfusion finale ne combine que **deux**\nlistes, pas quatre. Quatre singletons\nimpliqueraient deux fusions\nintermédiaires avant la fusion finale.\n"
            },
            {
              "text": "`[9, 3]` et `[2, 8]`\n",
              "correct": false,
              "feedback": "Erreur : ce sont les deux moitiés\nobtenues après le **premier** découpage,\nmais avant les tris récursifs. À la\nfusion finale, ces moitiés ont déjà\nété triées et sont devenues `[3, 9]`\net `[2, 8]`.\n"
            },
            {
              "text": "`[3, 9]` et `[2, 8]`\n",
              "correct": true,
              "feedback": "Bonne réponse : on découpe d'abord en\n`[9, 3]` et `[2, 8]`. On trie\nrécursivement chaque moitié : `[9, 3]`\ndevient `[3, 9]` après fusion de `[9]`\net `[3]` ; `[2, 8]` devient `[2, 8]`\naprès fusion de `[2]` et `[8]`. La\nfusion finale combine `[3, 9]` et\n`[2, 8]` pour produire `[2, 3, 8, 9]`.\n"
            }
          ],
          "explanation": "Schéma global du tri fusion : une phase\ndescendante de découpage récursif (jusqu'aux\nsingletons), suivie d'une phase remontante\nde fusions successives. Pour $n = 4$, la\nstructure d'appels forme un arbre binaire\ncomplet de hauteur $\\log_2 4 = 2$. À chaque\nniveau, le coût total des fusions est en\n$O(n)$, d'où la complexité globale en\n$O(n \\log n)$."
        }
      ]
    },
    {
      "id": "q30",
      "difficulty": 3,
      "skills": [
        "code-fusion"
      ],
      "title": "Code de la fonction de fusion",
      "partie": "tri-fusion",
      "statement": "Quelle fonction Python implémente\ncorrectement la **fusion** de deux listes\ndéjà triées en une seule liste triée, en\ntirant parti du tri préalable (temps\nlinéaire, sans retrier) ?",
      "options": [
        {
          "text": "```python\ndef fusion(a, b):\n    i, j = 0, 0\n    resultat = []\n    while i < len(a) and j < len(b):\n        if a[i] <= b[j]:\n            resultat.append(a[i])\n            i += 1\n        else:\n            resultat.append(b[j])\n            j += 1\n    return resultat\n```\n",
          "correct": false,
          "feedback": "Erreur : la boucle s'arrête dès que\nl'une des deux listes est épuisée, et\nles éléments restants de l'autre liste\nsont perdus. Avec `a = [1, 4, 7]` et\n`b = [2, 3]`, on obtient `[1, 2, 3]`\nau lieu de `[1, 2, 3, 4, 7]`. Il faut\nrecopier la fin de la liste non\népuisée après la boucle.\n"
        },
        {
          "text": "```python\ndef fusion(a, b):\n    return sorted(a + b)\n```\n",
          "correct": false,
          "feedback": "Cette version fonctionne mais\nn'illustre pas l'algorithme : on délègue\nau tri intégré, qui ne tire pas parti\ndu fait que `a` et `b` sont déjà\ntriées. Complexité : $O((n+m) \\log(n+m))$\nau lieu de $O(n + m)$.\n"
        },
        {
          "text": "```python\ndef fusion(a, b):\n    resultat = []\n    for x in a:\n        for y in b:\n            if x <= y:\n                resultat.append(x)\n            else:\n                resultat.append(y)\n    return resultat\n```\n",
          "correct": false,
          "feedback": "Erreur : la double boucle imbriquée a\nune complexité $O(n \\cdot m)$ au lieu\nde $O(n + m)$. De plus, on ajoute des\néléments en double (chaque élément de\n`a` est comparé à chaque élément de\n`b`, et chaque comparaison ajoute une\nvaleur). Le résultat n'est ni trié, ni\nde la bonne taille.\n"
        },
        {
          "text": "```python\ndef fusion(a, b):\n    i, j = 0, 0\n    resultat = []\n    while i < len(a) and j < len(b):\n        if a[i] <= b[j]:\n            resultat.append(a[i])\n            i += 1\n        else:\n            resultat.append(b[j])\n            j += 1\n    resultat.extend(a[i:])\n    resultat.extend(b[j:])\n    return resultat\n```\n",
          "correct": true,
          "feedback": "Bonne réponse : on utilise deux indices\n`i` et `j` pour parcourir les deux\nlistes en parallèle. À chaque tour, on\najoute le plus petit des deux éléments\nde tête, et on avance l'indice\ncorrespondant. Quand l'une des listes\nest épuisée, on copie simplement le\nreste de l'autre. Complexité : $O(n + m)$\noù $n$ et $m$ sont les longueurs des\ndeux listes.\n"
        }
      ],
      "explanation": "Cette fonction est le cœur du tri fusion :\nla qualité de l'algorithme global vient\nde l'efficacité linéaire de la fusion.\nVariante intéressante : implémenter la\nfusion **en place** dans la liste\nd'origine, ce qui économise de la\nmémoire. C'est cependant plus délicat à\ncoder et n'apporte pas de gain en\ncomplexité asymptotique."
    },
    {
      "id": "q31",
      "difficulty": 3,
      "skills": [
        "tri-fusion",
        "recursivite",
        "code"
      ],
      "title": "Ligne récursive du tri fusion",
      "partie": "tri-fusion",
      "statement": "On dispose d'une fonction `fusion(a, b)` qui fusionne deux listes\ntriées en une liste triée. On complète le tri fusion suivant :\n\n```python\ndef tri_fusion(t):\n    if len(t) <= 1:\n        return t\n    milieu = len(t) // 2\n    gauche = [t[i] for i in range(milieu)]\n    droite = [t[i] for i in range(milieu, len(t))]\n    return ...\n```\n\nQuelle expression remplace les points de suspension pour que la\nfonction trie toute liste ?",
      "options": [
        {
          "text": "`fusion(gauche, droite)`",
          "correct": false,
          "feedback": "Erreur : `fusion` suppose deux listes déjà triées, or `gauche` et\n`droite` ne le sont pas. Sur `[4, 1, 3, 2]`, la fonction renvoie\n`[3, 2, 4, 1]`.\n"
        },
        {
          "text": "`tri_fusion(gauche) + tri_fusion(droite)`",
          "correct": false,
          "feedback": "Erreur : l'opérateur `+` met les deux listes bout à bout sans\nles fusionner. À aucun niveau les valeurs ne sont comparées :\n`[4, 1, 3, 2]` est renvoyée inchangée.\n"
        },
        {
          "text": "`tri_fusion(fusion(gauche, droite))`",
          "correct": false,
          "feedback": "Erreur : la liste passée à l'appel récursif a la même longueur\nque `t`. Le problème ne rétrécit jamais, et Python finit par lever\nune `RecursionError`.\n"
        },
        {
          "text": "`fusion(tri_fusion(gauche), tri_fusion(droite))`",
          "correct": true,
          "feedback": "Bonne réponse : chaque moitié est d'abord triée par un appel\nrécursif sur une liste plus courte, puis les deux moitiés triées\nsont fusionnées. `[4, 1, 3, 2]` donne `[1, 2, 3, 4]`.\n"
        }
      ],
      "explanation": "Le tri fusion suit les trois étapes de la méthode : diviser la\nliste en deux moitiés, résoudre chaque moitié par un appel\nrécursif, puis combiner les deux résultats par une fusion. Les\nappels portent sur des listes strictement plus courtes, ce qui\ngarantit d'atteindre le cas de base."
    },
    {
      "id": "q32",
      "difficulty": 2,
      "skills": [
        "rotation-image",
        "diviser-pour-regner",
        "principe"
      ],
      "title": "Tourner une image par diviser pour régner",
      "partie": "principe",
      "statement": "Une image carrée de $n \\times n$ pixels, $n$\npuissance de $2$, doit être tournée d'un quart de\ntour. Comment procède la méthode diviser pour\nrégner ?",
      "options": [
        {
          "text": "Découper en quatre quadrants, tourner chacun récursivement, puis permuter les quadrants",
          "correct": true,
          "feedback": "Chaque quadrant tourné prend la place de son\nvoisin dans le sens de la rotation ; une image\nd'un pixel est le cas de base.\n"
        },
        {
          "text": "Tourner les pixels un par un, de la première ligne à la dernière, sans découpage",
          "correct": false,
          "feedback": "C'est une méthode directe par double boucle ;\nelle n'exploite ni découpage ni récursivité.\n"
        },
        {
          "text": "Découper l'image en deux moitiés, les échanger, puis recommencer sur chaque moitié",
          "correct": false,
          "feedback": "Échanger deux moitiés ne produit pas une rotation\nd'un quart de tour ; il faut quatre quadrants.\n"
        },
        {
          "text": "Trier les lignes de l'image par leur luminosité avant de les réécrire en colonnes",
          "correct": false,
          "feedback": "Un tri change le contenu de l'image ; une\nrotation ne fait que déplacer les pixels.\n"
        }
      ],
      "explanation": "Diviser : quatre sous-images de côté $n/2$. Régner :\nchacune est tournée par le même procédé. Combiner :\nle quadrant haut-gauche va en haut à droite, le\nhaut-droit en bas à droite, et ainsi de suite. Le\nprogramme cite cet exemple pour son coût en mémoire\nconstant."
    },
    {
      "id": "q33",
      "difficulty": 3,
      "skills": [
        "rotation-image",
        "cout-memoire",
        "en-place"
      ],
      "title": "Une rotation sans image supplémentaire",
      "partie": "principe",
      "statement": "Le programme de terminale présente la rotation d'une\nimage d'un quart de tour comme un exemple de diviser\npour régner « avec un coût en mémoire constant ».\nQu'est-ce que cela signifie ?",
      "options": [
        {
          "text": "Les pixels sont déplacés sur place, par échanges, sans construire une seconde image",
          "correct": true,
          "feedback": "Permuter quatre quadrants revient à échanger des\npixels quatre par quatre ; seul un pixel\ntemporaire est nécessaire.\n"
        },
        {
          "text": "L'image tournée occupe moins de mémoire que l'image de départ",
          "correct": false,
          "feedback": "Une rotation conserve le nombre de pixels ; la\ntaille ne change pas.\n"
        },
        {
          "text": "La rotation ne nécessite aucune mémoire, les pixels étant lus sans être écrits",
          "correct": false,
          "feedback": "Les pixels changent de place : ils sont bien\nréécrits, mais dans le tableau d'origine.\n"
        },
        {
          "text": "La récursivité est remplacée par une boucle pour économiser la pile d'appels",
          "correct": false,
          "feedback": "La méthode reste récursive ; le coût évoqué\nconcerne l'espace de travail : aucune copie de\nl'image.\n"
        }
      ],
      "explanation": "Une solution naïve crée une seconde image\n$n \\times n$ et y recopie chaque pixel à sa nouvelle\nposition : mémoire doublée. La version diviser pour\nrégner permute les quadrants dans le tableau\nd'origine, avec un seul pixel de secours pour les\néchanges : le coût mémoire ne dépend pas de $n$."
    },
    {
      "id": "q34",
      "difficulty": 2,
      "skills": [
        "exponentiation-rapide",
        "cout",
        "calcul"
      ],
      "title": "Le nombre de multiplications de l'exponentiation rapide",
      "partie": "autres",
      "statement": "Pour calculer $x^{16}$ par élévations au carré successives, de $x$\nà $x^2$, $x^4$, et ainsi de suite, combien de multiplications\nsont nécessaires ?",
      "options": [
        {
          "text": "$4$",
          "correct": true,
          "feedback": "Bonne réponse : $16 = 2^{4}$, et chaque élévation au carré\ndouble l'exposant : $4$ multiplications au lieu de $15$.\n"
        },
        {
          "text": "$15$",
          "correct": false,
          "feedback": "Erreur : $15$ est le coût de la méthode naïve, qui multiplie\npar $x$ à chaque étape.\n"
        },
        {
          "text": "$8$",
          "correct": false,
          "feedback": "Erreur : diviser l'exposant par deux une seule fois ne suffit\npas ; on recommence jusqu'à $1$.\n"
        },
        {
          "text": "$1$",
          "correct": false,
          "feedback": "Erreur : une seule multiplication donne $x^2$, pas $x^{16}$.\n"
        }
      ],
      "explanation": "L'exponentiation rapide est un diviser pour régner : $x^n$ se\ndéduit de $x^{n/2}$ par une seule multiplication, d'où un coût\nlogarithmique.",
      "variants": [
        {
          "statement": "Pour calculer $x^{16}$ par élévations au carré successives, de $x$\nà $x^2$, $x^4$, et ainsi de suite, combien de multiplications\nsont nécessaires ?",
          "options": [
            {
              "text": "$4$",
              "correct": true,
              "feedback": "Bonne réponse : $16 = 2^{4}$, et chaque élévation au carré\ndouble l'exposant : $4$ multiplications au lieu de $15$.\n"
            },
            {
              "text": "$15$",
              "correct": false,
              "feedback": "Erreur : $15$ est le coût de la méthode naïve, qui multiplie\npar $x$ à chaque étape.\n"
            },
            {
              "text": "$8$",
              "correct": false,
              "feedback": "Erreur : diviser l'exposant par deux une seule fois ne suffit\npas ; on recommence jusqu'à $1$.\n"
            },
            {
              "text": "$1$",
              "correct": false,
              "feedback": "Erreur : une seule multiplication donne $x^2$, pas $x^{16}$.\n"
            }
          ],
          "explanation": "L'exponentiation rapide est un diviser pour régner : $x^n$ se\ndéduit de $x^{n/2}$ par une seule multiplication, d'où un coût\nlogarithmique."
        },
        {
          "statement": "Pour calculer $x^{8}$ par élévations au carré successives, de $x$\nà $x^2$, $x^4$, et ainsi de suite, combien de multiplications\nsont nécessaires ?",
          "options": [
            {
              "text": "$3$",
              "correct": true,
              "feedback": "Bonne réponse : $8 = 2^{3}$, et chaque élévation au carré\ndouble l'exposant : $3$ multiplications au lieu de $7$.\n"
            },
            {
              "text": "$7$",
              "correct": false,
              "feedback": "Erreur : $7$ est le coût de la méthode naïve, qui multiplie\npar $x$ à chaque étape.\n"
            },
            {
              "text": "$4$",
              "correct": false,
              "feedback": "Erreur : diviser l'exposant par deux une seule fois ne suffit\npas ; on recommence jusqu'à $1$.\n"
            },
            {
              "text": "$1$",
              "correct": false,
              "feedback": "Erreur : une seule multiplication donne $x^2$, pas $x^{8}$.\n"
            }
          ],
          "explanation": "L'exponentiation rapide est un diviser pour régner : $x^n$ se\ndéduit de $x^{n/2}$ par une seule multiplication, d'où un coût\nlogarithmique."
        },
        {
          "statement": "Pour calculer $x^{32}$ par élévations au carré successives, de $x$\nà $x^2$, $x^4$, et ainsi de suite, combien de multiplications\nsont nécessaires ?",
          "options": [
            {
              "text": "$5$",
              "correct": true,
              "feedback": "Bonne réponse : $32 = 2^{5}$, et chaque élévation au carré\ndouble l'exposant : $5$ multiplications au lieu de $31$.\n"
            },
            {
              "text": "$31$",
              "correct": false,
              "feedback": "Erreur : $31$ est le coût de la méthode naïve, qui multiplie\npar $x$ à chaque étape.\n"
            },
            {
              "text": "$16$",
              "correct": false,
              "feedback": "Erreur : diviser l'exposant par deux une seule fois ne suffit\npas ; on recommence jusqu'à $1$.\n"
            },
            {
              "text": "$1$",
              "correct": false,
              "feedback": "Erreur : une seule multiplication donne $x^2$, pas $x^{32}$.\n"
            }
          ],
          "explanation": "L'exponentiation rapide est un diviser pour régner : $x^n$ se\ndéduit de $x^{n/2}$ par une seule multiplication, d'où un coût\nlogarithmique."
        }
      ]
    },
    {
      "id": "q35",
      "difficulty": 3,
      "skills": [
        "dichotomie",
        "recursif",
        "code"
      ],
      "title": "L'appel récursif de la dichotomie",
      "partie": "autres",
      "statement": "Dans cette recherche dichotomique récursive, quelle ligne doit\nremplacer le commentaire ?\n```python\ndef rech(t, x, g, d):\n    if g > d:\n        return False\n    m = (g + d) // 2\n    if t[m] == x:\n        return True\n    if t[m] < x:\n        # ligne à compléter\n    return rech(t, x, g, m - 1)\n```",
      "options": [
        {
          "text": "`return rech(t, x, m + 1, d)`",
          "correct": true,
          "feedback": "Bonne réponse : si `t[m]` est trop petit, `x` ne peut être qu'à\ndroite de `m`, dans l'intervalle de `m + 1` à `d`.\n"
        },
        {
          "text": "`return rech(t, x, g, m - 1)`",
          "correct": false,
          "feedback": "Erreur : c'est l'appel de l'autre cas, quand `t[m]` est trop\ngrand.\n"
        },
        {
          "text": "`return rech(t, x, m, d)`",
          "correct": false,
          "feedback": "Erreur : garder `m` dans l'intervalle peut empêcher la\nrécursion de progresser quand `m` vaut `g`.\n"
        },
        {
          "text": "`return rech(t, x, g, d)`",
          "correct": false,
          "feedback": "Erreur : l'intervalle ne change pas, la récursion ne\ntermine jamais.\n"
        }
      ],
      "explanation": "La version récursive de la dichotomie fait un seul appel, sur la\nmoitié qui peut contenir `x` : c'est un diviser pour régner sans\nétape de combinaison."
    },
    {
      "id": "q36",
      "difficulty": 2,
      "skills": [
        "fusion",
        "comparaisons",
        "trace"
      ],
      "title": "Les comparaisons d'une fusion",
      "partie": "tri-fusion",
      "statement": "La fusion de deux listes triées compare leurs premiers éléments\nrestants et prend le plus petit, jusqu'à épuisement d'une des deux\nlistes ; le reste de l'autre est recopié sans comparaison. Combien\nde comparaisons demande la fusion de `[1, 4, 9]` et `[2, 3, 10]` ?",
      "options": [
        {
          "text": "$5$",
          "correct": true,
          "feedback": "Bonne réponse : une comparaison par élément placé tant que les\ndeux listes sont non vides ; dès que l'une est vide, les\néléments restants sont recopiés sans comparer.\n"
        },
        {
          "text": "$6$",
          "correct": false,
          "feedback": "Erreur : $6$ est le nombre total d'éléments ; les derniers\nsont recopiés sans comparaison.\n"
        },
        {
          "text": "$4$",
          "correct": false,
          "feedback": "Erreur : recompte les comparaisons une par une, jusqu'à ce\nqu'une liste soit vide.\n"
        },
        {
          "text": "$9$",
          "correct": false,
          "feedback": "Erreur : chaque élément n'est comparé qu'au premier de l'autre\nliste, pas à tous.\n"
        }
      ],
      "explanation": "Une fusion coûte au plus $n + m - 1$ comparaisons pour deux listes\nde tailles $n$ et $m$ : c'est ce coût linéaire qui donne au tri\nfusion sa complexité en $n \\log n$.",
      "variants": [
        {
          "statement": "La fusion de deux listes triées compare leurs premiers éléments\nrestants et prend le plus petit, jusqu'à épuisement d'une des deux\nlistes ; le reste de l'autre est recopié sans comparaison. Combien\nde comparaisons demande la fusion de `[1, 4, 9]` et `[2, 3, 10]` ?",
          "options": [
            {
              "text": "$5$",
              "correct": true,
              "feedback": "Bonne réponse : une comparaison par élément placé tant que les\ndeux listes sont non vides ; dès que l'une est vide, les\néléments restants sont recopiés sans comparer.\n"
            },
            {
              "text": "$6$",
              "correct": false,
              "feedback": "Erreur : $6$ est le nombre total d'éléments ; les derniers\nsont recopiés sans comparaison.\n"
            },
            {
              "text": "$4$",
              "correct": false,
              "feedback": "Erreur : recompte les comparaisons une par une, jusqu'à ce\nqu'une liste soit vide.\n"
            },
            {
              "text": "$9$",
              "correct": false,
              "feedback": "Erreur : chaque élément n'est comparé qu'au premier de l'autre\nliste, pas à tous.\n"
            }
          ],
          "explanation": "Une fusion coûte au plus $n + m - 1$ comparaisons pour deux listes\nde tailles $n$ et $m$ : c'est ce coût linéaire qui donne au tri\nfusion sa complexité en $n \\log n$."
        },
        {
          "statement": "La fusion de deux listes triées compare leurs premiers éléments\nrestants et prend le plus petit, jusqu'à épuisement d'une des deux\nlistes ; le reste de l'autre est recopié sans comparaison. Combien\nde comparaisons demande la fusion de `[1, 2, 3]` et `[4, 5, 6]` ?",
          "options": [
            {
              "text": "$3$",
              "correct": true,
              "feedback": "Bonne réponse : une comparaison par élément placé tant que les\ndeux listes sont non vides ; dès que l'une est vide, les\néléments restants sont recopiés sans comparer.\n"
            },
            {
              "text": "$6$",
              "correct": false,
              "feedback": "Erreur : $6$ est le nombre total d'éléments ; les derniers\nsont recopiés sans comparaison.\n"
            },
            {
              "text": "$2$",
              "correct": false,
              "feedback": "Erreur : recompte les comparaisons une par une, jusqu'à ce\nqu'une liste soit vide.\n"
            },
            {
              "text": "$9$",
              "correct": false,
              "feedback": "Erreur : chaque élément n'est comparé qu'au premier de l'autre\nliste, pas à tous.\n"
            }
          ],
          "explanation": "Une fusion coûte au plus $n + m - 1$ comparaisons pour deux listes\nde tailles $n$ et $m$ : c'est ce coût linéaire qui donne au tri\nfusion sa complexité en $n \\log n$."
        },
        {
          "statement": "La fusion de deux listes triées compare leurs premiers éléments\nrestants et prend le plus petit, jusqu'à épuisement d'une des deux\nlistes ; le reste de l'autre est recopié sans comparaison. Combien\nde comparaisons demande la fusion de `[5, 6]` et `[1, 2, 3, 4]` ?",
          "options": [
            {
              "text": "$4$",
              "correct": true,
              "feedback": "Bonne réponse : une comparaison par élément placé tant que les\ndeux listes sont non vides ; dès que l'une est vide, les\néléments restants sont recopiés sans comparer.\n"
            },
            {
              "text": "$6$",
              "correct": false,
              "feedback": "Erreur : $6$ est le nombre total d'éléments ; les derniers\nsont recopiés sans comparaison.\n"
            },
            {
              "text": "$3$",
              "correct": false,
              "feedback": "Erreur : recompte les comparaisons une par une, jusqu'à ce\nqu'une liste soit vide.\n"
            },
            {
              "text": "$9$",
              "correct": false,
              "feedback": "Erreur : chaque élément n'est comparé qu'au premier de l'autre\nliste, pas à tous.\n"
            }
          ],
          "explanation": "Une fusion coûte au plus $n + m - 1$ comparaisons pour deux listes\nde tailles $n$ et $m$ : c'est ce coût linéaire qui donne au tri\nfusion sa complexité en $n \\log n$."
        }
      ]
    },
    {
      "id": "q37",
      "difficulty": 3,
      "skills": [
        "tri-fusion",
        "cout",
        "meilleur-cas"
      ],
      "title": "Le tri fusion sur une liste déjà triée",
      "partie": "tri-fusion",
      "statement": "Que vaut le coût du tri fusion sur une liste de $n$ éléments déjà\ntriée ?",
      "options": [
        {
          "text": "De l'ordre de $n \\log n$, comme pour toute liste",
          "correct": true,
          "feedback": "Bonne réponse : le tri fusion ne regarde pas si la liste est\ntriée. Il découpe jusqu'aux listes d'un élément et fusionne à\nchaque niveau, même si les fusions sont alors un peu moins\ncoûteuses.\n"
        },
        {
          "text": "$n$, une seule passe de fusion suffisant",
          "correct": false,
          "feedback": "Erreur : c'est le tri par insertion qui profite d'une liste\ntriée, pas le tri fusion.\n"
        },
        {
          "text": "$1$, le tri détectant l'ordre dès le départ",
          "correct": false,
          "feedback": "Erreur : aucune détection n'est prévue dans l'algorithme\nclassique.\n"
        },
        {
          "text": "$n^2$, le pire cas étant alors atteint",
          "correct": false,
          "feedback": "Erreur : le tri fusion n'a pas de cas quadratique.\n"
        }
      ],
      "explanation": "Le tri fusion a un coût régulier, en $n \\log n$ dans tous les cas :\nun avantage sur les mauvaises listes, un léger désavantage sur les\nlistes presque triées."
    },
    {
      "id": "q38",
      "difficulty": 2,
      "skills": [
        "principe",
        "dichotomie",
        "sous-probleme"
      ],
      "title": "Un diviser pour régner à un seul sous-problème",
      "partie": "principe",
      "statement": "La recherche dichotomique divise la liste en deux moitiés mais ne\npoursuit que dans l'une d'elles. Est-ce un diviser pour régner ?",
      "options": [
        {
          "text": "Oui, avec un seul sous-problème et sans combinaison",
          "correct": true,
          "feedback": "Bonne réponse : diviser, régner sur une moitié, et le résultat\nde la moitié est le résultat global. C'est le cas le plus simple\ndu paradigme, avec un coût logarithmique.\n"
        },
        {
          "text": "Non, un diviser pour régner doit traiter toutes les parties",
          "correct": false,
          "feedback": "Erreur : rien n'impose de traiter chaque partie ; écarter une\nmoitié est précisément la source de l'efficacité.\n"
        },
        {
          "text": "Non, car la dichotomie n'est pas récursive",
          "correct": false,
          "feedback": "Erreur : la dichotomie s'écrit naturellement de façon récursive.\n"
        },
        {
          "text": "Oui, mais son coût est alors de l'ordre de $n \\log n$",
          "correct": false,
          "feedback": "Erreur : avec un seul sous-problème de taille moitié et un\ntravail constant, le coût est en $\\log n$.\n"
        }
      ],
      "explanation": "Le nombre de sous-problèmes conservés détermine le coût : un seul\ndonne $\\log n$, deux avec combinaison linéaire donne $n \\log n$."
    }
  ]
}