189 lines
5.1 KiB
Python
189 lines
5.1 KiB
Python
from math import *
|
|
from random import *
|
|
from time import *
|
|
|
|
def mmod(a,b):
|
|
return a%b
|
|
def getplatform():
|
|
return 1
|
|
def getlinechars(o=False):
|
|
c,k=2**31-1,getplatform()
|
|
if k>=0:
|
|
c=[53,o and 99 or 29,o and 509 or 21,31,32,c,c][k]
|
|
return c
|
|
na,pkl,lnm=21,[],["Bulbizarre","Herbizarre","Florizarre","Salameche","Reptincel","Dracaufeu","Carapuce","Carabaffe","Tortank","Chenipan","Chrysacier","Papilusion","Aspicot","Coconfort","Dardargnan","Roucool","Roucoups","Roucarnage","Rattata","Rattatac","Piafabec","Rapasdepic","Abo","Arbok","Pikachu","Raichu","Sabelette","Sablaireau","Nidoran F","Nidorina","Nidoqueen","Nidoran M","Nidorino","Nidoking","Melofee","Melodelfe","Goupix","Feunard","Rondoudou","Grodoudou","Nosferapti","Nosferalto","Mystherbe","Ortide","Rafflesia","Paras","Parasect","Mimitoss","Aeromite","Taupiqueur","Triopikeur","Miaouss","Persian","Psykokwak","Akwakwak","Ferosinge","Colossinge","Caninos","Arcanin","Ptitard","Tetarte","Tartard","Abra","Kadabra","Alakazam","Machoc","Machopeur","Mackogneur","Chetiflor","Boustiflor","Empiflor","Tentacool","Tentacruel","Racaillou","Gravalanch","Grolem","Ponyta","Galopa","Ramoloss","Flagadoss","Magneti","Magneton","Canarticho","Doduo","Dodrio","Otaria","Lamantine","Tadmorv","Grotadmorv","Kokiyas","Crustabri","Fantominus","Spectrum","Ectoplasma"]
|
|
mrandmax,mrand,mfmax,nn,mp=2**31-1,0,93,getlinechars(True)-na,na//2
|
|
def mround(f):
|
|
d=mmod(abs(f),1)
|
|
return (mfloor(abs(f))+(d>=.5))*(1-2*(f<0))
|
|
def mfloor(f):
|
|
return round(f)-(round(f)>f)
|
|
def mceil(f):
|
|
return round(f)+(round(f)<f)
|
|
def mseed(s):
|
|
global mrand
|
|
mrand=mmod(s,mrandmax)
|
|
def mrandom():
|
|
mseed(mrand*16807)
|
|
return float(mrand/mrandmax)
|
|
def muniform(mini,maxi):
|
|
return mrandom()*(maxi-mini)+mini
|
|
def mrandint(mini,maxi):
|
|
return mround(muniform(mceil(mini),mfloor(maxi)))
|
|
def f2mf(f):
|
|
return mround(float(f*mfmax))
|
|
def mf2f(n):
|
|
return float(n/mfmax)
|
|
def mbit(a,b):
|
|
return mmod((a//(2**b)),2)
|
|
def getattack(p,pts):
|
|
global pkt
|
|
mseed(42)
|
|
for k in range(p+1):
|
|
mrandom()
|
|
a,pka=mrandint(1,mrandmax),""
|
|
for j in range(na):
|
|
if mbit(a,j)!=0:
|
|
pka+="X"
|
|
pkt[j]+=pts
|
|
else:
|
|
pka+=" -"[getplatform()>=5]
|
|
return pka
|
|
def i2c(k):
|
|
return chr(k+33)
|
|
def c2i(c):
|
|
return ord(c)-33
|
|
def clean():
|
|
global pkl
|
|
t,s=0,0
|
|
for l in pkl:
|
|
t+=l[1]
|
|
for l in pkl:
|
|
l[2]=f2mf(l[1]/(t or 1))
|
|
s+=l[2]
|
|
if(l[2]<=0):
|
|
pkl.remove(l)
|
|
return clean()
|
|
return s
|
|
def pk(n,p=1,d=2):
|
|
global pkt, pkl
|
|
n-=1
|
|
if n>=0 and n<len(lnm):
|
|
new=True
|
|
for k in range(len(pkl)):
|
|
if pkl[k][0]==n:
|
|
new,pkl[k][1]=False,max(p,0)
|
|
if new and len(pkl)<mp:
|
|
pkl.append([n,max(p,0),0])
|
|
ptt,pkt,t,st=clean(),[0 for k in range(na)],0,""
|
|
for l in pkl:
|
|
s=getattack(l[0],l[2]/ptt)
|
|
if d:
|
|
sn=" "+lnm[l[0]]
|
|
if len(sn)>nn:
|
|
sn=sn[:nn]
|
|
print(s+sn)
|
|
st=i2c(l[0])+st+i2c(l[2])
|
|
for k in pkt:
|
|
if(k):
|
|
t+=log(e+k*len(pkl))
|
|
if(d):
|
|
if(d>=2):
|
|
print("Bon score ? Si oui\nenvoie code suivant\na info@tiplanet.org :")
|
|
print(""+st)
|
|
return float(t)
|
|
def setst(st):
|
|
s,pkl[:],n=0,[],len(st)//2
|
|
for k in range(n):
|
|
s=pk(c2i(st[n-1-k])+1,c2i(st[n+k+len(st)%2]),False)
|
|
return s
|
|
|
|
pokemons = []
|
|
|
|
for l in range(94):
|
|
mseed(42)
|
|
for k in range(l + 1):
|
|
mrandom()
|
|
pokemons.append(mrandint(1, mrandmax))
|
|
|
|
def fast_score(code):
|
|
pkt = [0.0 for l in range(21)]
|
|
for k in range(10):
|
|
p = code[19 - k] / 93.0
|
|
for l in range(21):
|
|
if pokemons[code[k]] & (1 << l):
|
|
pkt[l] += p
|
|
size = 0
|
|
for k in range(10):
|
|
if code[19 - k] > 0:
|
|
size += 1
|
|
score = 0.0
|
|
for k in pkt:
|
|
if k:
|
|
score += log(e + k * size)
|
|
return score
|
|
|
|
def random_pokemon(code):
|
|
n = randint(0, 9)
|
|
v = randint(0, 93)
|
|
if not v in code[:10]:
|
|
code[n] = v
|
|
|
|
def random_attack(code):
|
|
score_max = fast_score(code)
|
|
for k in range(300):
|
|
while True:
|
|
i = randint(10, 19)
|
|
j = randint(10, 19)
|
|
if i != j:
|
|
break
|
|
d = randint(-93, 93)
|
|
vi = code[i] + d
|
|
vj = code[j] - d
|
|
if vi >= 0 and vi <= 93 and vj >= 0 and vj <= 93:
|
|
code_next = code.copy()
|
|
code_next[i] = vi
|
|
code_next[j] = vj
|
|
score_next = fast_score(code_next)
|
|
if score_max < score_next:
|
|
code[:] = code_next
|
|
score_max = score_next
|
|
|
|
seed(time())
|
|
|
|
code = [0 for k in range(20)]
|
|
code[19] = 93
|
|
|
|
score = fast_score(code)
|
|
|
|
code_max = code.copy()
|
|
score_max = score
|
|
|
|
# find team using simulated annealing
|
|
t = 1.0
|
|
while t > 0.0001:
|
|
t *= 0.999
|
|
code_next = code.copy()
|
|
random_pokemon(code_next)
|
|
random_attack(code_next)
|
|
score_next = fast_score(code_next)
|
|
if score_max < score_next:
|
|
code_max[:] = code_next
|
|
score_max = score_next
|
|
print('%.5f' % score_max, ''.join([chr(code_max[k] + 33) for k in range(20)]))
|
|
delta = score_next - score;
|
|
if delta >= 0 or random() < exp(delta / t):
|
|
code[:] = code_next
|
|
score = score_next
|
|
|
|
# find attack points using brute force
|
|
code_max = ''.join([chr(code_max[k] + 33) for k in range(20)])
|
|
for i in range(ord('2'), 256):
|
|
for j in range(ord('e'), 256):
|
|
code = code_max.replace('2', chr(i)).replace('e', chr(j))
|
|
score = setst(code)
|
|
if score_max < score:
|
|
score_max = score
|
|
print('%.5f' % score, code, i, j)
|
|
|