Adloun

Probleme – Le jeu de soustraction, et sa périodicité

Exercice · niveau 3 (difficile) · informatique (MP2I/MPI), chapitre 27 — Jeux, stratégies et recherche heuristique

Énoncé

On généralise l'exercice 27.2 : l'ensemble des retraits autorisés est un ensemble fini , et celui qui prend la dernière allumette gagne.

Corrigé

1. Le calcul direct. Le graphe biparti est utile pour modéliser, mais la position ne dépend pas du joueur : le jeu est impartial. On calcule donc un seul tableau.


(* gagnante.(n) vaut true si le joueur qui doit jouer avec n allumettes gagne.
   Précondition : s est une liste d'entiers >= 1, nmax >= 0.
   INVARIANT : après le tour n de la boucle, gagnante.(0..n) est correct.
   Complexité : Theta(nmax · |s|). *)
let positions s nmax =
  let gagnante = Array.make (nmax + 1) false in
  for n = 1 to nmax do
    gagnante.(n) <-
      List.exists (fun k -> k <= n && not gagnante.(n - k)) s
  done;
  gagnante

La ligne qui porte tout le jeu est not gagnante.(n - k) : une position est gagnante s'il existe un coup menant à une position perdante pour l'adversaire. C'est le du chapitre, et le y est caché dans la négation — une position est perdante quand tous ses coups mènent à des positions gagnantes. Terminaison : boucle bornée. Correction : par récurrence forte sur , chaque valeur ne dépend que de valeurs d'indice strictement inférieur, déjà calculées.

2. Le cas . Montrons par récurrence forte que est perdante si et seulement si .

La stratégie s'en déduit : retirer , une fonction de la seule position courante — sans mémoire.

3. La périodicité, pour tout fini. Soit . La ligne de code ci-dessus montre que ne dépend que de , c'est-à-dire de la fenêtre des valeurs précédentes. Une telle fenêtre est un mot de : il n'y en a que , donc un nombre fini.

En parcourant , on lit une suite de fenêtres ; par le principe des tiroirs, deux d'entre elles coïncident au plus tard au rang . Or la fenêtre détermine entièrement toute la suite qui la suit. Deux fenêtres égales aux rangs engendrent donc deux suites identiques : la suite est périodique de période à partir de . La borne est grossière — les périodes observées sont très petites — mais elle suffit à établir l'existence.

4. Les vérifications, mesurées.

positions perdantes lecture
ou
ou

Pour , la période est et non : la formule « multiples de » ne se généralise pas.

Et réserve un piège, celui de l'exercice 27.9. La position y est perdante sans être nulle : le joueur ne peut rien retirer, puisque le plus petit retrait vaut , et un joueur qui ne peut pas jouer a perdu. Or si l'on calcule ces positions par un attracteur sur le graphe biparti , avec le code du cours, on obtient une réponse fausse — ou au lieu de ou — parce que l'état est un cul-de-sac de que ce code n'ajoute jamais à l'attracteur. Le défaut de l'exercice 27.9 n'est pas une curiosité : il change la réponse du premier jeu venu. La version directe ci-dessus n'y est pas sujette, car sa disjonction List.exists sur une liste de coups vide vaut false, ce qui est exactement « le joueur bloqué perd ».

C'est le genre de cas limite qu'un jeu de tests doit contenir, et le chapitre chap:discipline explique pourquoi : il est aux frontières du domaine.

Les autres exercices de ce chapitre Le cours du chapitre

Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.