{"id":1998,"date":"2025-12-25T08:46:00","date_gmt":"2025-12-25T04:46:00","guid":{"rendered":"https:\/\/iremi.univ-reunion.fr\/?p=1998"},"modified":"2026-04-26T11:23:24","modified_gmt":"2026-04-26T07:23:24","slug":"modelisation-de-sowing-impartial-en-python","status":"publish","type":"post","link":"https:\/\/iremi.univ-reunion.fr\/?p=1998","title":{"rendered":"Mod\u00e9lisation de Sowing impartial en Python"},"content":{"rendered":"\n<p>Le jeu <a href=\"https:\/\/iremi.univ-reunion.fr\/?p=689\">Sowing<\/a> <a href=\"https:\/\/iremi.univ-reunion.fr\/?p=586\">impartial<\/a>, cr\u00e9\u00e9 par John Conway <a href=\"https:\/\/jeffe.cs.illinois.edu\/pubs\/sowing.html\">\u00e0 la fin du XX<sup>e<\/sup> si\u00e8cle<\/a>, a servi de fil conducteur en NSI (premi\u00e8re et terminale) durant l&rsquo;ann\u00e9e scolaire 2025-2026. De nombreux concepts du programme de cette sp\u00e9cialit\u00e9 sont en effet illustr\u00e9s par ce jeu. Voici la r\u00e8gle du jeu :<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>Chaque joueur, \u00e0 son tour,<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>choisit une case non vide,<\/li>\n\n\n\n<li>met dans sa main toutes les graines que contenait la case,<\/li>\n\n\n\n<li>choisit un sens de semis (vers la gauche ou vers la droite),<\/li>\n\n\n\n<li>s\u00e8me, une par une, dans le sens choisi, toutes les graines.<\/li>\n<\/ul>\n\n\n\n<p>Si le semis se termine en dehors du plateau ou dans une case jusque l\u00e0 vide, on a perdu. Le premier qui ne peut plus jouer ainsi, perd le jeu.<\/p>\n<\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\">Algorithmique<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Invariant<\/h3>\n\n\n\n<p>En jouant sur un plateau de 8 cases, tel qu&rsquo;initialement il y a 2 graines par cases, alors la proposition <strong><em>le nombre total de graines est 16<\/em><\/strong> est un invariant. Il sert notamment \u00e0 d\u00e9tecter la triche, mais aussi, lors de la programmation du jeu en Python, d&rsquo;\u00e9ventuels bugs.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Variant<\/h3>\n\n\n\n<p><mark style=\"background-color:#FFEE58\" class=\"has-inline-color has-contrast-color\">L&rsquo;existence d&rsquo;un variant<\/mark> simple et au programme de NSI permettant de prouver la terminaison de ce jeu, <mark style=\"background-color:#FFEE58\" class=\"has-inline-color\">est<\/mark> en 2025 <mark style=\"background-color:#FFEE58\" class=\"has-inline-color\">un probl\u00e8me ouvert<\/mark>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Structures de donn\u00e9es<\/h2>\n\n\n\n<p>Le jeu Sowing impartial est partiellement simulable en SQL, avec deux attributs, le premier \u00e9tant l&rsquo;indice de la case (cl\u00e9 primaire), le second \u00e9tant le nombre de graines contenues dans la case. De m\u00eame, en Python, il est logique de mod\u00e9liser un plateau de Sowing par un tableau d&rsquo;entiers, par exemple ce plateau :<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"720\" height=\"190\" src=\"https:\/\/iremi.univ-reunion.fr\/wp-content\/uploads\/2025\/11\/DSC_0173.jpg\" alt=\"\" class=\"wp-image-1487\" srcset=\"https:\/\/iremi.univ-reunion.fr\/wp-content\/uploads\/2025\/11\/DSC_0173.jpg 720w, https:\/\/iremi.univ-reunion.fr\/wp-content\/uploads\/2025\/11\/DSC_0173-300x79.jpg 300w\" sizes=\"auto, (max-width: 720px) 100vw, 720px\" \/><\/figure>\n\n\n\n<p>est assez logiquement mod\u00e9lis\u00e9 par le tableau <code>[1,2,2,0,2,2,2,1]<\/code>. Cependant, pour pouvoir backtracker (annuler une hypoth\u00e8se), il peut \u00eatre n\u00e9cessaire d&rsquo;utiliser une structure lin\u00e9aire comme les tableaux (type <code>list<\/code> en Python) mais, contrairement \u00e0 iceux, immuable. La mod\u00e9lisation de Sowing en Python peut donc motiver l&rsquo;introduction des tuples, qui, de plus, prennent moins de place en m\u00e9moire. Le fait que les tuples sont immuables permet, \u00e9galement, de s&rsquo;en servir comme cl\u00e9s dans un dictionnaire, qui mod\u00e9lisera le graphe du jeu.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Programmation du jeu en Python<\/h2>\n\n\n\n<p>Pour simuler le jeu, on a besoin de pouvoir choisir au hasard l&rsquo;indice d&rsquo;une case parmi les cases jouables. Aussi le programme commence-t-il par :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>from random import choice<\/code><\/pre>\n\n\n\n<p>et, en Terminale, pour dessiner le graphe du jeu, on fera<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>from graphviz import Digraph<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">R\u00e8gle du jeu<\/h3>\n\n\n\n<p>Une case ne peut \u00eatre jou\u00e9e que si elle existe (indice \u00e0 l&rsquo;int\u00e9rieur du plateau), elle est non vide, et que la case o\u00f9 tombe la derni\u00e8re graine est dans le plateau et n&rsquo;est pas vide :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>def jouable(p,i,s):\n    n = len(p)\n    if i&lt;0:\n        return False\n    if i&gt;=n:\n        return False\n    if p&#091;i]==0:\n        return False\n    if i+s*p&#091;i]&lt;0:\n        return False\n    if i+s*p&#091;i]&gt;=n:\n        return False\n    if p&#091;i+s*p&#091;i]]==0:\n        return False\n    return True<\/code><\/pre>\n\n\n\n<p>La fonction bool\u00e9enne <code>est_jouable<\/code> ci-dessus s&rsquo;applique \u00e0 un plateau <code>p<\/code> (un tuple), un indice <code>i<\/code> (un entier) et un sens <code>s<\/code> (un entier \u00e9gal \u00e0 1 ou -1), et dit si la case d&rsquo;indice <code>i<\/code> dans le plateau <code>p<\/code> est jouable en semant dans le sens <code>s<\/code>. L&rsquo;ordre dans lequel s&rsquo;effectuent les tests garantit que chaque expression a un sens au moment o\u00f9 on l&rsquo;\u00e9value (sinon on aurait quitt\u00e9 la fonction avec un <code>return<\/code>).<\/p>\n\n\n\n<p>La fonction <code>est_jouable<\/code> sert \u00e0 d\u00e9finir une fonction <code>jouables<\/code>, qui, \u00e0 un plateau <code>p<\/code>, associe la liste des indices des cases jouables sur ce plateau :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>def jouables(p):\n    return &#091;i for i in range(len(p)) if jouable(p,i,-1) or jouable(p,i,1)]\n<\/code><\/pre>\n\n\n\n<p>Le jeu est fini lorsque plus aucun indice n&rsquo;est jouable, donc on cherche \u00e0 obtenir une telle situation et le plateau est alors consid\u00e9r\u00e9 comme gagnant :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>def gagnant(p):\n    return jouables(p)==&#091;]<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Semis<\/h3>\n\n\n\n<p>Pour effectuer un semis, on a besoin d&rsquo;un objet mutable, alors on convertit le plateau <code>p<\/code> en une liste <code>q<\/code>, que l&rsquo;on modifie en semant les graines, et que l&rsquo;on convertit en tuple \u00e0 la fin du semis. Les graines sont sem\u00e9es une par une :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>def jouer(p,i,s):\n    assert jouable(p,i,s), \"tricheur !\"\n    q = list(p)\n    graines = q&#091;i]\n    q&#091;i] = 0\n    while graines:\n        i += s\n        graines -= 1\n        q&#091;i] += 1\n    return tuple(q)<\/code><\/pre>\n\n\n\n<p>L&rsquo;expression <code>graines<\/code> (le nombre de graines restant \u00e0 semer) est un variant (gr\u00e2ce \u00e0 <code>graines -= 1<\/code>) qui prouve qu&rsquo;un tour de jeu dure un temps fini (ce n&rsquo;est pas n\u00e9cessairement le cas au <a href=\"https:\/\/iremi.univ-reunion.fr\/?p=1009\">katro<\/a>). C&rsquo;est pour une partie compl\u00e8te du jeu, qu&rsquo;on ne dispose pas de variant.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Liste d&rsquo;adjacence<\/h3>\n\n\n\n<p>Pour la construction du graphe du jeu mais aussi pour l&rsquo;affichage des \u00e9tapes, on aura besoin d&rsquo;une fonction qui, \u00e0 un plateau <code>p<\/code>, associe ses enfants (les plateaux <code>q<\/code> tels qu&rsquo;il y a un arc de <code>p<\/code> vers <code>q<\/code> dans le graphe orient\u00e9 du jeu) :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>def enfants(p):\n    tab = &#091;jouer(p,i,-1) for i in range(len(p)) if jouable(p,i,-1)]\n    tab += &#091;jouer(p,i,1) for i in range(len(p)) if jouable(p,i,1)]\n    return tab<\/code><\/pre>\n\n\n\n<p>Cette fois-ci, on renvoie un objet mutable (un tableau) ce qui permet d&rsquo;utiliser la m\u00e9thode <code>append<\/code> pour construire ledit tableau.<\/p>\n\n\n\n<p>Il sera int\u00e9ressant, pour afficher le d\u00e9roul\u00e9 du jeu, de pouvoir calculer l&rsquo;indice de la case jou\u00e9e, et le sens du semis, \u00e0 partir de la connaissance de l&rsquo;ancien plateau <code>p<\/code> et du nouveau plateau <code>q<\/code> :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>def indice(p,q):\n    return &#091;i for i in range(len(p)) if p&#091;i]&gt;q&#091;i]]&#091;0]\n\ndef sens(p,q):\n    i = indice(p,q)\n    if i&gt;0 and p&#091;i-1]&lt;q&#091;i-1]:\n        return -1\n    if i&lt;len(p)-1 and p&#091;i+1]&lt;q&#091;i+1]:\n        return 1<\/code><\/pre>\n\n\n\n<p>La case jou\u00e9e est la seule qui soit devenue vide (c&rsquo;est-\u00e0-dire dont l&rsquo;ancienne valeur soit sup\u00e9rieure \u00e0 la nouvelle valeur qui est z\u00e9ro), et le sens est celui selon lequel la case voisine a plus de graines qu&rsquo;avant.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Distance entre plateaux<\/h3>\n\n\n\n<p>Tr\u00e8s peu d&rsquo;\u00e9l\u00e8ves de Premi\u00e8re se souviennent de la formule donnant la distance euclidienne entre deux points du plan rep\u00e9r\u00e9. De plus, des probl\u00e8mes d&rsquo;approximation se posent avec les flottants. Aussi a-t-on choisi ici, la <a href=\"https:\/\/fr.wikipedia.org\/wiki\/Distance_de_Manhattan\">distance de Manhattan<\/a> entre plateaux :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>def d(p,q):\n    '''distance de Manhattan\n    entre deux plateaux p et q.\n    p et q sont deux tuples.\n    '''\n    assert len(p)==len(q)\n    return sum(&#091;abs(p&#091;i]-q&#091;i]) for i in range(len(p))])<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Algorithme des k plus proches voisins<\/h2>\n\n\n\n<p>R\u00e9capitulons : on sait classer les plateaux entre gagnants et non gagnants, et on dispose d&rsquo;une distance entre plateaux. Pour aider un joueur \u00e0 choisir la case \u00e0 jouer (ce qu&rsquo;on appelle une strat\u00e9gie), on consid\u00e8re, quelque peu arbitrairement, qu&rsquo;on a int\u00e9r\u00eat \u00e0 viser un plateau qui a l&rsquo;air gagnant, c&rsquo;est-\u00e0-dire dont la distance \u00e0 un (ou plusieurs) plateaux connus pour \u00eatre gagnants, est petite.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Liste tri\u00e9e par distances<\/h3>\n\n\n\n<p>On associe donc, \u00e0 un plateau <code>p<\/code> (un tuple d&rsquo;entiers), une liste <code>tab<\/code> de tuples dont le premier \u00e9l\u00e9ment est la distance entre <code>p<\/code> et l&rsquo;enfant, et le deuxi\u00e8me \u00e9l\u00e9ment est l&rsquo;enfant lui-m\u00eame. Le tri est alors fait selon les distances :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>def voisins(p):\n    return sorted(&#091;(d(p,q),q) for q in enfants(p)])<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Majorit\u00e9 parmi les k plus proches voisins<\/h3>\n\n\n\n<p>Un entier positif <code>k<\/code> \u00e9tant donn\u00e9, on regarde l&rsquo;\u00e9tat (gagnant ou non) de l&rsquo;enfant m\u00e9dian (c&rsquo;est l&rsquo;\u00e9tat majoritaire parmi les <code>k<\/code> plus proches voisins de <code>p<\/code>), et on consid\u00e8re que c&rsquo;est probablement l&rsquo;\u00e9tat de <code>p<\/code> :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>def major(k,p):\n    kppv = voisins(p)&#091;:k]\n    etats = &#091;gagnant(q&#091;1]) for q in kppv]\n    etats.sort()\n    if etats:\n        return etats&#091;:k\/\/2]&#091;-1]<\/code><\/pre>\n\n\n\n<p>La strat\u00e9gie propos\u00e9e consiste alors \u00e0 regarder, parmi les enfants du plateau <code>p<\/code>, lesquels ont l&rsquo;air (selon kNN) d&rsquo;\u00eatre gagnants, et lesquels n&rsquo;en ont pas l&rsquo;air. Ensuite, s&rsquo;il y a au moins un plateau ayant l&rsquo;air gagnant, on en choisit un au hasard parmi les plateaux ayant l&rsquo;air gagnants, sinon on choisit au hasard un autre plateau :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>def strat(k,p):\n    gagnants = &#091;]\n    perdants = &#091;]\n    for e in enfants(p):\n        if major(k,e):\n            gagnants.append(e)\n        else:\n            perdants.append(e)\n    if gagnants:\n        return choice(gagnants)\n    else:\n        return choice(perdants)<\/code><\/pre>\n\n\n\n<p>Le choix de <code>k<\/code> est fait empiriquement. Comme il y a souvent moins de 4 enfants, et qu&rsquo;un ballotage est impossible s&rsquo;il y a un nombre impair d&rsquo;\u00e9lecteurs, la valeur de 3 para\u00eet raisonnable. On dispose maintenant des fonctions n\u00e9cessaires pour simuler une partie de ce jeu, l&rsquo;IA jouant contre elle-m\u00eame (comme <a href=\"https:\/\/fr.wikipedia.org\/wiki\/AlphaZero\">alpha zero<\/a>) :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>def simulpartie(p):\n    k = 3\n    plateau = p\n    joueur = 0\n    nom = &#091;'Sud','Nord']\n    nomsens = {-1: 'gauche', 1: 'droite'}\n    while not gagnant(plateau):\n        print(plateau)\n        print('C\\'est \u00e0',nom&#091;joueur],'de jouer.')\n        q = strat(k,plateau)\n        print(nom&#091;joueur],'joue la case d\\'indice',indice(plateau,q),'vers la',nomsens&#091;sens(plateau,q)],'.')\n        plateau = q\n        joueur = 1-joueur\n        if gagnant(plateau):\n            print(plateau)\n            print(nom&#091;joueur],'ne pouvant plus semer, a perdu.')<\/code><\/pre>\n\n\n\n<p>La strat\u00e9gie choisit un enfant du plateau, et pour l&rsquo;affichage on calcule la mani\u00e8re dont on peut passer du plateau actuel au plateau suivant, \u00e0 l&rsquo;aide des fonctions <code>indice<\/code> et <code>sens<\/code>. En fait la strat\u00e9gie ressemble plut\u00f4t \u00e0 une tactique :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&gt;&gt;&gt; simulpartie((1,2,2,1,1,2,2,1))\n(1, 2, 2, 1, 1, 2, 2, 1)\nC'est \u00e0 Sud de jouer.\nSud joue la case d'indice 3 vers la gauche .\n(1, 2, 3, 0, 1, 2, 2, 1)\nC'est \u00e0 Nord de jouer.\nNord joue la case d'indice 5 vers la droite .\n(1, 2, 3, 0, 1, 0, 3, 2)\nC'est \u00e0 Sud de jouer.\nSud joue la case d'indice 0 vers la droite .\n(0, 3, 3, 0, 1, 0, 3, 2)\nC'est \u00e0 Nord de jouer.\nNord joue la case d'indice 1 vers la droite .\n(0, 0, 4, 1, 2, 0, 3, 2)\nC'est \u00e0 Sud de jouer.\nSud joue la case d'indice 3 vers la gauche .\n(0, 0, 5, 0, 2, 0, 3, 2)\nC'est \u00e0 Nord de jouer.\nNord joue la case d'indice 4 vers la gauche .\n(0, 0, 6, 1, 0, 0, 3, 2)\nC'est \u00e0 Sud de jouer.\nSud joue la case d'indice 3 vers la gauche .\n(0, 0, 7, 0, 0, 0, 3, 2)\nNord ne pouvant plus semer, a perdu.<\/code><\/pre>\n\n\n\n<p>L&rsquo;\u00e9criture format\u00e9e, n&rsquo;\u00e9tant pas au programme, n&rsquo;a pas \u00e9t\u00e9 utilis\u00e9e ici. Dans l&rsquo;exemple ci-dessus, les joueurs n&rsquo;ont pas jou\u00e9 au mieux, car sinon Nord aurait gagn\u00e9 (nombre de Grundy nul) :<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"661\" height=\"536\" src=\"https:\/\/iremi.univ-reunion.fr\/wp-content\/uploads\/2026\/04\/Capture-decran-du-2026-04-17-08-03-17.png\" alt=\"\" class=\"wp-image-2007\" srcset=\"https:\/\/iremi.univ-reunion.fr\/wp-content\/uploads\/2026\/04\/Capture-decran-du-2026-04-17-08-03-17.png 661w, https:\/\/iremi.univ-reunion.fr\/wp-content\/uploads\/2026\/04\/Capture-decran-du-2026-04-17-08-03-17-300x243.png 300w\" sizes=\"auto, (max-width: 661px) 100vw, 661px\" \/><\/figure>\n\n\n\n<p>Pour comparer avec la suite, on reessaye avec un plateau plus simple :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&gt;&gt;&gt; simulpartie((2,2,2,2))\n(2, 2, 2, 2)\nC'est \u00e0 Sud de jouer.\nSud joue la case d'indice 3 vers la gauche .\n(2, 3, 3, 0)\nC'est \u00e0 Nord de jouer.\nNord joue la case d'indice 0 vers la droite .\n(0, 4, 4, 0)\nSud ne pouvant plus semer, a perdu.<\/code><\/pre>\n\n\n\n<p>L\u00e0 encore, les joueurs n&rsquo;ont pas jou\u00e9 au mieux, puisqu&rsquo;il y a une strat\u00e9gie gagnante pour Sud, comme on le verra plus bas (le nombre de Grundy est \u00e9gal \u00e0 2).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">En Terminale<\/h2>\n\n\n\n<p>On peut en fait trouver la strat\u00e9gie gagnante, en explorant le graphe du jeu. Celui-ci est d\u00e9fini en Terminale par un dictionnaire de listes d&rsquo;adjacences :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>def graphe(p):\n    dico = {p: enfants(p)}\n    d = {}\n    while len(d) != len(dico):\n        d = dico.copy()\n        for k,v in d.items():\n            for q in v:\n                if q not in d:\n                    dico&#091;q] = enfants(q)\n    return dico<\/code><\/pre>\n\n\n\n<p>On a besoin d&rsquo;une copie <code>d<\/code> du dictionnaire parce qu&rsquo;il est (heureusement) impossible de modifier un objet mutable (ici un dictionnaire) pendant qu&rsquo;on le parcourt.<\/p>\n\n\n\n<p>Pour obtenir un dessin du graphe, on utilise l&rsquo;objet <code>Digraph<\/code> du module <code>graphviz<\/code> :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>def dessin(p):\n    digraph = Digraph(format='pdf')\n    dico = graphe(p)\n    for k,v in dico.items():\n        for y in v:\n            digraph.edge(str(k),str(y))\n    return digraph<\/code><\/pre>\n\n\n\n<p>La fonction parcourt le dictionnaire des listes d&rsquo;adjacences, et pour chaque couple (k,y) de plateaux tels que l&rsquo;arc (k,y) fait partie du graphe, cr\u00e9e l&rsquo;arc dans le graphe orient\u00e9. Ensuite la commande<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&gt;&gt;&gt; dessin((2,2,2,2)).render('exple1')<\/code><\/pre>\n\n\n\n<p>cr\u00e9e le graphe suivant :<\/p>\n\n\n\n<div data-wp-interactive=\"core\/file\" class=\"wp-block-file\"><object data-wp-bind--hidden=\"!state.hasPdfPreview\" hidden class=\"wp-block-file__embed\" data=\"https:\/\/iremi.univ-reunion.fr\/wp-content\/uploads\/2026\/04\/exple1.pdf\" type=\"application\/pdf\" style=\"width:100%;height:320px\" aria-label=\"Contenu embarqu\u00e9 exple1.\"><\/object><a id=\"wp-block-file--media-147dc11a-9af7-4f02-a2c6-7028714cc0fa\" href=\"https:\/\/iremi.univ-reunion.fr\/wp-content\/uploads\/2026\/04\/exple1.pdf\">exple1<\/a><a href=\"https:\/\/iremi.univ-reunion.fr\/wp-content\/uploads\/2026\/04\/exple1.pdf\" class=\"wp-block-file__button wp-element-button\" download aria-describedby=\"wp-block-file--media-147dc11a-9af7-4f02-a2c6-7028714cc0fa\">T\u00e9l\u00e9charger<\/a><\/div>\n\n\n\n<p>o\u00f9 on voit que, si Sud avait jou\u00e9 (3,3,0,2) plut\u00f4t que (2,3,3,0) il aurait gagn\u00e9, quoi que fasse Nord ensuite.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Le jeu Sowing impartial, cr\u00e9\u00e9 par John Conway \u00e0 la fin du XXe si\u00e8cle, a servi de fil conducteur en NSI (premi\u00e8re et terminale) durant l&rsquo;ann\u00e9e scolaire 2025-2026. De nombreux concepts du programme de cette sp\u00e9cialit\u00e9 sont en effet illustr\u00e9s par ce jeu. Voici la r\u00e8gle du jeu : Algorithmique Invariant En jouant sur un [&hellip;]<\/p>\n","protected":false},"author":6,"featured_media":712,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9,12,10],"tags":[35],"coauthors":[54],"class_list":["post-1998","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-algorithmes-programmation-et-langages","category-jeux-mathematiques","category-machines-information-codage","tag-nsi"],"_links":{"self":[{"href":"https:\/\/iremi.univ-reunion.fr\/index.php?rest_route=\/wp\/v2\/posts\/1998","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/iremi.univ-reunion.fr\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/iremi.univ-reunion.fr\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/iremi.univ-reunion.fr\/index.php?rest_route=\/wp\/v2\/users\/6"}],"replies":[{"embeddable":true,"href":"https:\/\/iremi.univ-reunion.fr\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1998"}],"version-history":[{"count":16,"href":"https:\/\/iremi.univ-reunion.fr\/index.php?rest_route=\/wp\/v2\/posts\/1998\/revisions"}],"predecessor-version":[{"id":2093,"href":"https:\/\/iremi.univ-reunion.fr\/index.php?rest_route=\/wp\/v2\/posts\/1998\/revisions\/2093"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/iremi.univ-reunion.fr\/index.php?rest_route=\/wp\/v2\/media\/712"}],"wp:attachment":[{"href":"https:\/\/iremi.univ-reunion.fr\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1998"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/iremi.univ-reunion.fr\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1998"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/iremi.univ-reunion.fr\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1998"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/iremi.univ-reunion.fr\/index.php?rest_route=%2Fwp%2Fv2%2Fcoauthors&post=1998"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}