Aller au contenu

Le jeu de la ronde⚓︎

Règle du jeu⚓︎

Soit \(n\) un entier strictement positif.

\(n\) enfants jouent dans une cour de récréation : ils se placent en rond et choisissent au hasard l’un d’entre eux.

A partir de là, la règle est simple :

  • Le premier enfant tape sur l’épaule de son voisin de gauche : celui-ci est éliminé. Au début l’enfant 1 élimine donc l’enfant 2
  • On passe à l’enfant restant suivant et l’on recommence : il élimine celui situé à sa gauche. Dans l’exemple, l’enfant 3 élimine le 4
  • On continue encore et encore jusqu’à ce qu’il ne reste plus qu’un seul enfant : c’est le gagnant !

Le jeu de la ronde

Dans le cas où \(n=13\) (comme sur la figure), le gagnant est l’enfant \(11\).

Le but du jeu est simple : où se placer pour gagner ?

Méthode⚓︎

Dans cet exercice nous allons utiliser un tableau de booléen nommé joueurs dans lequel chaque valeur indique que le joueur concerné est encore en jeu (True) ou a déjà été éliminé (False).

Attention

Les indices des liste Python étant comptabilisés à partir de 0, avoir joueurs[2] égal à False signifie que le joueur n°3 a été éliminé.

Ce tableau sera initialisé avec autant de valeurs True qu'il y a de joueurs.

La partie se déroulera ainsi :

  • On garde trace de l'indice du joueur qui doit jouer
  • On cherche dans le tableau l'indice du prochain joueur encore en jeu
  • On "élimine" ce joueur
  • On cherche l'indice du prochain joueur encore en jeu : ce sera à lui de jouer

Ces différentes étapes continuent jusqu'à ce qu'il ne reste plus qu'un seul joueur encore en jeu.

Au travail !⚓︎

Vous devez écrire deux fonctions :

  • indice_prochain_True prend en argument une liste de booléens ainsi qu'un indice et renvoie l'indice de la prochaine valeur de la liste égale à True. On prendra soin de "boucler" les indices : si celui-ci dépasse la longueur de la liste, on le ramène à 0.

    On garantit que la liste booleens contient au moins une valeur True.

Exemples

🐍 Console Python
>>> booleens = [True, True, False, True, False]
>>> indice_prochain_True(booleens, 0)
1
>>> indice_prochain_True(booleens, 1)
3
>>> indice_prochain_True(booleens, 3)
0
  • gagnant prend en argument le nombre de joueurs au début de la partie et renvoie la position du joueur gagnant

Exemples

🐍 Console Python
>>> gagnant(1)
1
>>> gagnant(5)
3
>>> gagnant(13)
11
# Testsbksl-nlbksl-nl# Testsbksl-nl# Tests de la fonction indicepy-undprochainpy-undTruebksl-nlbooleens = [True, True, False, True, False]bksl-nlassert indicepy-undprochainpy-undTrue(booleens, 0) == 1bksl-nlassert indicepy-undprochainpy-undTrue(booleens, 1) == 3bksl-nlassert indicepy-undprochainpy-undTrue(booleens, 3) == 0bksl-nlbksl-nl# Tests de la fonction gagnantbksl-nlassert gagnant(1) == 1bksl-nlassert gagnant(5) == 3bksl-nlassert gagnant(13) == 11bksl-nlbksl-nl# Tests supplémentairesbksl-nlbooleens = [True, True, False, False]py-str10bksl-nlfor i in range(len(booleens)):bksl-nl assert indicepy-undprochainpy-undTrue(booleens, i) == i + \bksl-nl 1 if i % 4 == 0 else 4py-str(i//4)+1bksl-nl# Remarque : Si n = 2^m + l et 0 <= l < 2^m, alors gagnant(n) = 2l+1bksl-nlgagnants = {2: 1, 3: 3, 4: 1, 5: 3, 6: 5, 7: 7, 8: 1, 9: 3, 10: 5, 11: 7,bksl-nl 12: 9, 13: 11, 14: 13, 15: 15, 16: 1, 17: 3, 18: 5, 19: 7, 20: 9,bksl-nl 21: 11, 22: 13, 23: 15, 24: 17, 25: 19, 26: 21, 27: 23, 28: 25,bksl-nl 29: 27, 30: 29, 31: 31, 32: 1, 33: 3, 34: 5, 35: 7, 36: 9, 37: 11,bksl-nl 38: 13, 39: 15, 40: 17, 41: 19, 42: 21, 43: 23, 44: 25, 45: 27,bksl-nl 46: 29, 47: 31, 48: 33, 49: 35, 50: 37, 51: 39, 52: 41, 53: 43,bksl-nl 54: 45, 55: 47, 56: 49, 57: 51, 58: 53, 59: 55, 60: 57, 61: 59,bksl-nl 62: 61, 63: 63, 64: 1, 65: 3, 66: 5, 67: 7, 68: 9, 69: 11, 70: 13,bksl-nl 71: 15, 72: 17, 73: 19, 74: 21, 75: 23, 76: 25, 77: 27, 78: 29,bksl-nl 79: 31, 80: 33, 81: 35, 82: 37, 83: 39, 84: 41, 85: 43, 86: 45,bksl-nl 87: 47, 88: 49, 89: 51, 90: 53, 91: 55, 92: 57, 93: 59, 94: 61,bksl-nl 95: 63, 96: 65, 97: 67, 98: 69, 99: 71}bksl-nlfor nbpy-undjoueurs, vainqueur in gagnants.items():bksl-nl assert gagnant(bksl-nl nbpy-undjoueurs) == vainqueur, f"Erreur pour {nbpy-undjoueurs} joueurs"bksl-nlbksl-nl ∞/∞

