• Aucun résultat trouvé

ou sous le nom de "Juniper Green", du nom de l'école de son auteur, et "popularisé&#34

N/A
N/A
Protected

Academic year: 2022

Partager "ou sous le nom de "Juniper Green", du nom de l'école de son auteur, et "popularisé&#34"

Copied!
6
0
0

Texte intégral

(1)

E453 – Une belle joute [***** à la main]

Diophante choisit un entier n puis Zig et Puce s’adonnent à une joute de calcul mental qui obéit aux règles suivantes :

1) Le premier joueur annonce un nombre pair inférieur ou égal à n,

2) A tour de rôle chaque joueur doit annoncer un nombre parmi les multiples et les diviseurs du nombre choisi par son adversaire et inférieur ou égal à n,

3) Un nombre ne peut être prononcé qu’une seule fois.

Le perdant est le joueur qui ne trouve plus de multiples ou de diviseurs du nombre précédemment choisi.

Diophante choisit successivement les valeurs n = 20,50,100,120,1000,2020 pour six parties consécutives n°1,2,3,4,5,6. Zig joue en premier dans les parties n°1,3,5 et Puce en premier dans les parties n°2,4,6.

On suppose qu’au premier tour de chaque partie, Zig comme Puce choisissent l’entier pair qui optimise leurs chances de gain et qu’aux tours suivants l’un et l’autre jouent au mieux en vue de ne pas être le perdant.

Déterminer les vainqueurs des six parties.

Solution proposée par Daniel Collignon

Ce jeu, magnifique par ses règles simples et la difficulté de percevoir le cas général, probablement en raison de son lien avec les nombres premiers, est connu en tant que "Factors and Multiples Game" ou sous le nom de "Juniper Green", du nom de l'école de son auteur, et "popularisé" par Ian Stewart.

J'ai réalisé un court programme en Python (cf pj, où j'ai sorti le cas 2n=2, de manière à utiliser

"l'accélérateur" 1 perdant pour celui qui le joue car il existe toujours un nombre premier p tel que n<p<2n pour n>1, d'après le postulat de Bertrand) : il m'a permis de déceler les valeurs où le joueur 1 gagne, mais le nombre de cas à examiner explose au-dessus de 50

Il permet quand même de montrer que 20 et 50 sont gagnants pour celui qui commence, même s'il conviendrait d'expliciter davantage la stratégie.

Remarque : une fois n'est pas coutume, la suite

3,8,12,13,14,16,17,20,24,27,30,31,33,34,36,37,38,39,40,41,44,48,49,50,52,53..., ni son complémentaire, ne semblent connues de l'OEIS.

- Cas n°1 n = 20

Réponse : 1er joueur vainqueur avec premier coup = 12 Rappel :

1 est perdant pour celui qui le joue : 1-19 14 est perdant pour celui qui le joue : 14-7-1

Du coup pour simplifier l'arbre, on ne mentionne pas ces cas.

Les parties listées se poursuivraient donc soit avec 1, soit avec 14 pour le joueur 2.

Il est illustré ci-après le fait que le joueur 1 gagne avec 16 comme premier coup.

On factorise certains préfixes : B = 16-A-20 avec A = 2-8-4, 4-8-2 ou 8-4-2 B-5-10

B-10-5-15-3-6-12 B-10-5-15-3-9-18-6-12 B-10-5-15-3-12-6-18-9 B-10-5-15-3-18-9 Pour la suite, C = 16-8-4 C-12-6-2-18-3-9

C-12-6-2-18-9-3-15-5-10-20 C-12-6-2-18-9-3-15-5-20-10 C-12-6-3-15-5-10-2-20 C-12-6-3-15-5-10-20-2-18-9 C-12-6-18-9-3-15-5-10-2-20 C-20-10-2-12-3-9-18-6 C-20-10-2-12-6-3-9-18 C-20-10-2-12-6-3-15-5 C-20-10-2-12-6-3-18-9 C-20-10-5-15-3-12-2-6-18-9

(2)

C-20-10-5-15-3-12-6-2-18-9

Avec comme premier coup 12 pour le cas n=20, un programme écrit en langage Python (cf annexe) décrit en 26 lignes les parties possibles en retardant la séquence finale 1, 19

