<?xml version="1.0" encoding="UTF-8"?>
<quiz>
<question type="category">
  <category>
    <text>$course$/QCM de NSI/Première/Recherche linéaire</text>
  </category>
  <info format="html">
    <text><![CDATA[<p>Recherche séquentielle d'un élément dans une liste,<br/>
parcours élément par élément, cas favorables et<br/>
défavorables, complexité, comparaison avec la recherche<br/>
dichotomique, variantes (indice, booléen, toutes les<br/>
occurrences).</p>]]></text>
  </info>
</question>

<question type="multichoice">
  <name>
    <text>Recherche linéaire — Q01 : Recherche linéaire ou séquentielle</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>En quoi consiste la <strong>recherche linéaire</strong> (ou séquentielle) ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>La recherche linéaire est universelle : elle<br/>
fonctionne sur tout itérable (liste, chaîne,<br/>
tuple) sans hypothèse sur l'ordre des éléments.<br/>
Sa simplicité a un prix : elle peut nécessiter<br/>
jusqu'à n comparaisons.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Sauter directement à la position centrale puis comparer</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est l'idée de la recherche<br/>
<strong>dichotomique</strong>, qui n'est applicable qu'à<br/>
une liste triée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Parcourir la liste élément par élément et comparer chaque valeur à celle recherchée</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : c'est l'algorithme le plus<br/>
simple. Il fonctionne sur n'importe quelle<br/>
liste (triée ou non).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Utiliser un dictionnaire pour aller directement à la valeur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est une autre stratégie (table de<br/>
hachage), différente de la recherche<br/>
linéaire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Trier la liste puis chercher le premier élément</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la recherche linéaire ne nécessite<br/>
pas de tri préalable.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche linéaire — Q02 : Liste triée ou non ?</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>La recherche linéaire suppose-t-elle que la liste<br/>
soit <strong>triée</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Quand la liste est triée, on peut faire mieux<br/>
avec la dichotomique (O(log n)). Mais la linéaire<br/>
reste un choix correct, simple et universel.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Uniquement si la liste contient des nombres</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la recherche linéaire fonctionne<br/>
quel que soit le type des éléments<br/>
(nombres, chaînes, objets...).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Non, elle fonctionne sur n'importe quelle liste</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : c'est précisément l'avantage<br/>
de la recherche linéaire. On peut l'appliquer<br/>
à des données non triées (par exemple, une<br/>
liste de noms saisis dans l'ordre d'arrivée).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Uniquement si la liste contient au moins 10 éléments</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la recherche linéaire fonctionne<br/>
aussi sur des listes courtes ou vides.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Oui, sinon elle ne fonctionne pas</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est la <strong>dichotomique</strong> qui exige<br/>
une liste triée. La linéaire fonctionne sans<br/>
condition.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche linéaire — Q03 : Pire cas</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quel est le <strong>nombre maximal de comparaisons</strong> dans<br/>
une recherche linéaire dans une liste de longueur n ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pire cas : l'élément n'est pas présent. On a fait<br/>
n comparaisons négatives. Meilleur cas : l'élément<br/>
est en première position, une seule comparaison.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>n²</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on parcourt la liste <strong>une seule<br/>
fois</strong>, sans imbrication de boucle.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>log(n)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est la complexité de la recherche<br/>
dichotomique, applicable seulement aux listes<br/>
triées.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>n</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : dans le pire cas (élément<br/>
absent ou en dernière position), il faut<br/>
comparer chacun des n éléments. La complexité<br/>
est en O(n).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>n / 2</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : n / 2 est le nombre <strong>moyen</strong> de<br/>
comparaisons (en supposant l'élément présent<br/>
en position aléatoire), pas le maximum.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche linéaire — Q04 : Quand arrête-t-on la boucle ?</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Dans une recherche linéaire bien programmée, quand<br/>
arrête-t-on de parcourir la liste ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Schéma Python typique :<br/>
for i, x in enumerate(liste):<br/>
    if x == cible: return i<br/>
