π
<-
Chat plein-écran
[^]

Concours de rentrée 2019 - défi de Python

Online

Re: Concours de rentrée 2019 - défi de Python

Unread postby critor » 17 Nov 2019, 17:36

Ne désespérez pas, les résultats arrivent. :)

L'annonce est déjà prête pour TI-Planet. Manque juste à finaliser celle pour Planète Casio.
Image
User avatar
critorAdmin.
Niveau 19: CU (Créateur Universel)
Niveau 19: CU (Créateur Universel)
Level up: 0.1%
 
Posts: 34208
Images: 8862
Joined: 25 Oct 2008, 00:00
Location: Montpellier
Gender: Male
Calculator(s):
Class: Lycée
YouTube: critor3000
Twitter: critor2000
Facebook: critor.ti

Re: Concours de rentrée 2019 - défi de Python

Unread postby Tituya » 17 Nov 2019, 17:42

Donc résultats ce soir ?
from
hype
import
*


:p
User avatar
TituyaPremium
Niveau 1: MD (Membre Débutant)
Niveau 1: MD (Membre Débutant)
Level up: 0%
 
Posts: 4
Joined: 15 Nov 2019, 00:02
Gender: Not specified
Class: TS

Re: Concours de rentrée 2019 - défi de Python

Unread postby Zocipal » 17 Nov 2019, 18:11

On a hâte !
Image
User avatar
ZocipalPremium
Niveau 9: IC (Compteur Infatigable)
Niveau 9: IC (Compteur Infatigable)
Level up: 34.4%
 
Posts: 83
Joined: 12 Sep 2019, 20:15
Location: Hauts-de-France
Gender: Male
Calculator(s):
Class: 1ère Maths Physique NSI

Online

Re: Concours de rentrée 2019 - défi de Python

Unread postby critor » 17 Nov 2019, 20:06

Voilà, c'est fait, désolé pour l'attente : :)
viewtopic.php?f=49&t=23140&p=248090#p248088
Image
User avatar
critorAdmin.
Niveau 19: CU (Créateur Universel)
Niveau 19: CU (Créateur Universel)
Level up: 0.1%
 
Posts: 34208
Images: 8862
Joined: 25 Oct 2008, 00:00
Location: Montpellier
Gender: Male
Calculator(s):
Class: Lycée
YouTube: critor3000
Twitter: critor2000
Facebook: critor.ti

Online

Re: Concours de rentrée 2019 - défi de Python

Unread postby Afyu » 18 Nov 2019, 23:18

Voici comment j'ai procédé pour la résolution du défi Python dont j'ai découvert l'existence vers le 16 ou 17 octobre :

Après avoir effectué quelques test manuellement, j'ai écrit un programme en Python pour optimiser ma recherche.
J'ai récupéré la ressource
NumWorks
proposée pour le concours, que j'ai complétée.

L'idée est de tester des mains de 10
Pokémon
et de comparer chaque nouveau score obtenu avec le meilleur score obtenu jusqu'à présent.

J'ai donc créé une liste qui va contenir le meilleur score (ou plutôt les meilleurs scores successifs obtenus au cours de la recherche).
J'aurais pu créer une variable globale pour stocker mon meilleur score, mais ne maitrisant pas la syntaxe pour ça, j'ai préféré créer une liste scoreliste qui s'allonge avec chaque nouveau meilleur score. Il suffit alors de prendre scoreliste[-1] pour récupérer le dernier élément, donc le meilleur score.
Et j'ai fait de même pour les codes avec codeliste. Par la suite, j'ai créé une variable score_max qui stocke la valeur scoreliste[-1].

Je tenais à avoir la liste des
Pokémon
et des puissances associées de chacun de mes meilleurs scores. C'est pour cette raison que j'affiche le meilleur score scoreliste[-1], le code associé codeliste[-1] ainsi que la liste des
Pokémon
pokemon et la liste des puissances associées attaque.

