Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,13 @@
" print(f\" {n:2d} | {t} | {motif}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Lecture chiffree — pourquoi la période vaut 4 dans ce tableau.** La colonne Motif aligne un `P` exactement toutes les quatre lignes (`n % 4 == 0` aux lignes 0, 4, 8, 12). Le mecanisme se lit dans les coups disponibles {1, 2, 3} : depuis un multiple de 4, soustraire 1, 2 ou 3 fait sortir du multiple — aucun coup n'y reste ; depuis toute autre position n, le coup qui retranche exactement le reste n mod 4 y ramène. La période 4 n'est donc pas une propriete magique de ce jeu : c'est la longueur du plus grand coup plus un, et la couverture complete des restes qui va avec. La section 5 montrera le contre-exemple utile : pour S({1, 3, 4}) la plus grande valeur de Grundy monte a 3 et la période vaut 7, pas 5 — la periodicite des jeux de soustraction est frequente (observation de la section 5) mais sa longueur ne se deduit pas naivement de max(moves).\n"
]
},
{
"cell_type": "markdown",
"id": "ex-pn-classify-md",
Expand Down Expand Up @@ -413,6 +420,13 @@
" print(f\"{str(heaps):13} | {ns:7} | {t}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Lecture chiffree — cinq lignes, trois mecanismes de la nim-sum.** Les exemples de la sortie se decodent un par un. `(7, 7) | 0 | P` : deux tas identiques s'annulent entierement — chaque bit present deux fois tombe, le second joueur copie et gagne. `(1, 1, 1) | 1 | N` : nombre impair de tas identiques, la parite residuelle laisse 1 — l'annulation par paires est le seul mecanisme, l'orphelin survit. `(1, 2, 3) | 0 | P` et `(3, 5, 6) | 0 | P` : zero sans aucune paire de tas egaux — en binaire, 01 ⊕ 10 ⊕ 11 = 00 et 011 ⊕ 101 ⊕ 110 = 000, chaque colonne de bits tombe pair. Face a `(1, 2, 4) | 7 | N`, aucune colonne ne s'equilibre : 001 ⊕ 010 ⊕ 100 = 111. La nim-sum generalise l'annulation par paires a l'annulation par parite de colonnes.\n"
]
},
{
"cell_type": "markdown",
"id": "8b993aef",
Expand Down Expand Up @@ -499,6 +513,13 @@
" print(f\"Nouvelle nim-sum: {nim_sum(*new_heaps)}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Lecture chiffree — le coup gagnant reconstruit la parite.** Pour `[3, 5, 7]`, la sortie donne `Nim-sum: 1`, puis `Coup gagnant: reduire tas 0 de 3 a 2` et `Nouvelle nim-sum: 0`. Le mecanisme : la nim-sum 1 signale qu'un nombre impair de tas portent le bit 1 ; le solveur cherche le tas dont la reduction peut equilibrer toutes les colonnes a la fois — ici 3 → 2, car 10 ⊕ 101 ⊕ 111 = 000. Le detail qui compte : le coup n'attaque pas le plus gros tas ni le tas le plus desequilibre, il attaque le tas ou la correction est realisable en une seule reduction. Toute position N en possede au moins une (theoreme de Bouton) ; aucune position P n'en possede — c'est exactement la definition.\n"
]
},
{
"cell_type": "markdown",
"id": "ed6eb8a0",
Expand Down Expand Up @@ -576,6 +597,13 @@
" print(f\"mex({s}) = {mex(s)}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Lecture chiffree — le mex complete par le bas.** Les cinq lignes de la sortie se lisent comme une seule regle : `mex(S)` est le plus petit entier absent de S. Les deux lignes piegeuses : `mex({1, 2, 3}) = 0` — l'ensemble ne contient pas zero, donc le mex tombe a zero meme si l'ensemble est « rempli » au-dela ; et `mex({0, 2, 4}) = 1` — le trou le plus bas commande, meme entoure de pairs. `mex(set()) = 0` fixe la base : la position terminale sans successeur recoit Grundy 0, qui est la definition meme d'une P-position. Ce choix de mex (et pas de max, ni de somme) garantit que deux positions aux suites de Grundy differentes ne collisionnent jamais — la propriete que la table de la section suivante exploite.\n"
]
},
{
"cell_type": "markdown",
"id": "52956bb3",
Expand Down Expand Up @@ -670,6 +698,13 @@
" print(f\"{n:2} | {g:14} | {verify}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Lecture chiffree — grundy(nim(n)) = n, ligne par ligne.** La table aligne dix verifications `OK` : pour chaque n de 0 a 9, la valeur de Grundy calculee par la definition recursive (mex des successeurs) vaut exactement n. Autrement dit, un tas de Nim est son propre nimber : Grundy(n) = mex({0, 1, ..., n-1}) = n. La colonne Verification ne verifie pas un resultat numerique isole, elle boucle la definition — chaque ligne certifie que le mex des successeurs de n (qui sont exactement tous les entiers de 0 a n-1) retombe sur n. C'est ce pont identite qui rend le theoreme de Sprague-Grundy de la section suivante concret : chaque tas d'une position de Nim se comporte deja comme son nimber, et la somme de jeux s'annoncera comme un simple XOR de ces valeurs.\n"
]
},
{
"cell_type": "markdown",
"id": "67e27c05",
Expand Down Expand Up @@ -765,6 +800,13 @@
" print(f\"\\nCoup gagnant: tas {i}: {game['heaps'][i]} -> {new_h}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Lecture chiffree — l'analyse complete d'une position en une sortie.** Pour `[4, 7, 9]`, les cinq lignes racontent toute la theorie appliquee. `Valeurs de Grundy: [4, 7, 9]` — chaque tas est son nimber (section precedente). `Nim-sum: 10` — en binaire 100 ⊕ 111 ⊕ 1001 = 1010. `Type: N-position` — la nim-sum non nulle signe le tour gagnant. `Coup gagnant: tas 2: 9 -> 3` — verifier : 100 ⊕ 111 ⊕ 011 = 000, la nouvelle position est une P-position servie au prochain joueur. Le choix 9 → 3 n'est pas unique par principe, mais tout coup gagnant doit reduire un tas exactement a la valeur qui equilibre les deux autres : ici 4 ⊕ 7 = 3, la cible s'impose.\n"
]
},
{
"cell_type": "markdown",
"id": "ex-sg-sum-md",
Expand Down Expand Up @@ -850,6 +892,13 @@
"print(\"Exercice a completer\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Lire la sortie d'un exercice non rempli.** Les lignes `G1=S({1,2}): []`, `G2=S({1,3}): []`, `XOR: []` et `Verification: False` ne sont pas un resultat : les listes vides marquent l'etat du squelette, et le `False` final n'echoue aucun theoreme — il mesure des donnees absentes. Le contrat, pose par l'enonce : remplir les suites de Grundy des deux jeux de soustraction, former le XOR element par element, et verifier la These de Sprague-Grundy sur leur somme — la position combinee doit etre P exactement quand le XOR des nimbers vaut 0. La sortie remplie affichera deux suites (celles de la section 5 pour {1, 3, 4} commencent 0, 1, 0, 1, 2, 3, 2), leur XOR, et un verdict `True` sur chaque position testee.\n"
]
},
{
"cell_type": "markdown",
"id": "b843b282",
Expand Down Expand Up @@ -1062,6 +1111,13 @@
"print(\"Exercice a completer\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Lire la sortie d'un exercice non rempli.** La ligne « Exercice a completer » ouvre l'espace des exemples guides : le premier (jeu de soustraction, enonce en section 6) attend sa solution ici. Le terrain est deja pose — `grundy_subtraction` de la section 5 calcule la suite de Grundy de n'importe quel S(moves), et `classify_123_game` de la section 1 donne le gabarit d'affichage. Une solution remplie montrera la table n / Grundy / Type du jeu demande, ses P-positions alignees, et la lecture de sa periode — le meme geste que la section 5, sur un autre ensemble de coups.\n"
]
},
{
"cell_type": "markdown",
"id": "d4ed1f1d",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
date: '2026-09-18'
by: myia-po-2026:CoursIA
python_sha: 537a49b0b0a2680cadac17caf32c32d37b6c6a03
csharp_sha: 3e53680775740ebf95b2c86dcc5c4800d95cc4ad
content_python_sha: ff665ba30b564c336f8d7b8ac4d7967a08b5522f899066550987bb3aa96f32e3
content_csharp_sha: 433e313c65cbf5f5067e6d06c0c15848678ef1881787e9d25a9e11c1bbaa2df1
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
date: '2026-09-21'
by: myia-po-2026:CoursIA
python_sha: 537a49b0b0a2680cadac17caf32c32d37b6c6a03
csharp_sha: 10d07dbd15e15ac65c442c6165e417bcddaf15ca
content_python_sha: ff665ba30b564c336f8d7b8ac4d7967a08b5522f899066550987bb3aa96f32e3
content_csharp_sha: 980e0230311ad62d97f5a6f37f35a62133414f1299f8135a937db50b5088459c
Loading