return -1.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Au bout de log(n) comparaisons</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est la dichotomique. Sans<br/>
hypothèse de tri, on ne peut pas s'arrêter<br/>
avant.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Dès que l'élément n'est pas trouvé</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : si le premier élément n'est pas le<br/>
bon, l'élément peut quand même être plus loin.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Toujours après avoir parcouru toute la liste</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Pas optimal : si on a déjà trouvé l'élément,<br/>
inutile de continuer. Mais cela donne malgré<br/>
tout un résultat correct (juste plus lent).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Dès que l'élément cherché est trouvé, ou en arrivant à la fin de la liste</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : on s'arrête au plus tôt avec<br/>
un break ou un return. Cela améliore le<br/>
temps moyen mais ne change pas le pire cas<br/>
(élément absent, parcours complet).</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche linéaire — Q05 : Que renvoyer si absent ?</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Si l'élément cherché n'est <strong>pas dans la liste</strong>,<br/>
que peut-on raisonnablement renvoyer ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Lever une exception (ValueError, comme<br/>
list.index) est aussi une option. La méthode<br/>
Python str.find renvoie -1, mais str.index<br/>
lève une exception : il existe les deux.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La dernière position de la liste (n - 1)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on confondrait avec « élément en<br/>
dernière position ».</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La position 0 (par défaut)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on confondrait avec « élément en<br/>
première position ».</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La longueur de la liste</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : valeur arbitraire, pas une<br/>
convention reconnue.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>None ou -1, pour signaler l'absence</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : ce sont les deux conventions<br/>
courantes. str.find renvoie -1,<br/>
dict.get renvoie None. À la maison de<br/>
choisir, mais il faut <strong>être cohérent</strong> dans<br/>
tout le code.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche linéaire — Q06 : Code Python typique</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quel code implémente correctement la recherche<br/>
linéaire et renvoie l'<strong>indice</strong> de la cible (ou<br/>
-1 si absente) ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Vérifier deux choses dans toute fonction de<br/>
recherche : le <strong>type</strong> de retour (indice,<br/>
booléen, ou objet), et le <strong>comportement</strong> en<br/>
cas d'absence.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
def chercher(liste, cible):<br/>
    for i in range(len(liste)):<br/>
        if liste[i] == cible:<br/>
            return i<br/>
        return -1<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur d'<strong>indentation</strong> : return -1 est<br/>
dans la boucle, ce qui termine après la<br/>
première comparaison. La fonction renverrait<br/>
toujours 0 ou -1 selon le premier élément.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
def chercher(liste, cible):<br/>
    for x in liste:<br/>
        if x == cible:<br/>
            return x<br/>
    return -1<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on renvoie x (la <strong>valeur</strong>), pas<br/>
son indice. La spécification demandait<br/>
l'indice.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>`<code>python<br/>
def chercher(liste, cible):<br/>
    for i in range(len(liste)):<br/>
        if liste[i] == cible:<br/>
            return i<br/>
    return -1<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : parcours par indice, retour<br/>
précoce dès la cible trouvée, -1 si la<br/>
boucle se termine sans trouver.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
def chercher(liste, cible):<br/>
    while True:<br/>
        if liste[0] == cible:<br/>
            return 0<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : boucle infinie si l'élément n'est<br/>