La première ligne est écrite avec un >= et non pas un > pour stocker un nouveau score s'il est meilleur que le dernier meilleur score obtenu, ou s'il est égal à ce dernier. C'est peut-être peu pertinent, mais ça permet de changer de temps en temps la liste des
Pokémon
ou des puissances sur laquelle le programme effectue ses tests, même si le meilleur score n'évolue plus.
Code: Select all
if score>=score_max:
  atta.append(attaque[:])
  poke.append(pokemon[:])
  if score>score_max:
    print(scoreliste[-1],iii)
    print("#",score,codeliste[-1])
    print("# poke",poke[-1])
    print("# atta",atta[-1])
    print("")
  score_max=score


J'ai initialisé ma liste des
Pokémon
pokemon et ma liste des puissances attaque avec des 1, je crois.
Code: Select all
pokemon=[1, 1, 1, 1, 1, 1, 1, 1, 1, 1] (ou pokemon=[1]*10)
attaque=[1, 1, 1, 1, 1, 1, 1, 1, 1, 1] (ou attaque=[1]*10)

Je remplis la main avec la boucle :
Code: Select all
for kkk in range(10):
  pk(pokemon[kkk],attaque[kkk])

Et je la vide avec la boucle :
Code: Select all
for jjj in range(10):
  pk(pokemon[jjj],0)

J'ai commencé mes recherches en remplaçant une puissance d'attaque par un nombre tiré aléatoirement. Le rang de l'attaque est également choisi aléatoirement entre 0 et 9, ce qui désigne un des 10
Pokémon
de la main.
Code: Select all
rang=randint(0,9)
attaque[rang]=randint(1,200)


Dans un second programme, je cherche en modifiant non pas l'attaque des
Pokémon
, mais leur numéro parmi les 94 disponibles avec des nombres tirés aléatoirement, encore une fois :
Code: Select all
rang=randint(0,9)
pokemon[rang]=randint(1,94)


Je récupère ma meilleure main de
Pokémon
, avec les puissances associées, et je fais travailler mes deux programmes sur chaque meilleure main trouvée, en la changeant lorsqu'elle est améliorée.