[12, 2, 6, 3, 15, 5, 10, 20, 4, 8, 16]

[12, 2, 6, 3, 15, 5, 10, 20, 4, 16, 8]

[12, 2, 6, 18, 9, 3, 15, 5, 10, 20, 4, 8, 16]

[12, 2, 6, 18, 9, 3, 15, 5, 10, 20, 4, 16, 8]

[12, 3, 9, 18, 6, 2, 8, 4, 16]

[12, 3, 9, 18, 6, 2, 8, 16, 4, 20, 10, 5, 15]

[12, 4, 8, 2, 16]

[12, 4, 8, 16, 2, 6, 18, 3, 9]

[12, 4, 8, 16, 2, 6, 18, 9, 3, 15, 5, 10, 20]

[12, 4, 8, 16, 2, 6, 18, 9, 3, 15, 5, 20, 10]

[12, 4, 8, 16, 2, 10, 20, 5, 15, 3, 9, 18, 6]

[12, 4, 8, 16, 2, 14, 7]

[12, 4, 8, 16, 2, 18, 9, 3, 6]

[12, 4, 8, 16, 2, 20, 10, 5, 15, 3, 9, 18, 6]

[12, 6, 3, 9, 18, 2, 8, 4, 16]

[12, 6, 3, 9, 18, 2, 8, 16, 4, 20, 10, 5, 15]

[12, 6, 3, 15, 5, 10, 20, 2, 8, 4, 16]

[12, 6, 3, 15, 5, 10, 20, 2, 8, 16, 4]

[12, 6, 3, 15, 5, 10, 20, 4, 8, 2, 16]

[12, 6, 3, 15, 5, 10, 20, 4, 8, 16, 2, 14, 7]

[12, 6, 3, 15, 5, 10, 20, 4, 8, 16, 2, 18, 9]

[12, 6, 3, 15, 5, 20, 10, 2, 8, 4, 16]

[12, 6, 3, 15, 5, 20, 10, 2, 8, 16, 4]

[12, 6, 3, 18, 9]

- Cas n°2 n =50

Réponse : 1er joueur vainqueur avec premier coup = 26 Il faut éviter 34:17:1:47, 38:19:1:47 ou 46:23:1:47

Il faut également éviter 50 comme premier coup, en raison de : 50:25:1:47

50:25:5:35:1:47 50:25:5:35:7:49:1:47

Le même programme Python (cf annexe) permet d’arriver à des résultats similaires à ceux du cas n = 20, mais il faut 2899 lignes pour décrire l'arbre (en retardant la séquence finale 1, 47) avec comme premier coup 26. Voir fichier pdf.

-Cas n°3 et n°4 n= 100 et 120

Ces deux cas sont traités dans le document de l'APMEP. https://www.apmep.fr/IMG/pdf/AAA04049.pdf -Cas n°5 n = 1010

Le premier joueur choisit 502 et il y a 2 débuts possibles avant de rejoindre 3 : 502=2*251:2

514=2*257:257 771=3*257:3 ou

502=2*251:251 753=3*251:3

Ensuite pour repousser au maximum le passage par 1

(3)

597=3*199:199 995=5*199:5 695=5*139:139 973=7*139:7 511=7*73:73 949=13*73:13 559=13*43:43 989=23*43:23 529=23*23:1

Le coup de grâce : tout nombre premier entre 503 et 997

Cas n°6 n = 2020

Le premier joueur choisit 1018 et il y a 2 débuts possibles avant de rejoindre 3 : 1018=2*509:2

1042=2*521:521 1563=3*521:3 ou

1018=2*509:509 1527=3*509:3

Ensuite pour repousser au maximum le passage par 1

1203=3*401:401 2005=5*401:5 1415=5*283:283 1981=7*283:7 1057=7*151:151 1963=13*151:13 1079=13*83:83 1909=23*83:23 1219=23*53:53 1961=37*53:37 1369=37*37:1

Le coup de grâce : tout nombre premier entre 1013 et 2017

Références :

https://fr.wikipedia.org/wiki/Juniper_Green_(jeu)

https://irem.univ-reunion.fr/IMG/pdf/article_juniper_green_boris_laval_olivier_sicard-2.pdf http://dspace.rri.res.in/bitstream/2289/1349/3/Juniper%20green.pdf