pas en première position.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche linéaire — Q07 : Opérateur `in`</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>L'expression Python 42 in liste réalise<br/>
implicitement quelle opération ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>L'opérateur in cache la complexité. Sur des<br/>
gros volumes, préférer set (O(1)) à list<br/>
(O(n)) pour les tests d'appartenance répétés.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un tri</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : in ne modifie pas la liste.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une recherche dichotomique (rapide)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Python ne suppose pas que la liste<br/>
est triée. Il fait du linéaire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Une recherche linéaire de gauche à droite, qui s'arrête dès qu'une correspondance est trouvée</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : sur une list, in est en<br/>
O(n). Sur un set ou dict, il est en O(1)<br/>
(table de hachage).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une vérification de type</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : in teste l'appartenance, pas le<br/>
type.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche linéaire — Q08 : Liste vide</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que doit renvoyer une recherche linéaire (qui<br/>
renvoie l'indice ou -1) sur une <strong>liste vide</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Cas limite à toujours tester. Bonne pratique :<br/>
écrire un test unitaire assert chercher([], x) == -1.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une exception</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Pas nécessairement. Avec le schéma<br/>
standard, la boucle ne s'exécute pas et la<br/>
fonction renvoie -1 proprement.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>None</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Possible (autre convention), mais selon<br/>
notre énoncé, la fonction renvoie -1.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>-1 (élément absent)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : aucune valeur n'est dans la<br/>
liste vide, donc tout élément y est absent.<br/>
La boucle ne s'exécute pas, on tombe<br/>
directement sur return -1.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>0</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : 0 signifierait « trouvé en première<br/>
position » alors qu'il n'y a aucune position.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche linéaire — Q09 : Recherche de minimum</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Trouver le <strong>minimum</strong> d'une liste est aussi un<br/>
cas de recherche linéaire. Quelle est sa<br/>
complexité ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Note importante : ici on <strong>ne peut pas s'arrêter<br/>
tôt</strong> car on ne sait pas si un élément plus<br/>
petit existe plus loin. C'est différent de la<br/>
recherche d'une valeur précise.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(n²) : double boucle nécessaire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un seul parcours suffit (en gardant<br/>
le minimum courant dans une variable).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(1) : on prend juste le premier élément</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le premier élément n'est pas<br/>
forcément le minimum (sauf liste triée).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(log n) : recherche dichotomique</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ne fonctionne pas, même sur liste<br/>
triée la dichotomique cherche une cible<br/>
précise, pas un extremum.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>O(n) : on doit comparer tous les éléments</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : pour garantir le minimum, il<br/>
faut <strong>examiner chaque</strong> élément. On ne peut<br/>
pas s'arrêter avant la fin (contrairement à<br/>
la recherche d'une cible précise).</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche linéaire — Q10 : Trace simple</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On cherche cible = 7 dans liste = [3, 5, 7, 2, 7].<br/>
Combien de comparaisons effectue une recherche<br/>
linéaire <strong>avec arrêt précoce</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Sans arrêt précoce, on aurait fait 5<br/>
comparaisons et compté 2 occurrences. Avec<br/>
arrêt précoce, 3 comparaisons et indice retourné<br/>
directement (= 2).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>5</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on ne parcourt pas toute la liste si<br/>
on s'arrête au premier 7 rencontré.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>1</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : il faut comparer 3, puis 5 avant<br/>
d'arriver à 7.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>2</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : il faut bien tester liste[2] (et<br/>
la trouver égale à 7) pour conclure.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>3</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : liste[0]=3 (≠), liste[1]=5<br/>
(≠), liste[2]=7 (=) → on s'arrête. Trois<br/>
comparaisons.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche linéaire — Q11 : Meilleur cas</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est la complexité dans le <strong>meilleur cas</strong><br/>
de la recherche linéaire ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pour une recherche d'un élément aléatoirement<br/>
placé dans la liste, la complexité <strong>moyenne</strong><br/>
est O(n / 2), souvent simplifiée en O(n) car les<br/>
constantes sont ignorées dans la notation O.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>O(1)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : si l'élément cherché est en<br/>
<strong>première position</strong>, on s'arrête après une<br/>
seule comparaison.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(n²)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : pas de double boucle.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(log n)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucun mécanisme dichotomique ici.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(n)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : O(n) est le pire cas.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche linéaire — Q12 : Variante booléenne</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On veut juste savoir si l'élément est présent ou<br/>
non (sans avoir besoin de l'indice). Quelle<br/>
version est la plus pythonique ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Maxime : « N'écris pas en Python ce que Python<br/>
sait déjà faire. » L'opérateur in est conçu<br/>
pour exactement ce cas.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
def present(liste, cible):<br/>
    return liste.index(cible)<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : index lève ValueError si<br/>
l'élément est absent (pas un booléen).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>`<code>python<br/>
def present(liste, cible):<br/>
    return cible in liste<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : Python a une syntaxe native<br/>
pour cela. Sous le capot, c'est exactement<br/>
la même boucle linéaire, mais le code est<br/>
plus lisible.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
def present(liste, cible):<br/>
    for x in liste:<br/>
        if x == cible:<br/>
            return True<br/>
    return False<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Code correct, mais plus long que nécessaire.<br/>
Python offre une syntaxe plus directe.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
def present(liste, cible):<br/>
    return cible == liste<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on compare l'élément à la liste<br/>
entière, ce qui renvoie toujours False<br/>
(sauf cas dégénéré).</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche linéaire — Q13 : Toutes les occurrences</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour trouver <strong>toutes</strong> les positions où la cible<br/>
apparaît dans la liste, quelle adaptation de la<br/>
recherche linéaire utilise-t-on ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Code typique :<br/>
[i for i, x in enumerate(liste) if x == cible].<br/>
Élégant, en une ligne, en O(n).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>On trie la liste avant de chercher</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : trier modifie l'ordre et fait perdre<br/>
les positions originales.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>On parcourt toute la liste et on enregistre tous les indices où l'élément correspond</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : pas d'arrêt précoce ici, on<br/>
accumule dans une liste de résultats.<br/>
Complexité : O(n) (parcours unique).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>On utilise une recherche dichotomique</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la dichotomique trouve <strong>une</strong><br/>
occurrence dans une liste triée, mais ne<br/>
liste pas toutes les occurrences naturellement.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>On s'arrête à la première occurrence et on l'enregistre</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on raterait les suivantes.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche linéaire — Q14 : Linéaire vs dichotomique</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour rechercher un élément dans une <strong>liste triée</strong><br/>
de 1 000 000 d'éléments, combien de comparaisons<br/>
au pire avec chacune des deux méthodes ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>log₂(2¹⁰) = 10, log₂(2²⁰) = 20. Doubler la<br/>
taille de la liste ajoute juste <strong>une</strong><br/>
comparaison à la dichotomique, mais double les<br/>
comparaisons de la linéaire.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Linéaire : 1 000 000 ; dichotomique : ~ 20</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : log₂(10⁶) ≈ 20. La<br/>
dichotomique est ~ 50 000 fois plus rapide<br/>
dans ce cas. C'est l'intérêt majeur du tri.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Linéaire : 1 000 000 ; dichotomique : 1 000</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la dichotomique est en O(log n),<br/>
beaucoup plus efficace.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Linéaire : 1 000 ; dichotomique : 1 000 000</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : valeurs inversées.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Les deux sont identiques</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la dichotomique est exponentiellement<br/>
plus rapide sur les grandes tailles.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche linéaire — Q15 : Bug d'initialisation</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Un élève écrit<br/>
`<code>python<br/>
def chercher(liste, cible):<br/>
    for i in range(len(liste)):<br/>
        if liste[i] == cible:<br/>
            trouve = True<br/>
        else:<br/>
            trouve = False<br/>
    return trouve<br/>
</code>`<br/>
Quel est le bug ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Schéma correct : initialiser un drapeau<br/>
<strong>avant</strong> la boucle, ne le mettre à True<br/>
qu'<strong>en cas de succès</strong>. Mieux : utiliser<br/>
return True direct et return False après la<br/>
boucle.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>return doit être à l'intérieur de la boucle</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait un autre code, mais ce<br/>
n'est pas la cause du bug actuel.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>À chaque itération, trouve est réinitialisé. Seul le résultat de la dernière comparaison est renvoyé.</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : si la cible est trouvée puis<br/>
que la dernière itération échoue, trouve<br/>
finit à False. Solution : initialiser<br/>
trouve = False avant la boucle, et <strong>ne<br/>
faire</strong> que trouve = True à l'intérieur<br/>
(sans else).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La fonction est trop lente</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la performance n'est pas le<br/>
problème principal.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La variable trouve n'est pas définie hors de la boucle</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Python autorise (à risque) la sortie<br/>
d'une variable de boucle, tant que la<br/>
boucle s'exécute au moins une fois.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche linéaire — Q16 : While ou for ?</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est la différence pratique entre une<br/>
recherche linéaire écrite avec for et avec<br/>
while ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Bonne pratique : for pour parcourir une<br/>
structure connue ; while quand on ne sait pas<br/>
à l'avance combien d'itérations seront<br/>
nécessaires (lecture utilisateur, condition<br/>
complexe).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>while ne fonctionne pas sur les listes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : while fonctionne avec n'importe<br/>
quelle condition booléenne.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>for est plus lisible quand on parcourt tous les indices ; while est plus naturel pour combiner deux conditions d'arrêt (par exemple i &lt; n and not trouve)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : while permet une condition<br/>
composée. for est plus concis quand on<br/>
itère simplement sur la longueur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>for est plus rapide</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Performance équivalente. La différence est<br/>
stylistique.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Les deux sont strictement équivalents en Python</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Sur le plan du résultat oui, sur le plan de<br/>
la lisibilité non.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche linéaire — Q17 : Recherche dans un dictionnaire</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pourquoi la recherche d'une <strong>clé</strong> dans un<br/>
dictionnaire Python est-elle en O(1) (alors que<br/>
in liste est en O(n)) ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>À retenir : liste → in en O(n) ; set ou<br/>
dict → in en O(1) en moyenne. Pour des tests<br/>
d'appartenance répétés, transformer une liste en<br/>
set est souvent payant.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Parce que les dictionnaires utilisent une table de hachage : la position d'une clé est calculée directement par une fonction de hachage</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : pas besoin de parcourir, on<br/>
calcule directement l'emplacement à partir<br/>
de la clé. C'est l'avantage majeur de cette<br/>
structure.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce que les dictionnaires sont triés</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : depuis Python 3.7, l'ordre<br/>
d'insertion est conservé, mais cela n'a rien<br/>
à voir avec la complexité de recherche.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce qu'ils contiennent moins de données</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un dict peut être gigantesque, sa<br/>
recherche reste en O(1).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce que Python est un langage rapide</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Réponse vague et incorrecte : la rapidité<br/>
vient de la <strong>structure de données</strong>, pas<br/>
du langage.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche linéaire — Q18 : Optimisation par fréquence</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Si l'on sait qu'un élément est <strong>plus souvent<br/>
cherché</strong> que les autres, comment optimiser une<br/>
série de recherches linéaires successives ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Cette idée (« self-organizing list ») est<br/>
utilisée en pratique dans certains caches.<br/>
C'est un bon exemple où l'<strong>ordre</strong> des données<br/>
influence la performance.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Trier la liste par ordre croissant</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le tri n'aide pas la linéaire (et coûte O(n<br/>
log n)). De plus, les éléments fréquents ne<br/>
sont pas forcément les plus petits.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Doubler la taille de la liste</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : cela aggrave le problème.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Placer les éléments les plus fréquents au début de la liste</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la recherche linéaire avec<br/>
arrêt précoce trouvera ces éléments plus<br/>
vite. Heuristique « move-to-front » :<br/>
déplacer chaque élément trouvé en tête.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Convertir la liste en chaîne</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucun gain, et in sur une chaîne<br/>
recherche les sous-chaînes, pas les<br/>
éléments.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche linéaire — Q19 : Recherche dans liste de tuples</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Soit<br/>
eleves = [("Alice", 17), ("Bob", 16), ("Eve", 18)].<br/>
Comment trouver l'âge d'Alice ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Si l'on fait souvent ce genre de recherche,<br/>
mieux vaut convertir en dict :<br/>
{nom: age for nom, age in eleves} puis<br/>
eleves["Alice"] en O(1).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
eleves["Alice"]<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : eleves est une liste, pas un<br/>
dictionnaire. On ne peut pas l'indexer par<br/>
chaîne.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>`<code>python<br/>
for nom, age in eleves:<br/>
    if nom == "Alice":<br/>
        return age<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : on déballe chaque tuple en<br/>
deux variables, on teste le nom, on renvoie<br/>
l'âge. Recherche linéaire classique.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
eleves.index(("Alice"))<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ("Alice") est une chaîne (pas un<br/>
tuple ; il manque la virgule). Et même<br/>
("Alice",) ne correspond pas car le tuple<br/>
est ("Alice", 17).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
eleves.find("Alice")<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la méthode .find n'existe pas sur<br/>
les listes.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche linéaire — Q20 : Sur une chaîne</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>L'expression "a" in "abracadabra" :</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Subtilité : sur une chaîne, "abc" in "ababcabc"<br/>
renvoie aussi True (sous-chaîne, pas<br/>
caractère). Sur une liste, "abc" in liste<br/>
teste l'égalité avec chaque élément.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Lève une exception</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la syntaxe est valide.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Renvoie False</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : "a" apparaît bien dans<br/>
"abracadabra".</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Renvoie le nombre d'occurrences</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : in renvoie un booléen, pas un<br/>
entier. Pour le comptage, utiliser .count().</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Renvoie True</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : in sur une chaîne fait une<br/>
recherche de <strong>sous-chaîne</strong> (pas de<br/>
caractère unique seulement). "a" est<br/>
présent comme sous-chaîne.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche linéaire — Q21 : Bug : oubli du `break`</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>`<code>python<br/>
def trouver(liste, cible):<br/>
    indice = -1<br/>
    for i in range(len(liste)):<br/>
        if liste[i] == cible:<br/>
            indice = i<br/>
    return indice<br/>
