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 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
Citer : Posté le 14/12/2019 21:42 | #
Merci à toi également.
Citer : Posté le 15/12/2019 00:51 | #
@Critor
I'm always grateful for your great work.
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 15/12/2019 01:05 | #
Your work is great too.
Thanks.
Ajouté le 15/12/2019 à 18:30 :
Emballage terminé, enfin, ça fait 3 jours que je suis dessus...
Merci de vérifier :
@Renaud42 :
@Filoji :
Citer : Posté le 15/12/2019 18:32 | #
Après envoi des colis, combien de temps pour les recevoir ? Pour me préparer mentalement
(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 15/12/2019 18:33 | #
En temps normal c'est 2-3 jours en boîte à lettres, ou une semaine en point relais.
Dans la période actuelle de fêtes et de grèves, cela peut être davantage...
Ajouté le 15/12/2019 à 19:30 :
Bon, on passe aux expéditions.
Vous serez en vacances vendredi ou samedi, et allez peut-être partir...
De plus c'est la période des fêtes et il peut y avoir des individus malintentionnés qui guettent l'arrivée des colis pensant y trouver du contenu de valeur facilement revendable, et dévalisent votre boîte à lettres ou se présentent spontanément au livreur en se faisant passer pour vous. Comme les livreurs changent régulièrement et que je n'en ai jamais eu aucun qui m'a demandé une pièce d'identité, cela ne doit pas être bien difficile...
Cela nous est déjà tristement arrivé en 2017 avec proghy_v2, dont le lot NumWorks était marqué comme livré alors que sa boîte à lettres était vide. La Poste n'a rien voulu savoir et n'a été d'aucune aide, répondant après des semaines de soi-disant enquête que y'avait marqué livré, ne nous versant pas le moindre centime, et nous n'avons donc de notre côté rien pu reverser au gagnant.
Le pire c'est que la police avait attrapé et relâché des voleurs de boîte à lettres à même pas 500 mètres de chez lui à peine quelques jours avant, et avait donc a priori des chances non négligeables de pouvoir chercher et trouver :
https://www.ledauphine.com/faits-divers/2017/12/02/il-volait-dans-les-boites-aux-lettres
Nous avons donc répondu à proghy_v2 qu'il devait aller porter plainte, et que nous fournirions alors de notre côté le maximum d'éléments (photos, numéro de série, etc...).
J'ignore pourquoi, mais à partir de ce moment-là et malgré une relance depuis, proghy_v2 n'a plus jamais répondu.
Nous ne pouvons pourtant pas porter plainte à votre place dans ces cas-là, nous ne sommes pas témoins du délit.
NumWorks a également fait son possible, mais le numéro de série du modèle en question, une préversion historique d'avant la rentrée 2017, n'a plus jamais été connecté au workshop. Le voleur a dû voir que ce n'était pas un ordi portable / tablette malgré le colis assez plat, et tirer ce modèle historique à la poubelle.
Tout ça pour vous amener aux questions :
1) Souhaitez-vous un envoi dès cette semaine ou bien préférez-vous que l'on attende ?
2) Si envoi cette semaine, à l'adresse déjà communiquée ou bien à une autre ? (la communiquer dans ce cas par courriel)
3) Préférez vous une livraison en boîte à lettres ou bien en point Mondial Relay ? (le communiquer par courriel si vous avez une préférence, sinon on tentera de choisir le plus proche - attention à leurs éventuelles fermetures à eux aussi...)
4) Souhaitez-vous assurer le contenu du colis ?
Dans ce dernier cas, on vous demande de prendre en charge les frais d'assurance. La dernière fois que j'ai regardé, c'était :
- pour la livraison en boîte à lettres, Colissimo Recommandé R2 : +4€ (assurance de 200€ + remise en mains propres contre signature)
- pour la livraison en point Mondial Relay, niveau N2 : +3,50€ (assurance de 125€)
Le plus simple dans ce cas est d'effectuer le versement par Paypal à . Je doute qu'il y ait besoin d'assurer davantage, mais n'hésitez pas à demander si vous voulez autre chose.
Mais après, petit avertissement personnel, le service réclamations de la Poste a selon moi une qualité de service déplorable. Je l'ai hélas maintes fois expérimenté, et pas que pour proghy_v2. Ils vous font patienter des semaines pour une soi-disant enquête qui consiste bêtement à vous envoyer un message préformaté avec un copié/collé de ce qu'indique le suivi, comme si vous ne saviez pas lire. J'ignore si c'est volontaire, mais en pratique à moins d'un colis qui se volatilise sans avoir été indiqué comme livré, il est très difficile d'obtenir quoi que ce soit de leur part.
Citer : Posté le 15/12/2019 20:06 | #
Tu peux envoyer directement et à la même adresse, mon bureau de poste va garder les colis à partir de samedi
-Planétarium 2
Citer : Posté le 15/12/2019 20:34 | #
Ok, merci à toi.
Citer : Posté le 15/12/2019 21:03 | #
Mais tu pense expedier quand du coup ?
-Planétarium 2
Citer : Posté le 15/12/2019 21:13 | #
Pour ceux qui ont répondu ce soir, je vais faire le maximum pour que ça parte demain.
Citer : Posté le 15/12/2019 21:20 | #
Merci ça serait magnifique
-Planétarium 2
Citer : Posté le 15/12/2019 21:37 | #
Hop là ! Pour mon cas:
1) Envoi cette semaine
2) A l'adresse communiquée
3) De préférence en boite au lettre chez moi
4) Non
(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 15/12/2019 21:42 | #
Ok @Tituya.
Par contre, sauf erreur de ma part tu ne nous as pas communiqué tes nom et prénom.
Alors à moins que ton adresse soit individuelle, ça risque d'être difficile pour le facteur de savoir qui est Tituya.
Citer : Posté le 15/12/2019 21:44 | #
En effet J'avoue ne pas y avoir pensé, je préfère garder un anonymat maximal sur internet
J'envoie ça de suite par mail !
(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 15/12/2019 21:44 | #
Merci à toi.
Citer : Posté le 15/12/2019 21:46 | #
Envoyé
(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 16/12/2019 11:04 | #
Pour moi :
1) Envoi cette semaine
2) A l'adresse communiquée
3) Ma boite au lettre
4) Non pas d'assurance
Merci d'avance
Passé ici il y a peu. ಥ‿ಥ
Jouez à Mario sans arrêt sur votre Casio !
City Heroes
Piano Casio
Micro GIMP
Citer : Posté le 16/12/2019 18:31 | #
Merci @CaptainLuigi.
Ton colis est affranchi, il part demain.
Hormis sentaro21, tous les autres envois postaux demandés hier ont bien été déposés aujourd'hui avant la levée.
Sauf pour Pavel qui n'est pas en France métropolitaine, tous les autres vous avez donc des chances non négligeables d'une première tentative de livraison dès mercredi matin. En espérant que ça rentre en boîte à lettres, ou sinon qu'il y ait quelqu'un...
Vérifiez votre adresse courriel et si besoin le dossier des spams, vous devez normalement recevoir de la Poste le numéro de suivi, ainsi que les événements de suivi majeurs.
Pour ceux qui ont demandé des points relais c'est plus difficile. Entre ceux qui sont fermés pour les fêtes et ceux qui sont fermés le lundi... Je tente de déposer les quelques colis concernés demain tôt le matin ou sinon sur la pause méridienne.
Citer : Posté le 16/12/2019 20:36 | #
Merci Critor
-Planétarium 2
Citer : Posté le 16/12/2019 20:41 | #
Je dirais même un GRAND MERCI à Critor pour avoir préparé et envoyé 12 colis rien qu'aujourd'hui, et ce n'est clairement pas tout. Quelle organisation !
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