Après quelques essais (ici 10), je reprends ma recherche avec comme liste de départ la dernière meilleure main obtenue. Et j'effectue des changements sur cette main pour espérer améliorer mon score. Je ne repars pas d'une main totalement aléatoire à chaque fois que j'améliore mon meilleur score.
Code: Select all
if nb_chgt==10:
  attaque=atta[-1] (ou pokemon=poke[-1] dans l'autre programme)


Après quelques min...jours de calculs, j'ai obtenu un score proche de 49,3154 avec O#0K_g^huS""1""h"""" mais qui est enregistré dans le tableau des participations sous un score un peu inférieur : 49,31486.
Mon meilleur score ne s'améliorant plus, j'ai changé mon approche. J'ai essayé de modifier les puissances d'attaque, mais de 1 en 1. Je choisis un
Pokémon
aléatoirement, dans ma meilleure main trouvée jusqu'alors et je modifie la puissance de ce
Pokémon
de 1. (donc j'ajoute 1 ou je retranche 1).
Code: Select all
rang=randint(0,9)
attaque[rang]+=2*randint(0,1)-1


En tirant un entier aléatoirement valant 0 ou 1, puis en prenant son double (donc 0 ou 2) et enfin en lui retranchant 1, on obtient un entier qui vaut -1 ou 1.
Les deux lignes de code précédentes peuvent être compactées en une seule :
Code: Select all
attaque[randint(0,9)]+=2*randint(0,1)-1

J'ai abandonné ma première syntaxe en une ligne :
Code: Select all
attaque[randint(0,9)]=attaque[randint(0,9)]+2*randint(0,1)-1
au profit d'une écriture avec un += parce que les deux nombres tirés aléatoirement avec randint(0,9) sont très souvent différents, et ça ne m'intéresse pas.

Avec cette nouvelle approche, j'ai de nouveau pu améliorer mon meilleur score pour atteindre 49,31730 et même 49,31859 (le 19/10) et 49,31975 le 19/10 au soir !
Code: Select all
49.31730339247606
'O#0K_g^huS""3""f""""'
poke [51, 85, 72, 62, 71, 63, 43, 16, 3, 47]
atta [4, 4, 61, 2, 2, 235, 3, 2, 3, 3]

49.3185945083636
'O#0K_g^huS""3""g""""'
poke [51, 85, 72, 62, 71, 63, 43, 16, 3, 47]
atta [2, 3, 61, 2, 2, 239, 2, 4, 2, 2]

Cette nouvelle approche m'a montré à chaque nouveau meilleur score que les puissances d'attaque de tous mes
Pokémon
se rapprochaient toujours plus de 2, sauf pour 2
Pokémon
.
J'ai fini par essayer, à la main, des puissances d'attaque toutes égales à 2, sauf pour les deux
Pokémon
exception.
Et j'ai modifié mon programme pour que l'ajustement des puissances ne se fasse que pour les deux
Pokémon
exception.

Les deux
Pokémon
en question étant placés en position 2 et 5, j'ai donc modifié mon choix du rang pour :
Code: Select all
rang=3*randint(0,1)+2
qui donne un nombre entier aléatoire qui vaut 2 ou 5.

Oui ? De quoi ? J'aurais pu tout simplement mettre les deux
Pokémon
en question en position 0 et 1 et tirer un nombre entier entre 0 et 1 avec randint(0,1) ? Euh...bah...euh... c'est pas faux. Bien vu ! pfff xD
Mais pourquoi faire simple quand on peut faire compliqué ? :D

Avec les deux dernières puissances proches de 60 et de 230, j'ai obtenu les scores 49,3188 et 49,3197. Puis pour des puissances d'attaque à 35 et à 143 et à 1 pour les 8 autres
Pokémon
, j'ai obtenu le score ultime de 49,3207 (le 21/10) !!
Code: Select all
49.31975298152274
'O#0K_g^huS""3""h""""'
poke [51, 85, 72, 62, 71, 63, 43, 16, 3, 47]
atta [2, 2, 58, 2, 2, 234, 2, 2, 2, 2]

49.32078546995182
'O#0K_g^huS""3""i""""'
poke [51, 85, 72, 62, 71, 63, 43, 16, 3, 47]
atta [1, 1, 35, 1, 1, 143, 1, 1, 1, 1]

Super enthousiaste (naïvement ? Peut-être bien, oui... :(), j'envoie mes scores à Critor en espérant que la différence d'évaluation ne soit pas trop grande... et là c'est le drame ! Mes codes valent en fait 49,3151. La looooooose !

Je suis donc allé éplucher le forum et j'ai compris que les codes étaient passés dans la moulinette setst() pour retrouver le score et que c'est ce score qui est validé et ajouté dans le tableau des participations.
J'ai donc modifié mon programme en conséquence, en calculant le score avec setst("code_obtenu") avant de le comparer à mon meilleur score.
Code: Select all
score=setst(codeliste[-1])

J'ai finalement compris (alors que c'était expliqué sur le forum, depuis le début du défi ! Mais quand on ne sait pas lire, hein...) que si la somme des puissances dépasse 100, alors toutes les puissances sont réduites par la fonction setst(), avec le même coefficient multiplicateur, pour que leur somme ne dépasse plus 100, puis arrondies à l'unité. Si les puissances réduites sont trop petites, alors l'arrondi à l'unité donne 0, ce qui explique la disparition de certains
Pokémon
de la main lorsqu'on ajoute un
Pokémon
avec une trop grande puissance.
La liste pkl contient le numéro de chaque
Pokémon
de la main, ainsi que sa puissance associée et un troisième nombre. Ce dernier nombre est la valeur retenue, après réduction et arrondi à l'unité.
J'ai donc découvert que mon 35 devient 18 et que mon 143 devient 72.
Pour respecter la proportionalité, il aurait au moins fallu avoir 17,5 et 71,5 (et 0,5 pour les 8 autres puissances, du coup ?).

Après quelques essais, j'ai vu que la somme des puissances pouvait être comprise entre 93 et 97. Mais même avec cette petite tolérance, je n'ai pas réussi à retrouver de très bons scores.

Après des heures de calcul, uniquement sur les deux puissances différentes de 1, pas moyen d'obtenir de nouveau un score supérieur à 49,3185... très déçu, j'abandonne et me lance dans la résolution du 3ème défi.
Le dernier jour ouvert pour la participation, vers 22h45, je me décide à lancer un ultime calcul. Le calcul de la dernière chance. Juste avant, je vais éplucher le forum, une fois encore, à la recherche d'une bonne idée. Je découvre qu'il est possible de passer des caractères codés avec un \ suivi d'un nombre. viewtopic.php?f=49&t=23011&start=190#p247491

J'ai sauté sur l'occasion et j'ai testé à la main quelques caractères écrits avec cette nouvelle écriture, jusqu'à retrouver mes 3 très bons scores au-dessus de 49,318 !! Un de ces trois scores n'avait pas encore été soumis, d'après le tableau des participations, alors j'en profite, j'envoie 2 mails (à 23h40 et 23h52 ! Plus que 8 min, tic tac tic tac !!).

Ces codes ressemblent à ça, le 35 et le 143 étant remplacés par des caractères codés avec un \ suivi d'une chaîne de caractère :
Code: Select all
setst('O#0K_g^huS""\x3D""\x99""""')
49.318885384185236

setst('O#0K_g^huS""\x42""\xB2""""')
49.31951877543954

Et finalement, un participant est sorti de nulle part en soumettant 18 codes, en réservant la plupart des codes encore dispo, juste quelques heures avant moi.
Tant pis, je suis finalement 9ème. Mais je suis content d'avoir essayé jusqu'au bout et d'avoir trouvé une main qui donne un score de 49,3207 si on ne le repasse pas dans la moulinette setst() et qui n'utilise pas de caractères bizarres commençant par un \.

Je remercie grandement toutes les personnes qui ont permis à ce concours d'exister et qui ont permis d'avoir autant de lots très intéressants !

Je donne ici mon script complet, même pas nettoyé pour montrer mes traces de recherches.

Code: Select all
#score=[]
codeliste=[0]
scoreliste=[0]
#cas
from math import *
def mmod(a,b):
  return a%b
#0 Nspire MicroPython
#1 NumWorks Python
#2 G90/35+E2 Python
#3 G75/85/95 CasioPython
#4 83PCE Python/PyAdapt
#5 HP Prime CAS
#6 G90/35+E2 KhiCAS
def getplatform():
  k=-1
  try:
    if chr(256)==chr(0):
      k=[6,5][("HP" in version())>0]
  except:
    pass
  if k>=0:
    return k
  try:
    import sys
    try:
      if sys.platform=="nspire":
        k=0
      elif sys.platform.startswith("TI-Python"):
        k=4
    except:
      k=3
  except:
    try:
      import kandinsky
      k=1
    except:
      k=2
  return k
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
lnm=["Bulbizarre","Herbizarre","Florizarre","Salameche","Reptincel","Dracaufeu","Carapuce","Carabaffe","Tortank","Chenipan","Chrysacier","Papilusion","Aspicot","Coconfort","Dardargnan","Roucool","Roucoups","Roucarnage","Rattata","Rattatac","Piafabec"]
lnm.extend(["Rapasdepic","Abo","Arbok","Pikachu","Raichu","Sabelette","Sablaireau","Nidoran F","Nidorina","Nidoqueen","Nidoran M","Nidorino","Nidoking","Melofee","Melodelfe","Goupix","Feunard","Rondoudou","Grodoudou","Nosferapti","Nosferalto"])
lnm.extend(["Mystherbe","Ortide","Rafflesia","Paras","Parasect","Mimitoss","Aeromite","Taupiqueur","Triopikeur","Miaouss","Persian","Psykokwak","Akwakwak","Ferosinge","Colossinge","Caninos","Arcanin","Ptitard","Tetarte","Tartard","Abra","Kadabra"])
lnm.extend(["Alakazam","Machoc","Machopeur","Mackogneur","Chetiflor","Boustiflor","Empiflor","Tentacool","Tentacruel","Racaillou","Gravalanch","Grolem","Ponyta","Galopa","Ramoloss","Flagadoss","Magneti","Magneton","Canarticho","Doduo","Dodrio","Otaria"])
lnm.extend(["Lamantine","Tadmorv","Grotadmorv","Kokiyas","Crustabri","Fantominus","Spectrum","Ectoplasma"])
na,pkl=21,[]
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 :")
      scoreliste.append(float(t))
      codeliste.append(""+st)
      #score.append(setst(st))
    #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]),k+1>=n)
  return s
print("pk(n,p) pour rajouter\nle Pokemon n a ta main\navec p points d'attaque.")
#end




score_max=0
poke=[]
atta=[]
pokemon=[57, 72, 5, 43, 3, 69, 89, 62, 63, 16]
#attaque=[1, 1, 1, 1, 1, 1, 1, 1, 59, 236]
#pokemon=[51, 85, 72, 62, 71, 63, 43, 16, 3, 47]
#dd=9
attaque=[1, 1, 17, 1, 1, 68, 1, 1, 1, 1]
#pokemon=[1]*10
#attaque=[dd]*10
nb_chgt=0

from random import randint

for iii in range(50):
  #pokemon=[randint(1,94) for y in range(10)]
  #attaque=[randint(1,200) for y in range(10)]
  if iii>0: # et si iii vaut 0, on évite cette boucle et on ajoute un premier score non nul dans scoreliste
    #pokemon[randint(0,9)]+=2*randint(0,1)-1#randint(1,94)
    #rang=randint(0,9)
    rang=3*randint(0,1)+2
    #pokemon[randint(0,9)]=randint(1,94)
    #attaque[rang]-=1
    #attaque[rang]=max(attaque[rang]+2*randint(0,1)-1,1)
    #rang=randint(0,9)
    #rang=8-rang #3*randint(0,1)+2
    #pokemon[rang]=randint(1,94)
    #attaque[rang]=max(1,93-(sum(attaque[:])-attaque[rang]))
    #attaque[rang]=randint(1,50)
    attaque[rang]+=2*randint(0,1)-1
    #attaque[3*randint(0,1)+2]+=1*(2*randint(0,1)-1)
  for kkk in range(10):
    pk(pokemon[kkk],attaque[kkk])
  score=setst(codeliste[-1]) # ici le vrai score
  if score>=score_max:
    atta.append(attaque[:])
    poke.append(pokemon[:])
    #code=codeliste[-1]
    if score>score_max:
      print(scoreliste[-1],iii) # ici le score avant évaluation dans setst()
      print("#",score,codeliste[-1])
      #print("#",setst(code))
      print("# poke",poke[-1])
      print("# atta",atta[-1])
      print("")
    score_max=score
  for jjj in range(10):
      pk(pokemon[jjj],0)
  nb_chgt+=1
  if nb_chgt==20:
    #pokemon=poke[-1]
    attaque=atta[-1]
Last edited by Afyu on 25 Nov 2019, 20:35, edited 1 time in total.
User avatar
AfyuPremium
Niveau 3: MH (Membre Habitué)
Niveau 3: MH (Membre Habitué)
Level up: 37.5%
 
Posts: 30
Joined: 30 Oct 2019, 19:17
Gender: Male
Calculator(s):
Class: plutôt, oui :)

Online

Re: Concours de rentrée 2019 - défi de Python

Unread postby critor » 18 Nov 2019, 23:52

Ah, merci à toi. :)
Image
User avatar
critorAdmin.
Niveau 19: CU (Créateur Universel)
Niveau 19: CU (Créateur Universel)
Level up: 0.1%
 