</code>`<br/>
Quel est le comportement de cette fonction si la<br/>
cible apparaît plusieurs fois ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Cas piège mais utile : ce code peut être correct<br/>
si l'on cherche <strong>la dernière occurrence</strong>. La<br/>
version classique « première occurrence »<br/>
requiert un return i ou un break après<br/>
l'affectation.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle renvoie -1</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : -1 est l'initialisation, mais elle<br/>
est écrasée si une correspondance existe.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Elle renvoie l'indice de la dernière occurrence</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la boucle continue jusqu'au<br/>
bout, et indice = i écrase la valeur à<br/>
chaque correspondance. À la fin, c'est la<br/>
dernière occurrence qui reste.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle entre dans une boucle infinie</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : for sur range est borné.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle renvoie l'indice de la première occurrence</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : il manque un break ou un return<br/>
pour s'arrêter à la première occurrence.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche linéaire — Q22 : Choisir le bon algorithme</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour rechercher un élément dans une liste de<br/>
100 éléments, <strong>non triée</strong>, qu'on ne consultera<br/>
qu'une seule fois, quelle stratégie est la plus<br/>
efficace <strong>globalement</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Règle générale : prétraiter (trier, indexer)<br/>
n'est rentable qu'au-delà d'un certain nombre<br/>
de recherches. Pour une recherche unique, la<br/>
linéaire est imbattable en simplicité.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Recherche linéaire directement</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : pour <strong>une seule</strong><br/>
recherche, la linéaire (au plus 100<br/>
comparaisons) est plus rapide que tri +<br/>
dichotomie. L'investissement du tri n'est<br/>
rentable que pour de <strong>multiples</strong><br/>
recherches.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Convertir en dictionnaire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Possible mais O(n) pour construire le dict.<br/>
Pour une seule recherche, gain nul.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Faire la recherche en parallèle sur 4 cœurs</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Sur 100 éléments, le coût de<br/>
parallélisation dépasse largement le coût<br/>
de la recherche.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Trier puis dichotomie</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : trier coûte O(n log n) ≈ 700<br/>
opérations, plus 7 pour la dichotomie. Soit<br/>
~ 707 opérations contre 100 max pour la<br/>
linéaire. Pas rentable pour une seule<br/>
recherche.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche linéaire — Q23 : Boucle while à bug</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>`<code>python<br/>
def chercher(liste, cible):<br/>
    i = 0<br/>
    while liste[i] != cible:<br/>
        i += 1<br/>
    return i<br/>