(4)

Annexe

Programme Python

#n gagnant pour celui qui joue en premier :

3,8,12,13,14,16,17,20,24,27,30,31,33,34,36,37,38,39,40,41,44,48,49,50,52,53, ...

#pour n = 20, premier coup perdant pour 14

#pour n = 50, premier coup perdant pour 34, 38, 46 et 50

#Paramètre à modifier

#n maximal (le temps de calcul explose au-delà de 50) max=50

######

#Pour mesurer le temps d'exécution d'une partie de code

#Importer la fonction à l'aide de

#from timeit import default_timer as timer

#Puis à l'endroit adéquat

# start = timer()

# ...

# end = timer()

# print(end - start)

#On importe ces 2 fonctions mathématiques : floor = valeur plancher ; sqrt = racine carrée from math import floor,sqrt

#d|n tq 1<d<n def d2(n):

s=set()

for i in range(2,1+floor(sqrt(n))):

if (n%i) == 0:

s |= {i, n//i}

return(s)

#d|n tq 1=<d<n def d(n):

return({1}|d2(n))

#i*n=<max tq i>1 def m(n):

s=set()

for i in range(2,1+max//n):

s.add(i*n) return(s)

#jouer n avec la liste s est-il gagnant ? def g(n,s):

#jouer 1 est perdant car il existe p premier tq n/2<p<n dès que n>=3 (postulat de Bertrand) if n==1:

return False t=s-{n}

if len(t)==0:

return True else:

for i in (d(n)|m(n))&t:

if g(i,t):

return False

#l'autre joueur a une stratégie gagnante : le coup est perdant

(5)

return True

#sinon le coup est gagnant

#n est-il gagnant ? def gg(n):

if n==2:

return False else:

t=set(range(1,1+n)) for i in range(1,1+n//2):

if g(2*i,t):

return True break return False

#retourne la liste des valeurs 3=<n<m gagnantes def lg(m):

l=set()

for i in range(3,m):

if gg(i):

l.add(i) return l

#retourne la liste de premier coup pair gagnant pour n def l1g(n):

l=set()

t=set(range(1,1+n)) for i in range(1,1+n//2):

j=2*i if g(j,t):

l.add(j) return l

#jeu gagnant du joueur1, le coup précédant étant n, la liste restante étant s def j1(n,s,sol):

tt=set()

for d in ((d2(n)|m(n))&s):

if g(d,s):

tt.add(d) mm=max md=d for d in tt:

e=(d2(d)|m(d))&s ll=len(e)

if ll<mm:

mm=ll md=d

sol.append(md) j2(md,s-{md},sol)

#ensemble des réponses du joueur2 dans le cas d'une partie gagnante pour joueur1, le coup précédant étant n, la liste restante étant s

def j2(n,s,sol):

e=sorted((d2(n)|m(n))&s) if len(e)==0:

ss.append(sol)

(6)

return else:

for d in e:

tmp=list(sol) tmp.append(d) j1(d,s-{d},tmp) return

#on liste les parties possible dans le cas n avec comme premier coup gagnant i n=50

s=set(range(1,1+n))

#for i in l1g(n):

# ss=[]

# j2(i,s-{i},[i])

# print(i,len(ss))

i=26 ss=[]

j2(i,s-{i},[i]) print(i,len(ss)) for j in ss:

print(j)

Références

Documents relatifs

&#34;mlExpansionHistory&#34; ou une couche &#34;envelopedData&#34;. Il se peut qu'un message partant d'un domaine &#34;DOMSEC&#34; ait été déjà traité par un MLA, dans ce cas

[r]

Comme arccos donne une valeur entre 0 et π, donc positive, elle donne la bonne valeur d’angle seulement dans le cas où l’image de z est située au dessus de l’axe des abscisses

Pour les plus courageux : un entier naturel quelconque peut-il être représenté par la différence de deux nombres puissants.. Solution par

[r]

Erire un programme C permettant de saisir au lavier un nombre entier stritement

[r]

Devoir Surveillé 3 - durée : 1 h 7 décembre 2010 Les documents, la calculatrice, et tout matériel électronique sont interdits.. Le soin, la précision et la qualité de la