du concours était un jeu sur un automate cellulaire avec des règles peu conventionnelles. Il s'agissait de faire coopérer deux populations adverses, les Muens et les Atlantes, avec le maximum d'efficacité pendant 42 ans. Pour compliquer les équations, chaque cellule de l'automate pouvait contenir une proportion variable d'individus.
C'est parti pour le hall of fame des stratégies de gestion de populations que vous avez mises en oeuvre.
, lycéen en Terminale S à l'aide de sa Graph 90+E, réalise dès le départ pas moins de
points en l'an 42. Précisons que dans sa simulation les Atlantes emportent la victoire sur les Muens en l'an 64 ce qui donne un score maximal de
points en l'an 42. Précisons que dans sous cette configuration les Atlantes gagnent encore sur les Muens mais après pas moins de 173 ans, pour score final de
points en l'an 42. Dans cette réalité alternative ce sont les Muens qui éradiquent les Atlantes mais dès l'an 87, pour un score terminal de
points en l'an 42. Avec un tel semis, les Atlantes écrasent à leur tour les Muens ici encore assez vite, dès l'an 86, pour un ultime score de
points en l'an 42. Ici encore la cohabitation n'est pas bien durable, les Atlantes régnant sans partage dès l'an 71, pour un score alors figé à
points en l'an 42. Une vision à plus long terme dans son cas, les Muens n'arrivant alors à exterminer les Atlantes qu'après 134 ans, pour un score définitif de
points.
points en l'an 42. Une bonne durabilité là encore, les Muens ne dominant alors le monde qu'après 144 ans, pour un score s'arrêtant alors à
points.
points en l'an 42.
Mais hélas l'équilibre n'est sans lui qu'éphémère, les Muens triomphant alors après seulement 88 ans pour
, lycéen plus interventioniste en Première, invoque ses pouvoirs divins pas plus de
points en l'an 42. Une cohabitation de ces populations qui a le mérite de durer 247 ans, avant la victoire finale des Atlantes sur les Muens pour
points en l'an 42. Une durabilité toutefois en retrait, les Atlantes devant les maîtres du monde après 149 ans pour
points.
Amiga68000 a écrit :Voici mon code, et vu mon classement vous comprendrez que ma méthode n'est pas la meilleure.
J'ai fait des tirages aléatoires en paramétrant
(en en tirant aléatoirement) :
• la taille zone de départ où mettre les habitants
(variables carrex et carrey)
• le nombre d’habitants
Voilà les 2 fonctions utilisées:
atmu=run(100,False)
• 100 = nombre de tirages de 42 ans
• 0 = pas de limite
• True = sauvegarde de chaque tirage pour faire des statistiques
Routine qui à partir d'une composition fait varier chaque position de chaque habitant et prend la meilleure configuration :
variercompo()
Et le code global ci-contre
(merci Pavel pour la transpo sur PC).
from math import log10,sqrt
from random import randint
import csv
from math import log10,sqrt
from tkinter import *
def color(r, g, b):
return '#%02x%02x%02x' % (r, g, b)
def fill_rect(x, y, w, h, color):
y += 18
canvas.create_rectangle(x, y, x + w, y + h, fill=color, outline='')
def draw_string(text, x, y, fg=color(0,0,0), bg=None):
y += 18
t = canvas.create_text(x, y, anchor=NW, text=text, fill=fg)
if bg is not None:
r = canvas.create_rectangle(canvas.bbox(t), fill=bg, outline='')
canvas.tag_lower(r, t)
def clear():
canvas.delete('all')
canvas.create_rectangle(0, 18, 320, 240, fill=color(255, 255, 255), outline='')
canvas.create_rectangle(0, 0, 320, 18, fill=color(255, 183, 52), outline='')
def init():
global atmu,n,j,s,ma,mb,mc,w,fp,fm
atmu,n,j,s,w,fp,fm=[],9,0,0,5,0,0
ma,mb,mc=[[0]*n for k in range(n)],[[0]*n for k in range(n)],[[0]*n for k in range(n)]
def dr():
global s,j,w
sw=320
d,h=min(sw//n,221//n),(color(0,0,0),color(255,255,255))
b=sw-1-n*d
clear()
for i in range(0,n*d+1,d):
fill_rect(b,i,n*d,1,h[0])
fill_rect(b+i,0,1,n*d,h[0])
for y in range(0,n):
for x in range(0,n):
t=255-(255*abs(ma[y][x])//w)
fill_rect(b+x*d+1,y*d+1,d-1,d-1,ma[y][x]<0 and color(t,t,255) or ma[y][x]>0 and color(255,t,t) or h[1])
draw_string(" ATLEMU ",1,1,color(255,255,0),color(127,127,127))
draw_string("Muen\ndo(-1,c,l)",0,19,color(0,0,255),h[1])
draw_string("Atlante\ndo(1,c,l)",0,53,color(255,0,0),h[1])
draw_string("Passer\ndo(0)",0,87,color(255,0,255),h[1])
draw_string("Recommencer\ninit()",0,121,color(0,0,0),h[1])
draw_string("An: "+str(j)+"\nScore:\n"+str(s)[:10],0,n*d-49)
def do(*ar):
global j,gp,gm,fp,fm,s
j,k,v,(sc,sl)=j+1,ar[0],(len(ar)%2) or ar[len(ar)-1],(len(ar)>=3) and (ar[1],ar[2]) or (0,0)
k,gp,gm=k and k//abs(k),fp,fm
for y in range(n):mb[y]=mc[y].copy()
for y in range(n):
for x in range(n):
o,ma[y][x]=ma[y][x],ma[y][x]+w*(ma[y][x]==0 and x==sc and y==sl)*((k>0)-(k<0))+(ma[y][x]<=0 and (x-sc or y-sl or k==0) and mb[y][x]//10==3)*((ma[y][x]==0)*w-ma[y][x]*(not(not(ma[y][x]))))-(ma[y][x]>=0 and (x-sc or y-sl or k==0) and mb[y][x]-10*(mb[y][x]//10)==3)*((ma[y][x]==0)*w+ma[y][x]*(not(not(ma[y][x]))))
if o and ma[y][x]==o:
ls=(-1,w>abs(ma[y][x]))
ma[y][x]=ma[y][x]+(ma[y][x]>0)*ls[mb[y][x]//10==3 or mb[y][x]//10==4]-(ma[y][x]<0)*ls[mb[y][x]-10*(mb[y][x]//10)==3 or mb[y][x]-10*(mb[y][x]//10)==2]
if ma[y][x]-o:
fp,fm=fp+(ma[y][x]>0 and not(o))-(o>0 and not(ma[y][x])),fm+(ma[y][x]<0 and not(o))-(o<0 and not(ma[y][x]))
if not(o) and ma[y][x] or o and not(ma[y][x]):
for dl in range(-1,2):
for dc in range(-1,2):
if dl or dc:mc[y+dl+(dl<0 and y==0)*n-(dl>0 and y==n-1)*n][x+dc+(dc<0 and x==0)*n-(dc>0 and x==n-1)*n]+=(ma[y][x]<0)-(o<0 and 0==ma[y][x])+10*((ma[y][x]>0)-(o>0 and 0==ma[y][x]))
if max(fp,gp)*max(fm,gm):s=s/(1+abs(k)*log10(sqrt(j)))+fp*fm*min(fp,gp)*min(fm,gm)/max(fp,gp)/max(fm,gm)
atmu.append((sc*k+k,sl*k+k))
if v:
dr()
# print("Bon score ? Envoie la liste\n'atmu' a info@tiplanet.org")
return s
def st(l,v=True):
init()
for p in l:s=do((p[0]>0)-(p[0]<0),abs(p[0])-1,abs(p[1])-1,v)
dr()
return s
# ************************************************************************************
# **
# ** SUB PERSO
# **
# ************************************************************************************
rep="D:/_Datas/_Datas PERSO/Python-atlemu"
def sauvecsv(v,nom=rep + "/sansnom.csv",m="w"):
#sauvegarde une matrice p en csv
#with open("L:/_Datas/11 - Arnaud/Python - DEFI/table.csv", "w") as f_write:
with open(nom, m) as f_write:
writer = csv.writer(f_write,delimiter=";")
writer.writerow(v) # writer.writerows(v) si plusieurs lignes
return
def sauvetxt(v,nom=rep + "/sansnom.txt"):
fichier = open(nom,"w")
fichier.write(str(v))
fichier.close()
return
def run(nbboucles,sauvechaquetirage=False):
global atmumax
smax=0
boucle=0
moyscore=0
while boucle<nbboucles or nbboucles==0:
boucle+=1
init()
if boucle%100==0:print("run "+str(boucle)+" Max="+str(smax))
carrex= randint(2,4)
carrey= randint(2,4)
zonex=9-carrex
zoney=9-carrey
x1=randint(1,zonex)
y1=randint(1,zoney)
x2=randint(1,zonex)
y2=randint(1,zoney)
nbhabitants=12 #randint(3,5)
for k in range(nbhabitants-1): #nombre d'habitants par couleur
# l=randint(0,carre)
# m=randint(0,carre)
do(1,x1+randint(0,carrex),y1+randint(0,carrey) )
do(-1,x2+randint(0,carrex),y2+randint(0,carrey) )
# nx1=x1+randint(0,carrex)
# ny1=y1+randint(0,carrey)
# if ma[nx1-1][ny1-1]!=0:
# s=do(0)
# else:
# do(1,nx1,ny1)
#
# nx2=x2+randint(0,carrex)
# ny2=y2+randint(0,carrey)
# if ma[nx2-1][ny2-1]!=0:
# s=do(0)
# else:
# do(-1,nx2,ny2)
s=do(0)
s=do(0)
do(1,x1+randint(0,carrex),y1+randint(0,carrey) )
do(-1,x2+randint(0,carrex),y2+randint(0,carrey) )
while j<42:
s=do(0)
moyscore+=s
if s>smax:
smax=s
atmumax=list(atmu)
print("---")
print("#"+str(smax))
print("#"+str(atmumax))
print("---")
print("Carre X="+str(carrex))
print("Carre Y="+str(carrey))
print("Nb habitants="+str(nbhabitants))
print("---")
if not(sauvechaquetirage):
sauvertirage(smax,nbhabitants,0,carrex,carrey,atmumax)
if sauvechaquetirage:
sauvertirage(s,nbhabitants,0,carrex,carrey,atmu)
print("#"+str(smax))
print("#st("+str(atmumax)+",False)")
print("#"+str(smax))
moyscore=moyscore/nbboucles
print("#"+str(moyscore))
st(atmumax,False)
return atmumax
def sauvertirage(score,nbhabitants,surface,carrex,carrey,compo):
if surface==0:
surface=carrex*carrey
e=[]
e.append(score)
e.append(nbhabitants)
e.append(surface)
e.append(carrex)
e.append(carrey)
e.append(compo)
sauvecsv(e,rep+"/stat-tirages.csv","a")
return
def variercompo():
compo=[(7, 2), (-4, -7), (8, 2), (-2, -7), (7, 4), (-3, -7), (0, 0), (-4, -9), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0)]
smax=0
atmumax=[]
s=st(compo,False)
smax=s
atmumax=list(atmu)
for k in range(len(compo)):
print("k="+str(k))
hab=compo[k]
x=hab[0]
y=hab[1]
if x!=0:
#on fait varier les positions
plage=[-1,0,1]
for deltax in plage:
nx=x+deltax
for deltay in plage:
ny=y+deltay
#on a la nouvelle position nx,ny
ncompo=list(compo)
print(ncompo[k])
ncompo[k][0]=nx
ncompo[k][1]=ny
#on teste la compo
s=st(ncompo,False)
#
if s>smax:
smax=s
atmumax=list(atmu)
print("---")
print("#"+str(smax))
print("#"+str(atmumax))
print("---")
print("Carre X="+str(carrex))
print("Carre Y="+str(carrey))
print("Nb habitants="+str(nbhabitants))
print("---")
return
master = Tk()
master.resizable(0, 0)
canvas = Canvas(master, width=320, height=240)
canvas.pack()
sauvertirage("Score","nb habitants","surface","carre X","carre Y","Sequence")
init()
dr()
variercompo()
#atmu=run(100,False)
#sauvetxt(atmu,rep+"/CompoAtmu.txt")
#affichage
if __name__== "__main__":master.mainloop()
#st([(7, 2), (-4, -7), (8, 2), (-2, -7), (7, 4), (-3, -7), (0, 0), (-4, -9), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0)],False)
#18425.217793183947
#st([(7, 2), (-4, -7), (8, 2), (-2, -7), (7, 4), (-3, -7), (0, 0), (-4, -9), (0, 0), (-3, -9), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0)],False)
#18390.75048739328
#18381.309236990124
#[(7, 2), (-4, -7), (8, 2), (-2, -7), (7, 4), (-3, -7), (8, 2), (-4, -9), (7, 4), (-3, -9), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0)]
#18381.309236990124
#18168.450679791244
#[(9, 7), (-4, -8), (9, 8), (-4, -7), (7, 8), (-2, -8), (9, 8), (-4, -8), (8, 6), (-4, -9), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0)]
#18168.450679791244
#18049.830151963542
#[(9, 3), (-5, -3), (7, 3), (-5, -2), (9, 2), (-5, -4), (7, 2), (-3, -4), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0)]
#18049.830151963542
#18035.99025478949
#[(3, 3), (-8, -7), (2, 3), (-7, -6), (3, 4), (-9, -6), (4, 3), (-7, -7), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0)]
#18035.99025478949
#18003.837819596458
#[(3, 3), (-4, -8), (3, 4), (-4, -7), (5, 3), (-2, -8), (2, 2), (-5, -9), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0)]
#18003.837819596458
#17841.546235752416
#[(4, 4), (-8, -2), (4, 5), (-8, -3), (2, 5), (-6, -3), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0)]
#17781.124608967286
#[(4, 7), (-8, -6), (3, 6), (-9, -7), (5, 6), (-7, -7), (4, 7), (-8, -6), (3, 5), (-9, -8), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0)]
#17605.76772889996
#[(2, 9), (-7, -6), (3, 9), (-7, -7), (2, 8), (-5, -7), (4, 7), (-5, -7), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0)]
#17425
#[(4, 5), (-8, -3), (4, 4), (-8, -4), (4, 3), (-6, -4), (3, 3), (-6, -3), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0)]
points en l'an 42. Saluons la durée exceptionnelle de cohabitation de ces deux populations, les Muens devant attendre pas moins de 263 ans pour régner en maîtres absolus, pour pas moins de
points en l'an 42. Par contre c'est bien moins solide, les Atlantes faisant disparaître les derniers Muens après seulement 86 ans pour
, lycéen en Première Spécialité Mathématiques+PC+SVT accompagné de sa fidèle TI-83 Premium CE Edition Python présent à la fois
points ! La durabilité est améliorée, avec les Muens qui ne signent l'arrêt de mort des Atlantes que l'an 148 avec
points.
points en l'an 42 ! Meilleure durabilité puisque les Atlantes ne triomphent des Muens qu'après 193 ans pour
points en l'an 42 ! Meilleure durabilité puisque les Atlantes gagnent leur dernier combat dès l'an 96 avec
points.
points en l'an 42 ! Et c'est du solide, les Muens ne remportant leur ultime bataille qu'en l'an 225 avec
points en l'an 42 ! C'est un peu plus fragile, les deux populations n'arrivant à cohabiter que jusqu'à l'an 142, où seuls les Atlantes subsisteront avec
points.
points en l'an 42 ! Un net mieux en terme de cohabitation, qui dure maintenant jusqu'à l'an 183, où ne resteront que les Muens avec
points en l'an 42 ! Une longévité de plus exceptionnelle, les Atlantes mettant pas moins 277 ans à achever les derniers Muens pour
points en l'an 42 ! Dommage toutefois que cela dure moins, les Atlantes ne mettant que 102 ans à conquérir le monde pour
points.
nous exhibe également la configuration ultime. A partir de l'an 26 les deux populations font la paix et entrent ainsi en stabilité parfaite. La score attention ainsi des sommets avec par exemple pas moins de
points au record de 277 ans, et continue ensuite son chemin vers l'infini et au-delà, une première place largement méritée !
Pavel a écrit :Voici quelques explications de ma méthode pour obtenir 21960 points. J'ai commencé à jouer sur ma TI-83 Premium CE mais je n'étais pas assez patient pour attendre au moins 15 secondes après chaque tour et j'ai vite abandonné cette idée. Ensuite, j'ai légèrement modifié le script Numworks en remplaçant Kandinsky par tkinter et j'ai continué à jouer sur un PC. La version modifiée du script ci-contre se trouve également dans
ce dépôt.
from math import log10,sqrt
from tkinter import *
master = Tk()
master.resizable(0, 0)
canvas = Canvas(master, width=320, height=240)
canvas.pack()
def color(r, g, b):
return '#%02x%02x%02x' % (r, g, b)
def fill_rect(x, y, w, h, color):
y += 18
canvas.create_rectangle(x, y, x + w, y + h, fill=color, outline='')
def draw_string(text, x, y, fg=color(0,0,0), bg=None):
y += 18
t = canvas.create_text(x, y, anchor=NW, text=text, fill=fg)
if bg is not None:
r = canvas.create_rectangle(canvas.bbox(t), fill=bg, outline='')
canvas.tag_lower(r, t)
def clear():
canvas.delete('all')
canvas.create_rectangle(0, 18, 320, 240, fill=color(255, 255, 255), outline='')
canvas.create_rectangle(0, 0, 320, 18, fill=color(255, 183, 52), outline='')
def init():
global atmu,n,j,s,ma,mb,mc,w,fp,fm
atmu,n,j,s,w,fp,fm=[],9,0,0,5,0,0
ma,mb,mc=[[0]*n for k in range(n)],[[0]*n for k in range(n)],[[0]*n for k in range(n)]
def dr():
global s,j,w
sw=320
d,h=min(sw//n,221//n),(color(0,0,0),color(255,255,255))
b=sw-1-n*d
clear()
for i in range(0,n*d+1,d):
fill_rect(b,i,n*d,1,h[0])
fill_rect(b+i,0,1,n*d,h[0])
for y in range(0,n):
for x in range(0,n):
t=255-(255*abs(ma[y][x])//w)
fill_rect(b+x*d+1,y*d+1,d-1,d-1,ma[y][x]<0 and color(t,t,255) or ma[y][x]>0 and color(255,t,t) or h[1])
draw_string(" ATLEMU ",1,1,color(255,255,0),color(127,127,127))
draw_string("Muen\ndo(-1,c,l)",0,19,color(0,0,255),h[1])
draw_string("Atlante\ndo(1,c,l)",0,53,color(255,0,0),h[1])
draw_string("Passer\ndo(0)",0,87,color(255,0,255),h[1])
draw_string("Recommencer\ninit()",0,121,color(0,0,0),h[1])
draw_string("An: "+str(j)+"\nScore:\n"+str(s)[:10],0,n*d-49)
def do(*ar):
global j,gp,gm,fp,fm,s
j,k,v,(sc,sl)=j+1,ar[0],(len(ar)%2) or ar[len(ar)-1],(len(ar)>=3) and (ar[1],ar[2]) or (0,0)
k,gp,gm=k and k//abs(k),fp,fm
for y in range(n):mb[y]=mc[y].copy()
for y in range(n):
for x in range(n):
o,ma[y][x]=ma[y][x],ma[y][x]+w*(ma[y][x]==0 and x==sc and y==sl)*((k>0)-(k<0))+(ma[y][x]<=0 and (x-sc or y-sl or k==0) and mb[y][x]//10==3)*((ma[y][x]==0)*w-ma[y][x]*(not(not(ma[y][x]))))-(ma[y][x]>=0 and (x-sc or y-sl or k==0) and mb[y][x]-10*(mb[y][x]//10)==3)*((ma[y][x]==0)*w+ma[y][x]*(not(not(ma[y][x]))))
if o and ma[y][x]==o:
ls=(-1,w>abs(ma[y][x]))
ma[y][x]=ma[y][x]+(ma[y][x]>0)*ls[mb[y][x]//10==3 or mb[y][x]//10==4]-(ma[y][x]<0)*ls[mb[y][x]-10*(mb[y][x]//10)==3 or mb[y][x]-10*(mb[y][x]//10)==2]
if ma[y][x]-o:
fp,fm=fp+(ma[y][x]>0 and not(o))-(o>0 and not(ma[y][x])),fm+(ma[y][x]<0 and not(o))-(o<0 and not(ma[y][x]))
if not(o) and ma[y][x] or o and not(ma[y][x]):
for dl in range(-1,2):
for dc in range(-1,2):
if dl or dc:mc[y+dl+(dl<0 and y==0)*n-(dl>0 and y==n-1)*n][x+dc+(dc<0 and x==0)*n-(dc>0 and x==n-1)*n]+=(ma[y][x]<0)-(o<0 and 0==ma[y][x])+10*((ma[y][x]>0)-(o>0 and 0==ma[y][x]))
if max(fp,gp)*max(fm,gm):s=s/(1+abs(k)*log10(sqrt(j)))+fp*fm*min(fp,gp)*min(fm,gm)/max(fp,gp)/max(fm,gm)
atmu.append((sc*k+k,sl*k+k))
if v:
dr()
print("Bon score ? Envoie la liste\n'atmu' a info@tiplanet.org")
return s
def st(l,v=True):
init()
for p in l:s=do((p[0]>0)-(p[0]<0),abs(p[0])-1,abs(p[1])-1,v)
dr()
return s
init()
dr()
if __name__== "__main__":
master.mainloop()
Je me suis beaucoup amusé avec le mode interactif de ce jeu et en même temps j'ai remarqué les particularités suivantes de ce jeu :
• il faut trois colonies de la même civilisation pour que les colonies commencent à se multiplier
• le calcul du score n'est pas sensible au décalage horizontal ou vertical et toute solution peut être transformée en l'un des deux types de solutions suivantes :
• la toute première colonie est en position
(0,0) et cette colonie est Muenne
• la toute première colonie est en position
(0,0) et cette colonie est Atlante
Pour maximiser le score, j'ai utilisé l'algorithme de recuit simulé et j'ai réécrit le calcul du score en C pour pouvoir calculer le score le plus rapidement possible.
J'ai passé beaucoup de temps à ajuster les paramètres de l'algorithme et j'ai aussi remarqué les points suivants:
• les solutions où la première colonie est Atlante ont tendance à apporter plus de points
• les meilleures solutions prennent moins de 12 tours pour réaliser le semis
Enfin, ma méthode a pris la forme suivante:
• au premier tour, mettre une colonie Atlante à
(0,0)
• à chaque itération de recuit simulé, faire les modifications suivantes:
• changer aléatoirement l'un des 10 prochains tours en plaçant une colonie sur une position libre
• vérifier les 10 prochains tours un par un en essayant tous les 163 mouvements possibles et garder une combinaison avec le score maximum
• recommencer plusieurs fois avec différentes séquences de nombres pseudo-aléatoires
Pour être sûr d'avoir de bonnes séquences de nombres pseudo-aléatoires, j'ai pris l'algorithme
WELL512.
#include <errno.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
struct STATE
{
int8_t code[42];
int8_t board[81 * 42];
double score;
};
/*
WELL512 algorithm
http://www.iro.umontreal.ca/~panneton/WELLRNG.html
implemented by Chris Lomont
http://lomont.org/papers/2008/Lomont_PRNG_2008.pdf
*/
uint32_t buf[16];
uint32_t pos;
uint32_t wellrng512()
{
uint32_t a, b, c, d;
a = buf[pos];
c = buf[(pos + 13) & 15];
b = a ^ c ^ (a << 16) ^ (c << 15);
c = buf[(pos + 9) & 15];
c ^= (c >> 11);
a = buf[pos] = b ^ c;
d = a ^ ((a << 5) & 0xDA442D24UL);
pos = (pos + 15) & 15;
a = buf[pos];
buf[pos] = a ^ b ^ d ^ (a << 2) ^ (b << 18) ^ (c << 28);
return buf[pos];
}
double score(struct STATE *state)
{
double s;
int8_t i, j, k, l, dx, dy, lp, lm, o, x, y, xn, yn;
int8_t dp, dm, fp, fm, gp, gm, maxp, maxm, minp, minm;
int8_t ma[81], mp[81], mm[81], np[81], nm[81];
s = 0.0;
fp = 0;
fm = 0;
memset(ma, 0, 81);
memset(mp, 0, 81);
memset(mm, 0, 81);
for(j = 0; j < 42; ++j)
{
i = state->code[j];
l = abs(i) - 1;
k = (i > 0) - (i < 0);
gp = fp;
gm = fm;
memcpy(np, mp, 81);
memcpy(nm, mm, 81);
memcpy(state->board + j * 81, ma, 81);
for(i = 0; i < 81; ++i)
{
o = ma[i];
if(i == l && k != 0)
{
if(ma[i] == 0) ma[i] = 5 * k;
}
else
{
ma[i] += (np[i] == 3) * ((ma[i] == 0) * 5 - (ma[i] < 0) * ma[i]) - (nm[i] == 3) * ((ma[i] == 0) * 5 + (ma[i] > 0) * ma[i]);
}
if(ma[i] == o && o != 0)
{
lp = np[i] == 3 || np[i] == 4 ? abs(ma[i]) < 5 : -1;
lm = nm[i] == 3 || nm[i] == 2 ? abs(ma[i]) < 5 : -1;
ma[i] += (ma[i] > 0) * lp - (ma[i] < 0) * lm;
}
if(ma[i] != o && (ma[i] == 0 || o == 0))
{
dp = (ma[i] > 0) - (o > 0);
dm = (ma[i] < 0) - (o < 0);
fp += dp;
fm += dm;
x = i % 9;
y = i / 9;
for(dx = -1; dx < 2; ++dx)
{
for(dy = -1; dy < 2; ++dy)
{
if(dx == 0 && dy == 0) continue;
yn = y + dx;
yn = yn < 0 ? 8 : yn > 8 ? 0 : yn;
xn = x + dy;
xn = xn < 0 ? 8 : xn > 8 ? 0 : xn;
mp[yn * 9 + xn] += dp;
mm[yn * 9 + xn] += dm;
}
}
}
}
maxp = fp > gp ? fp : gp;
maxm = fm > gm ? fm : gm;
minp = fp < gp ? fp : gp;
minm = fm < gm ? fm : gm;
if(maxp != 0 && maxm != 0)
{
s = s / (1 + abs(k) * log10(sqrt(j + 1))) + 1.0 * fp * fm * minp * minm / maxp / maxm;
}
}
return s;
}
void init(struct STATE *state)
{
memset(state->code, 0, 42);
state->code[0] = 1;
memset(state->board, 0, 81 * 42);
state->score = score(state);
}
void random_walk(struct STATE *state)
{
int8_t i, imax, j, l;
double s, smax;
for(l = 0; l < 2; ++l)
{
while(1)
{
i = wellrng512() % 163 - 81;
j = wellrng512() % 10 + 1;
if(i == 0 || state->board[j * 81 + abs(i) - 1] == 0)
{
state->code[j] = i;
break;
}
}
}
for(l = 0; l < 1; ++l)
{
for(j = 1; j < 12; ++j)
{
imax = 0;
smax = 0.0;
for(i = -81; i < 82; ++i)
{
state->code[j] = i;
s = score(state);
if(smax < s)
{
imax = i;
smax = s;
}
}
state->code[j] = imax;
state->score = smax;
}
}
}
void print(struct STATE *state)
{
int8_t i, j, k, l;
printf("%.9f ", state->score);
for(j = 0; j < 42; ++j)
{
i = state->code[j];
l = abs(i) - 1;
k = (i > 0) - (i < 0);
printf("(%d, %d), ", k * (l % 9 + 1), k * (l / 9 + 1));
}
printf("\n");
}
int main(int argc, char *argv[])
{
struct STATE current, next;
double delta, result, t;
unsigned seed;
int8_t i;
result = 0.0;
while(1)
{
seed = time(NULL);
srand(seed);
printf("seed: %d\n", seed);
pos = 0;
for(i = 0; i < 16; ++i)
{
buf[i] = rand() ^ (rand() << 16) ^ (rand() << 31);
}
init(¤t);
t = 1.0;
while(t > 0.001)
{
t *= 0.999;
next = current;
random_walk(&next);
if(result < next.score)
{
result = next.score;
print(&next);
}
delta = next.score - current.score;
if(delta >= 0 || wellrng512() < RAND_MAX * exp(delta / t))
{
current = next;
}
}
}
return EXIT_SUCCESS;
}
Après plusieurs heures, j'ai eu la chance de trouver une séquence de nombres aléatoires permettant à mon code de converger vers 21960 en quelques minutes. Je suis très heureux que cette solution, en même temps, apporte beaucoup de points et crée un monde absolument stable dans lequel les deux civilisations coexisteront pendant des millions d'années.
Enfin, voici
un lien vers mon code en C également ci-contre.
#include <errno.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
struct STATE
{
int8_t code[42];
int8_t board[81 * 42];
double score;
};
/*
WELL512 algorithm
http://www.iro.umontreal.ca/~panneton/WELLRNG.html
implemented by Chris Lomont
http://lomont.org/papers/2008/Lomont_PRNG_2008.pdf
*/
uint32_t buf[16];
uint32_t pos;
uint32_t wellrng512()
{
uint32_t a, b, c, d;
a = buf[pos];
c = buf[(pos + 13) & 15];
b = a ^ c ^ (a << 16) ^ (c << 15);
c = buf[(pos + 9) & 15];
c ^= (c >> 11);
a = buf[pos] = b ^ c;
d = a ^ ((a << 5) & 0xDA442D24UL);
pos = (pos + 15) & 15;
a = buf[pos];
buf[pos] = a ^ b ^ d ^ (a << 2) ^ (b << 18) ^ (c << 28);
return buf[pos];
}
double score(struct STATE *state)
{
double s;
int8_t i, j, k, l, dx, dy, lp, lm, o, x, y, xn, yn;
int8_t dp, dm, fp, fm, gp, gm, maxp, maxm, minp, minm;
int8_t ma[81], mp[81], mm[81], np[81], nm[81];
s = 0.0;
fp = 0;
fm = 0;
memset(ma, 0, 81);
memset(mp, 0, 81);
memset(mm, 0, 81);
for(j = 0; j < 42; ++j)
{
i = state->code[j];
l = abs(i) - 1;
k = (i > 0) - (i < 0);
gp = fp;
gm = fm;
memcpy(np, mp, 81);
memcpy(nm, mm, 81);
memcpy(state->board + j * 81, ma, 81);
for(i = 0; i < 81; ++i)
{
o = ma[i];
if(i == l && k != 0)
{
if(ma[i] == 0) ma[i] = 5 * k;
}
else
{
ma[i] += (np[i] == 3) * ((ma[i] == 0) * 5 - (ma[i] < 0) * ma[i]) - (nm[i] == 3) * ((ma[i] == 0) * 5 + (ma[i] > 0) * ma[i]);
}
if(ma[i] == o && o != 0)
{
lp = np[i] == 3 || np[i] == 4 ? abs(ma[i]) < 5 : -1;
lm = nm[i] == 3 || nm[i] == 2 ? abs(ma[i]) < 5 : -1;
ma[i] += (ma[i] > 0) * lp - (ma[i] < 0) * lm;
}
if(ma[i] != o && (ma[i] == 0 || o == 0))
{
dp = (ma[i] > 0) - (o > 0);
dm = (ma[i] < 0) - (o < 0);
fp += dp;
fm += dm;
x = i % 9;
y = i / 9;
for(dx = -1; dx < 2; ++dx)
{
for(dy = -1; dy < 2; ++dy)
{
if(dx == 0 && dy == 0) continue;
yn = y + dx;
yn = yn < 0 ? 8 : yn > 8 ? 0 : yn;
xn = x + dy;
xn = xn < 0 ? 8 : xn > 8 ? 0 : xn;
mp[yn * 9 + xn] += dp;
mm[yn * 9 + xn] += dm;
}
}
}
}
maxp = fp > gp ? fp : gp;
maxm = fm > gm ? fm : gm;
minp = fp < gp ? fp : gp;
minm = fm < gm ? fm : gm;
if(maxp != 0 && maxm != 0)
{
s = s / (1 + abs(k) * log10(sqrt(j + 1))) + 1.0 * fp * fm * minp * minm / maxp / maxm;
}
}
return s;
}
void init(struct STATE *state)
{
memset(state->code, 0, 42);
state->code[0] = 1;
memset(state->board, 0, 81 * 42);
state->score = score(state);
}
void random_walk(struct STATE *state)
{
int8_t i, imax, j, l;
double s, smax;
for(l = 0; l < 2; ++l)
{
while(1)
{
i = wellrng512() % 163 - 81;
j = wellrng512() % 10 + 1;
if(i == 0 || state->board[j * 81 + abs(i) - 1] == 0)
{
state->code[j] = i;
break;
}
}
}
for(l = 0; l < 1; ++l)
{
for(j = 1; j < 12; ++j)
{
imax = 0;
smax = 0.0;
for(i = -81; i < 82; ++i)
{
state->code[j] = i;
s = score(state);
if(smax < s)
{
imax = i;
smax = s;
}
}
state->code[j] = imax;
state->score = smax;
}
}
}
void print(struct STATE *state)
{
int8_t i, j, k, l;
printf("%.9f ", state->score);
for(j = 0; j < 42; ++j)
{
i = state->code[j];
l = abs(i) - 1;
k = (i > 0) - (i < 0);
printf("(%d, %d), ", k * (l % 9 + 1), k * (l / 9 + 1));
}
printf("\n");
}
int main(int argc, char *argv[])
{
struct STATE current, next;
double delta, result, t;
unsigned seed;
int8_t i;
seed = 1571773356;
srand(seed);
printf("seed: %d\n", seed);
pos = 0;
for(i = 0; i < 16; ++i)
{
buf[i] = rand() ^ (rand() << 16) ^ (rand() << 31);
}
init(¤t);
result = 0.0;
t = 1.0;
while(t > 0.001)
{
t *= 0.999;
next = current;
random_walk(&next);
if(result < next.score)
{
result = next.score;
print(&next);
}
delta = next.score - current.score;
if(delta >= 0 || wellrng512() < RAND_MAX * exp(delta / t))
{
current = next;
}
}
return EXIT_SUCCESS;
}
Cette épreuve conclut notre concours de rentrée 2019 ! Merci à tous les participants, vous avez produit des superbes participations qui nous ont surpris jusqu'à la fin.
Il ne reste plus aux gagnant qu'à sélectionner leurs lots. Ça se passe dans les commentaires, comme d'habitude. Surveillez ce topic et le topic associé sur TI-Planet pour votre tour. La liste des lots et goodies encore disponible est gérée par Critor sur TI-Planet. C'est
Citer : Posté le 17/12/2019 09:14 | #
Attend , pourquoi je suis pas sur la liste ?
Ajouté le 17/12/2019 à 09:15 :
[Edit] j'ai compris
Passé ici il y a peu. ಥ‿ಥ
Jouez à Mario sans arrêt sur votre Casio !
City Heroes
Piano Casio
Micro GIMP
Citer : Posté le 17/12/2019 21:03 | #
Pour les réponses reçues jusqu'à hier inclus, c'est parti.
Voici pour les envois postaux :
On constate que Disperseur domine le classement, sa livraison de demain matin étant déjà annoncée contrairement aux autres...
Citer : Posté le 18/12/2019 12:27 | #
Colis reçus Critor ! Materiel en très bon état, emballage soigné, c super !
Gros Merci à toi !!!!!!
-Planétarium 2
Citer : Posté le 18/12/2019 13:35 | #
C'est parti pour Noël...
Citer : Posté le 18/12/2019 13:51 | #
Ben perso g pas attendu Noël
-Planétarium 2
Citer : Posté le 18/12/2019 14:17 | #
Merdi pour ton retour @Disperseur.
Citer : Posté le 18/12/2019 19:05 | #
Colis reçu pour moi aussi ! Tout fonctionne bien mais il me manque les stickers, pas grave
(Et de toute façon, vous pouvez pas dire le contraire)
MultipliCasio
RDM Calculs
Back Mirror
A Switch To The Top C
Citer : Posté le 18/12/2019 19:06 | #
Merci pour ton retour.
Et non non, les stickers sont juste bien cachés.
Citer : Posté le 18/12/2019 19:07 | #
Trouvé (je trouve le stickers planète casio pas très élégant perso, j'aurai préféré le logo du site )
(Et de toute façon, vous pouvez pas dire le contraire)
MultipliCasio
RDM Calculs
Back Mirror
A Switch To The Top C
Citer : Posté le 18/12/2019 19:08 | #
Félicitations !
Ajouté le 18/12/2019 à 20:07 :
Pour ceux qui n'ont pas encore répondu pour leurs souhaits d'expédition, voir par ici svp, merci :
https://www.planet-casio.com/Fr/forums/topic16051-2-resultat-du-concours-de-rentree-2019-epreuve-de-basic.html#172368
Filoji
Renaud42
Citer : Posté le 18/12/2019 21:53 | #
Ah et j'ai oublié Critor: Joyeux Noël à toi aussi (en avance mais pour repondre à ta carte ) !
-Planétarium 2
Citer : Posté le 18/12/2019 21:56 | #
Merci à toi !
Citer : Posté le 19/12/2019 08:55 | #
Bravo Critor, tu m'as fait découvrir les calculatrices TI ! J'ai été agréablement surpris par les possibilités de la TI 83 Premium CE Edition Python ! Je pense que je vais passer mes vacances à la prendre en main
-Planétarium 2
Citer : Posté le 19/12/2019 09:12 | #
Hey , je pense que le mien ne va pas tarder , il est dans le centre de distribution
Passé ici il y a peu. ಥ‿ಥ
Jouez à Mario sans arrêt sur votre Casio !
City Heroes
Piano Casio
Micro GIMP
Citer : Posté le 19/12/2019 13:32 | #
@CaptainLuigi, ton colis est apparemment chez ton concierge/gardien/voisin selon le suivi.
Citer : Posté le 19/12/2019 16:22 | #
@CaptainLuigi, ton colis est apparemment chez ton concierge/gardien/voisin selon le suivi.
Tout va bien , la gardienne me l'a donné , tout est présent dans le colis .
Joyeux Noël Critor ( Pas mal le coup de la carte )
Et merci encore
Passé ici il y a peu. ಥ‿ಥ
Jouez à Mario sans arrêt sur votre Casio !
City Heroes
Piano Casio
Micro GIMP
Citer : Posté le 19/12/2019 17:05 | #
Merci surtout à toi, c'est toi qui as bossé dur.
Citer : Posté le 23/12/2019 08:46 | #
Lots arrived safely today.
Merry Christmas!!
Thank you very much!!
Overclocking utilitaire Ftune/Ptune2/Ptune3 est également disponible.
Si vous avez des questions ou un rapport de bogue, n'hésitez pas à me le faire savoir.
Citer : Posté le 23/12/2019 10:52 | #
You're welcome. Thank you very much for your kind post and Merry Christmas !
Citer : Posté le 23/12/2019 22:13 | #
Pour moi, envoie s'il te plait :
1) Envoi cette semaine
2) A l'adresse communiquée
3) Ma boite au lettre
4) Pas d'assurance
Merci, je n'avais pas suivi la discussion
Citer : Posté le 23/12/2019 22:14 | #
Merci pour ta réponse. Je te fais partir ça au plus tôt.