</code>`<br/>
Quel problème pose ce code ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Bug très classique. Pour les boucles while,<br/>
toujours vérifier deux choses : la condition<br/>
d'arrêt <strong>et</strong> l'évolution de la variable de<br/>
boucle (pour éviter une boucle infinie ou un<br/>
dépassement).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucun, le code est correct</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : il y a un bug majeur lié au cas<br/>
d'absence.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La fonction ne renvoie jamais rien</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : elle renvoie i quand elle trouve<br/>
la cible.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Si l'élément est absent, la boucle dépasse la fin de la liste et lève IndexError</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : il manque la condition<br/>
i &lt; len(liste) dans le while. Sans cela,<br/>
on accède à liste[len(liste)] qui n'existe<br/>
pas. Solution :<br/>
while i &lt; len(liste) and liste[i] != cible:.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le code modifie la liste</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucune modification de la liste.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche linéaire — Q24 : Comparer en pratique</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Sur ma machine, une recherche linéaire dans une<br/>
liste de 1 million d'éléments prend ~ 30 ms. Que<br/>
prendra une recherche dans une liste de 1<br/>
milliard d'éléments (si la mémoire le permet) ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Compétence essentielle : savoir extrapoler le<br/>
temps d'exécution selon la complexité. La<br/>
recherche linéaire devient gênante au-delà de<br/>
quelques millions d'éléments si elle est<br/>
répétée.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Environ 60 ms (juste deux fois plus)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : 1 milliard, c'est mille fois plus<br/>
que 1 million, pas deux fois.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Environ 30 secondes (1000 fois plus, car n est multiplié par 1000)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : O(n) → temps proportionnel.<br/>
1 milliard / 1 million = 1000, donc 30 ms ×<br/>
1000 = 30 s. Cette estimation est précieuse<br/>
pour anticiper les performances.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Environ 30 secondes au carré</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait O(n²), pas O(n).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Toujours environ 30 ms (constante)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : O(n) signifie que le temps croît<br/>
<strong>proportionnellement</strong> à n.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche linéaire — Q25 : Synthèse</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Parmi les affirmations suivantes sur la recherche<br/>
linéaire, laquelle est <strong>fausse</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Maxime : « Pas d'algorithme universellement<br/>
meilleur. » Le choix dépend des hypothèses<br/>
(liste triée ?), du nombre de recherches, et<br/>
de la taille des données.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>En Python, l'opérateur in sur une liste fait une recherche linéaire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Vrai : in sur une list est en O(n) ; il<br/>
faudrait un set ou dict pour avoir O(1).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Elle fonctionne sur des listes triées comme non triées</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Vrai : c'est l'avantage majeur sur la<br/>
dichotomique.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Sa complexité au pire est O(n)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Vrai : parcours complet de la liste.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Elle est toujours plus rapide que la dichotomique</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Faux (donc bonne réponse) : sur une liste<br/>
triée et de grande taille, la dichotomique<br/>
(O(log n)) est exponentiellement plus<br/>
rapide. La linéaire reste compétitive sur<br/>
des petites listes ou pour une recherche<br/>
unique.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche linéaire — Q26 : Compter les occurrences</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On veut <strong>compter</strong> combien de fois la cible<br/>
apparaît dans la liste (et non simplement la<br/>
trouver). Quelle adaptation de la recherche<br/>
linéaire faut-il faire ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Différence essentielle avec la recherche d'une<br/>
occurrence : on ne peut pas s'arrêter au premier<br/>
succès, donc le pire cas et le meilleur cas sont<br/>
identiques en O(n). En Python, la méthode<br/>
liste.count(cible) fait exactement cela.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
def compter(liste, cible):<br/>
    for x in liste:<br/>
        if x == cible:<br/>
            return 1<br/>
    return 0<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur classique : on s'arrête à la première<br/>
occurrence et on renvoie toujours 0 ou 1, ce<br/>
qui revient à un test d'appartenance, pas à<br/>
un comptage.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
def compter(liste, cible):<br/>
    return len(liste) if cible in liste else 0<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur grossière : si la cible apparaît au<br/>
moins une fois, on renvoie la longueur<br/>
totale de la liste (donc tous les éléments<br/>
sont comptés, même ceux qui ne sont pas la<br/>
cible).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>`<code>python<br/>
def compter(liste, cible):<br/>
    n = 0<br/>
    for x in liste:<br/>
        if x == cible:<br/>
            n += 1<br/>
    return n<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : on parcourt <strong>toute</strong> la<br/>
