La fête foraine
Vous vous amusez à une fête foraine. Vous décidez de jouer au stand "Gagnez le gros lot !". Des lots visuellement identiques, numérotés de 1 à 32, sont exposés. Ils ont tous la même valeur de 1€, sauf un qui a la valeur de 100 €. Vous devez trouver une stratégie pour déterminer à coup sûr le numéro du lot de valeur 100 €.
La règle du jeu est la suivante : vous pouvez sélectionner deux groupes de lots, nommés groupe_1
et groupe_2
. Le forain (qui connaît bien-sûr le numéro du gros lot) vous donnera une indication sur les valeurs globales de groupe_1
et groupe_2
.
Si les deux groupes ont la même valeur globale, il dira "identique"
, si le groupe_1
a plus de valeur, il dira "groupe_1"
, sinon il dira "groupe_2"
.
😥 Vous ne pouvez pas lui demander plus de six indications.
La classe Lots_en_jeu
permet de créer une sélection de lots numérotés qui seront mis en jeu par le forain.
Vous devez rédiger la fonction gros_lot
qui prend en paramètres :
lots
de la classeLots_en_jeu
;- le numéro
debut
de début de la zone de recherche (inclus) ; - le numéro
fin
de fin de la zone de recherche (exclu).
Cette fonction renvoie le numéro du lot de valeur 100 € dans lots
.
Les indications données par le forain sont mises en oeuvre par indication(lots, debut_1, fin_1, debut_2, fin_2)
.
Le groupe_1
contient les lots dont les numéros de début et de fin sont debut_1
(inclus) et fin_1
(exclu).
Le groupe_2
contient les lots dont les numéros de début et de fin sont debut_2
(inclus) et fin_2
(exclu).
Le résultat renvoyé sera :
"groupe_1"
si legroupe_1
a la plus grande valeur ;"identique"
si les deux groupes ont la même valeur ;"groupe_2"
si legroupe_2
a la plus grande valeur.
Ainsi indication(lots, 1, 15, 15, 30)
compare les valeurs totales des lots de numéros allant de 1
(inclus) à 15
(exclu) pour le groupe_1
et de 15
(inclus) à 30
(exclu) pour le groupe_2
.
La fonction indication
est déjà écrite, vous ne devez pas l’écrire.
On fournit ci-dessous quelques exemples d’utilisation des différentes fonctions :
>>> lots = Lots_en_jeu() # une sélection de 32 lots
>>> lots
'Une sélection de 32 lots'
>>> # comparaison des valeurs totales des groupes
>>> # de lots dont les numéros sont dans [1, 20[ et [28, 32[
>>> indication(lots, 1, 20, 28, 32)
'groupe_1'
>>> indication(lots, 5, 15, 17, 27)
'identique'
>>> gros_lot(lots, 1, 33)
2
Votre fonction, pour 32 lots, ne doit pas appeler plus de 6 fois la fonction indication
.
Toute tentative juste de résolution sera valorisée.
Exercice
Compléter ci-dessous :
debutpy-und1
(inclus) et finpy-und1
(exclu).bksl-nl groupepy-und2 contient les lots dont les numéros de début et de fin sontbksl-nl debutpy-und2
(inclus) et finpy-und2
(exclu).bksl-nlbksl-nl Cette fonction renvoie :bksl-nl py-str "groupepy-und1" si le groupepy-und1 a la plus grande valeurbksl-nl py-str "identique" si les deux groupes ont la même valeurbksl-nl py-str "groupepy-und2" si le groupepy-und2 a la plus grande valeurbksl-nlbksl-nl indication(lots, 1, 20, 28, 31) compare donc les valeursbksl-nl des lots de numéros :bksl-nl py-str allant de 1 (inclus) à 20 exclu pour le groupepy-und1bksl-nl py-str allant de 28 (inclus) à 31 exclu pour le groupepy-und2bksl-nl """bksl-nlbksl-nl if debutpy-und1 <= lots.npy-undgagnant < finpy-und1:bksl-nl valeurpy-und1 = (bksl-nl lots.valeur py-str (finpy-und1 - debutpy-und1 - 1) + lots.gagnantbksl-nl )bksl-nl else:bksl-nl valeurpy-und1 = lots.valeur py-str (finpy-und1 - debutpy-und1)bksl-nlbksl-nl if debutpy-und2 <= lots.npy-undgagnant < finpy-und2:bksl-nl valeurpy-und2 = (bksl-nl lots.valeur py-str (finpy-und2 - debutpy-und2 - 1) + lots.gagnantbksl-nl )bksl-nl else:bksl-nl valeurpy-und2 = lots.valeur py-str (finpy-und2 - debutpy-und2)bksl-nlbksl-nl if valeurpy-und1 < valeurpy-und2:bksl-nl return "groupepy-und2"bksl-nl elif valeurpy-und1 == valeurpy-und2:bksl-nl return "identique"bksl-nl else:bksl-nl return "groupepy-und1"bksl-nlbksl-nlbksl-nl#--- HDR ---#bksl-nlbksl-nlbksl-nldef grospy-undlot(lots, debut, fin):bksl-nl """bksl-nl Renvoie le numéro du gros lot dans lotsbksl-nl """bksl-nl ...bksl-nl bksl-nlbksl-nl# Testsbksl-nlfor i in range(10):bksl-nl lots = Lotspy-undenpy-undjeu()bksl-nl assert grospy-undlot(lots, 1, 33) == lots.npy-undgagnantbksl-nlbksl-nl bksl-nldef grospy-undlot(lots, debut, fin):bksl-nl """bksl-nl Renvoie le numéro du gros lot dans lotsbksl-nl """bksl-nl if debut + 1 == fin: # une seule pièce dans la zone d'étudebksl-nl return debutbksl-nlbksl-nl milieu = (debut + fin) // 2bksl-nl observation = indication(lots, debut, milieu, milieu, fin)bksl-nl if observation == "groupepy-und1":bksl-nl return grospy-undlot(lots, debut, milieu)bksl-nl else:bksl-nl return grospy-undlot(lots, milieu, fin)bksl-nlbksl-nlbksl-nl
On peut réaliser une version itérative de cette fonction, qui repose sur un algorithme de dichotomie.
def gros_lot(lots, debut, fin):
"""
Renvoie le numéro du gros lot dans lots
"""
while debut < fin:
if debut + 1 == fin: # une seule pièce dans la zone d'étude
return debut
milieu = (debut + fin) // 2
observation = indication(lots, debut, milieu, milieu, fin)
if observation == "groupe_1":
fin = milieu
else:
debut = milieu