Posts: 34208
Images: 8862
Joined: 25 Oct 2008, 00:00
Location: Montpellier
Gender: Male
Calculator(s):
Class: Lycée
YouTube: critor3000
Twitter: critor2000
Facebook: critor.ti

Previous

Return to News Divers

Who is online

Users browsing this forum: No registered users and 6 guests

-
Search
-
Featured topics
Omega, le fork étendant les capacités de ta NumWorks, même en mode examen !
Comparaisons des meilleurs prix pour acheter sa calculatrice !
Concours TI-Planet-Casio de rentrée 2019. 3 défis pour plus d'une 15aine de calculatrices graphiques et nombre de goodies sortant de l'ordinaire ! :D
123
-
Donations / Premium
For more contests, prizes, reviews, helping us pay the server and domains...

Discover the the advantages of a donor account !
JoinRejoignez the donors and/or premium!les donateurs et/ou premium !


Partner and ad
Notre partenaire Jarrety 
-
Stats.
860 utilisateurs:
>816 invités
>39 membres
>5 robots
Record simultané (sur 6 mois):
6892 utilisateurs (le 07/06/2017)
-
Other interesting websites
Texas Instruments Education
Global | France
 (English / Français)
Banque de programmes TI
ticalc.org
 (English)
La communauté TI-82
tout82.free.fr
 (Français)