liste sans arrêt précoce, on incrémente un<br/>
compteur à chaque correspondance. Complexité<br/>
O(n). Équivalent à liste.count(cible).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
def compter(liste, cible):<br/>
    return liste.index(cible)<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : index renvoie la position de la<br/>
première occurrence (et lève une exception<br/>
si elle est absente), pas le nombre total.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche linéaire — Q27 : Recherche par condition</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On cherche le <strong>premier</strong> élément d'une liste de<br/>
nombres qui soit <strong>strictement supérieur</strong> à<br/>
100 (et son indice). Quel code applique<br/>
correctement la recherche linéaire à ce cas ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Schéma général de la recherche linéaire par<br/>
prédicat. On peut le rendre plus pythonique<br/>
avec next : next((x for x in liste if x &gt; 100), None).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
def premier_grand(liste):<br/>
    liste.sort()<br/>
    return liste[-1]<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur double : on trie (ce qui modifie la<br/>
liste et coûte O(n log n)), puis on renvoie<br/>
le maximum, qui n'est pas forcément le<br/>
<strong>premier</strong> élément supérieur à 100 dans<br/>
l'ordre original.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
def premier_grand(liste):<br/>
    return max(liste) &gt; 100<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur de spécification : on demande le<br/>
premier élément supérieur à 100, pas un<br/>
booléen indiquant s'il en existe un. Et<br/>
cette version coûte O(n) sans donner<br/>
l'information utile.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
def premier_grand(liste):<br/>
    for x in liste:<br/>
        if x &gt; 100:<br/>
            return x<br/>
        return None<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur d'indentation : return None est<br/>