def indicepy-undprochainpy-undTrue(booleens, indice):bksl-nl taille = len(booleens)bksl-nlbksl-nl while True:bksl-nl indice += ...bksl-nl if indice == taille:bksl-nl ...bksl-nl if booleens[...]:bksl-nl return ...bksl-nlbksl-nlbksl-nldef gagnant(nbpy-undjoueurs):bksl-nl joueurs = [True for py-und in range(nbpy-undjoueurs)]bksl-nl indicepy-undjoueur = ...bksl-nl while ...:bksl-nl prochain = ...bksl-nl joueurs[prochain] = Falsebksl-nl indicepy-undjoueur = ...bksl-nl nbpy-undjoueurs = ...bksl-nlbksl-nl return ...bksl-nlbksl-nlbksl-nl# Testsbksl-nl# Tests de la fonction indicepy-undprochainpy-undTruebksl-nlbooleens = [True, True, False, True, False]bksl-nlassert indicepy-undprochainpy-undTrue(booleens, 0) == 1bksl-nlassert indicepy-undprochainpy-undTrue(booleens, 1) == 3bksl-nlassert indicepy-undprochainpy-undTrue(booleens, 3) == 0bksl-nlbksl-nl# Tests de la fonction gagnantbksl-nlassert gagnant(1) == 1bksl-nlassert gagnant(5) == 3bksl-nlassert gagnant(13) == 11bksl-nlbksl-nldef indicepy-undprochainpy-undTrue(booleens, indice):bksl-nl taille = len(booleens)bksl-nl while True:bksl-nl indice += 1bksl-nl if indice == taille:bksl-nl indice = 0bksl-nl if booleens[indice]:bksl-nl return indicebksl-nlbksl-nlbksl-nldef gagnant(nbpy-undjoueurs):bksl-nl joueurs = [True for py-und in range(nbpy-undjoueurs)]bksl-nl indicepy-undjoueur = 0bksl-nl while nbpy-undjoueurs > 1:bksl-nl prochain = indicepy-undprochainpy-undTrue(joueurs, indicepy-undjoueur)bksl-nl joueurs[prochain] = Falsebksl-nl indicepy-undjoueur = indicepy-undprochainpy-undTrue(joueurs, prochain)bksl-nl nbpy-undjoueurs -= 1bksl-nlbksl-nl return indicepy-undjoueur+1bksl-nlbksl-nlbksl-nl# Testsbksl-nl# Tests de la fonction indicepy-undprochainpy-undTruebksl-nlbooleens = [True, True, False, True, False]bksl-nlassert indicepy-undprochainpy-undTrue(booleens, 0) == 1bksl-nlassert indicepy-undprochainpy-undTrue(booleens, 1) == 3bksl-nlassert indicepy-undprochainpy-undTrue(booleens, 3) == 0bksl-nlbksl-nl# Tests de la fonction gagnantbksl-nlassert gagnant(1) == 1bksl-nlassert gagnant(5) == 3bksl-nlassert gagnant(13) == 11bksl-nlbksl-nl

A

Commentaires⚓︎

{{ IDE('exo_corr') }}

Comme on est sûr que la liste booleens contient au moins une valeur True, on peut construire la fonction autour de while True: tout en ayant la certitude de sortir de la boucle.

Dans la boucle :

  • on incrément indice et l'on vérifie qu'il ne dépasse pas la taille de la liste (si oui, on lui donne la valeur 0)
  • on teste si booleens[indice] est égal à True. Si c'est le cas on renvoie la valeur de indice

Dans la fonction gagnant, on commence par créer la liste de booléens, tous égaux à True (tous les joueurs sont encore en jeu).

On désigne le joueur dont c'est le tour avec indice_joueur0 au début pour le joueur 1).

On lance ensuite la partie qui continue jusqu'à ce que le nombre de joueurs soit égal à 1.

A chaque étape :

  • on cherche l'indice du prochain joueur encore en jeu
  • on l'élimine
  • on passe au joueur suivant en effectuant une nouvelle recherche

A la fin de la fonction, on renvoie indice_joueur+1 afin de tenir compte du décalage entre les indices dans la liste et les numéros des joueurs.

Z

Retour en haut de la page