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 08/12/2019 17:31 | #
Merci beaucoup à tous.
Pavel, par ici pour toi stp :
https://tiplanet.org/forum/viewtopic.php?f=49&t=23237&p=249058#p249053
Ajouté le 09/12/2019 à 17:19 :
@Sentaro21, what would you like ?
https://tiplanet.org/forum/viewtopic.php?f=49&t=23237&p=249125#p249125
Citer : Posté le 10/12/2019 00:37 | #
Thanks a lot again for this great contest.
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 11/12/2019 15:25 | #
Alors, ou en est-on avec les lots ?
-Planétarium 2
Citer : Posté le 11/12/2019 15:26 | #
Au 10ème, ça avance bien jusqu'à présent.
Citer : Posté le 11/12/2019 15:46 | #
Sur 14 lots.. il t'en reste 5 ou 6 encore
-Planétarium 2
Citer : Posté le 11/12/2019 20:37 | #
Comment peut-on voire les lots restants ?
Citer : Posté le 11/12/2019 20:40 | #
Tout est bien détaillé sur le post Ti-planet sur cette épreuve
(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 11/12/2019 20:45 | #
Ah ok merci. Je ne savais pas si les lots affichés étaient ceux restants ou s’ils pouvaient deja être réservés.
Citer : Posté le 11/12/2019 21:24 | #
Justement, @Ne0tux c'est à ton tour :
https://tiplanet.org/forum/viewtopic.php?f=49&t=23237&p=249307#p249307
Citer : Posté le 12/12/2019 07:13 | #
Wow c déjà terminé ! Quelle rapidité par rapport a l'épreuve python ! Donc c bon, plus de lots a distribuer.. ?
-Planétarium 2
Citer : Posté le 13/12/2019 12:56 | #
@Ne0tux, ton colis est fait, merci d'en vérifier le contenu
Citer : Posté le 13/12/2019 14:04 | #
Tout est bon, merci encore !
La Planète Casio est accueillante : n'hésite pas à t'inscrire pour laisser un message ou partager tes créations !
Citer : Posté le 13/12/2019 14:10 | #
De rien, merci surtout à toi pour tes remarquables participations.
Ajouté le 13/12/2019 à 14:30 :
@Tituya, ton colis est fait, merci d'en vérifier le contenu
Citer : Posté le 13/12/2019 15:09 | #
Tout est bien correct pour moi ! Merci beaucoup
(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 13/12/2019 15:24 | #
De rien, c'est toi que nous remercions.
Ajouté le 13/12/2019 à 18:51 :
2 autres colis prêts à vérifier.
@edgar13 :
@Disperseur :
Citer : Posté le 13/12/2019 18:57 | #
Eh oui c tout moi ça
Merci Critor pour ton temps et pour ces magnifiques lots
-Planétarium 2
Citer : Posté le 13/12/2019 19:02 | #
Merci également pour le temps non négligeable que tu as toi-même passé sur nos défis.
Citer : Posté le 14/12/2019 16:54 | #
C'est bon pour moi aussi
Citer : Posté le 14/12/2019 17:50 | #
Merci à vous.
20 colis sont prêts, mais c'est pas fini...
En attendant, merci de vérifier :
@Renaud42 :
@Captainluigi :
@Sentaro21 :
Citer : Posté le 14/12/2019 20:57 | #
C'est bon pour moi , Critor , Merci d'avance
Passé ici il y a peu. ಥ‿ಥ
Jouez à Mario sans arrêt sur votre Casio !
City Heroes
Piano Casio
Micro GIMP