dans la boucle, donc la fonction sort dès le<br/>
premier élément (qui est rarement supérieur<br/>
à 100). De plus, on ne renvoie pas l'indice.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>`<code>python<br/>
def premier_grand(liste):<br/>
    for i, x in enumerate(liste):<br/>
        if x &gt; 100:<br/>
            return (i, x)<br/>
    return None<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la recherche linéaire se<br/>
généralise à n'importe quelle condition<br/>
(prédicat). On parcourt la liste, on teste<br/>
la condition, on renvoie dès le premier<br/>
succès. Si aucun élément ne satisfait la<br/>
condition, on renvoie None.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche linéaire — Q28 : Recherche dans un tableau à deux dimensions</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On dispose d'une matrice carrée représentée par<br/>
une liste de listes (par exemple<br/>
m = [[3, 7, 1], [8, 2, 5], [4, 9, 6]]). On<br/>
cherche le couple (ligne, colonne) de la<br/>
première occurrence de la valeur 5. Quel code<br/>
est correct ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pour une matrice non carrée, on remplace<br/>
len(m[i]) par la longueur de la ligne<br/>
courante. Avec enumerate, le code devient<br/>
plus lisible :<br/>
for i, ligne in enumerate(m): for j, x in enumerate(ligne): ....</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
def chercher(m, cible):<br/>
    if cible in m:<br/>
        return m.index(cible)<br/>
    return None<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : in m teste si la cible est l'une<br/>
des <strong>lignes</strong> de la matrice, pas l'un de<br/>
ses éléments. Ce code ne trouvera donc rien<br/>
(sauf si la cible est elle-même une liste<br/>
identique à une ligne).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
def chercher(m, cible):<br/>
    for ligne in m:<br/>
        for x in ligne:<br/>
            if x == cible:<br/>
                return x<br/>
    return None<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on renvoie la <strong>valeur</strong> trouvée<br/>
(ce qui est trivial puisqu'on connaît<br/>
déjà la cible), pas le couple de<br/>
coordonnées demandé. Il faut utiliser<br/>
enumerate pour récupérer les indices.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>python<br/>
def chercher(m, cible):<br/>
    for i in range(len(m)):<br/>
        if m[i] == cible:<br/>
            return i<br/>
    return None<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on compare une <strong>ligne entière</strong> à<br/>
la cible (un nombre), ce qui sera toujours<br/>
faux. On confond élément de la matrice et<br/>
ligne.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>`<code>python<br/>
def chercher(m, cible):<br/>
    for i in range(len(m)):<br/>
        for j in range(len(m[i])):<br/>
            if m[i][j] == cible:<br/>
                return (i, j)<br/>
    return None<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : double boucle imbriquée pour<br/>
parcourir lignes et colonnes, retour<br/>
précoce dès la cible trouvée. Pour la<br/>
matrice donnée, on renvoie (1, 2).<br/>
Complexité O(L × C) où L est le nombre de<br/>
lignes et C le nombre de colonnes.</p>]]></text>
    </feedback>
  </answer>
</question>

</quiz>
