Avertissement :Il s'agit d'une page optimisée pour la navigation mobile. Voir la
page originale.
Optimisation.
Homer_Dalor le 24/05/2017 à 16:56
Coucou les gens.
Pour mon prochain programme, qui sera sûrement assez long (pas trop quand même), j'ai déjà effectué quelques "sous-programmes" (entre guillemets parce que ça en est pas en fait B| C'est juste des bouts de code :p
Du coup comme je sais que j'ai sûrement pas optimisé au max, je me tourne vers vous, afin de m'aider à trouver l'optimisation optimale (#pléonasme)
******************************************************************************
Je vais tout d'abord vous expliquer quoi que je fait dans ces différents "sous-programmes".
Voici le premier :
Ici, j'ai besoin d'une liste qui regroupe tout les nombres de 0 à 54 dans le désordre.
Code
:suite(X,X,1,54->L1
:54->dim(L2
:For(A,54,1,-1
:entAleat(1,A->B
:L1(B->L2(A
:L1(A->L1(B
:End
Celui-là je pense pas vraiment que ça soit optimisable :p
Du coup on passe à la suite.
***********************************************************************
Ici c'est un peu plus compliqué. Avec la liste créée juste auparavant, je vais faire 8 "piles" composés de respectivement de 1, 2, 3, 4, 5, 6, 7 et 26 valeurs, ensuite on fout tout ça dans une chaîne, en sachant que si on tombe sur la valeur 2 par exemple, elle devrait apparaître en "02".
ET avant toutes ces valeurs, on leur attribut 1 ou 0, 1 si c'est la dernière valeur de la pile, 0 si c'est pas la dernière.
Et pour finir, chaque pile devra être séparé d'une autre par le caractère "[", sachant qu'il y aura ce caractère au début et à la fin de la chaîne.
Voilà la théorie. Un exemple. Voici notre liste :
Code
{41,12,25,2,6,15,44,10,3,38
J'ai raccourci pour que ça soit pas trop long.
Cette liste devra donner ceci :
Code
"[141[012125[002006115[044010003138["
Voici donc le code que j'ai concocté :
Code
:"[-> Chaîne9
:For(A,1,8
:For(B,1,A+17(A=8
:L1(A(A-1)/2+1+B)/10
:Chaîne9+sous-chaîne("01",(B=A)+1,1)+sous-chaîne("012345",PartEnt(Rép),1)+sous-chaîne("0123456789",PartDec(Rép),1 -> Chaîne9
:End
:Chaîne9+"[->Chaîne9
:End
Voilà pour la deuxième partie, je me demande si j'ai bien expliqué... B|
***************************************************************************
La dernière partie que j'ai effectué pour l'instant se résume comme ceci :
On donne A le numéro de la pile, B la Bème valeur de cette pile,
et E une autre pile.
Le but de la manoeuvre est de déplacer toutes les valeur de la pile A en partant de la valeur B et de mettre ces valeurs à la fin de la pile E.
Exemple : Voici notre chaine :
Code
"[001[002003[004005006[007008009010["
On prend A=2, B=1, E=1, cela nous donnera :
Code
"[001002003[[004005006[007008009010["
Et du coup voici mon code un peu bourrin :
Code
:0
:For(D,1,A
:CarChaîne(Chaîne9,"[",Rép+1
:End
:Sous-Chaîne(Chaîne9,Rép+3B-2,carChaîne(chaîne9,"[",Rép+1)-Rép-3B+2->Chaîne8
:sous-chaîne(chaîne9,1,carChaîne(chaîne9,Rép,1)-1)+sous-chaîne(Chaîne9,carChaîne(chaîne9,Rép,1)+longueur(Rép),longueur(Chaîne9)-carChaîne(chaîne9,Rép,1)+1-longueur(Rép -> Chaîne9
:0
:For(D,1,E+1
:carChaîne(Chaîne9,"[",Rép+1
:End
:sous-chaîne(Chaîne9,1,Rép-1)+Chaîne8+sous-chaîne(Chaîne9,Rép,longueur(Chaîne9)-Rép+1
Voilà voilà, si quelqu'un se sent l'envie d'essayer d'optimiser ça si c'est possible, je lui souhaite bonne chance !
Et si quelqu'un a trouvé le programme que je veux faire, chut, c'est une surprise <3
Et si quelqu'un me dit "Pourquoi tu fais pas des listes ou une matrice?", je lui répond : "J'aime pas la simplicité". Et c'est pour des raisons de place aussi

Mingerton le 25/05/2017 à 02:27
Eh ba le premier on va faire comme sur ton dernier code, un rand sans répétition :
Code
NbrAléat(54ü (
) L2
suite(X,X,1,54ü (
) L1
TriCroi(L2,L1
Ici c'est pour une liste de 1 à 54, comme dans ton code.
***********************************
J'ai un peu de mal à comprendre ton code je vais pas te mentir. Après je ne l'ai pas essayé car pas de machine sous la main.
Sur ton code, un truc pour économiser un octet : /10 devient .1 avant le terme.
En premier jet je donnerais le code suivant, mais il m'a l'air clairement plus lourd donc je le mets au cas où mais c'est pas de l'optimisation :
// Notations anglaises, j'ai toujours codé en anglais donc c'est plus naturel comme ça pour moi. Traductions en bas de mon message
// L1 est notre liste d'entiers aléatoires
Code
"[ü (
) Str9
DelVar BFor(I,1,dim(L1
If sum(I=augment(seq(X,X,1,7),{26
Then
seq(L1(X),X,B+1,B+Iü (
) L2
B+Iü (
) B
For(A,1,I
{0,1ü (
) L3:{0,L2(Aü (
) L4 //Ces quatres lignes
LinReg(ax+b) L3,L4,Y1 //correspondent à la
Equ>String(Y1,Str1 //conversion du terme
sub(Str1,1,length(Str1-3 //de la liste en chaîne
If 9ù (
) L1(A
"0"+Ans
sub("01",1+(A=I),1)+Ans
Str9+Ansü (
) Str9
End
Ans+"[ü (
) Str9
End
End
***********************************
Voilà un code pour se passer des boucles For() qui ralentissent significativement l'exécution :
Code
".5X(3X+5ü (
) Y1
Y1(Aü (
) U:Y1(Eü (
) V
length(Str9ü (
) Z
3B-2+Y1(A-1ü (
) Y
sub(Str9,Y+1,3(A-B+1
If E<A
sub(Str9,1,V)+Ans+sub(Str9,V+1,Y-V)+sub(Str9,U+1,Z-U
If E>A
sub(Str9,1,Y)+sub(Str9,U+1,V-U)+Ans+sub(Str9,V+1,Z-V
If E=A
Str9
Il y a certainement une optimisation supplémentaire à faire en résumant en une seule ligne en utilisant correctement un max ou un min(E,A). Je la vois pas encore clairement par contre.
*******************************************************************
Pour les notations anglaises:
sub() == sous-chaine()
Ans == Rep
length() == longueur()
Str9 == Chaine9
rand == NbrAléat
DelVar == EffVar
sum() == somme()
augment() == chaine()
seq() == suite()
Equ>String == Equ>Chaine
Et les caractères bizarres comme ü et ù sont des abréviations du site pour les caractères spéciaux, passe ta souris dessus pour voir la correspondance.
Homer_Dalor le 25/05/2017 à 16:54
Coucou :3
Merci de t'être penché dessus <3
****************************************************************************
Je crois que je suis un boulet, ne pas me souvenir que sur la roulette y a aussi un aléatoire sans doublons, faut le faire B| Je me repends !
****************************************************************************
Euh, je crois que t'es parti trop loin là
****************************************************************************
Ici, je me suis mal exprimé, cet opération de "transfert de valeurs", on la fera plusieurs fois, donc la chaîne ne sera pas toujours composé que d'une valeurs pour la première pile, pareil pour les suivantes.
****************************************************************************
Désolé pour le temps perdu ^^'
En tout cas quand t'optimises, t'y vas pas de main-morte, tu vas chercher loin :o La classe
Plein de bisous !

Mingerton le 25/05/2017 à 17:12
Ouais le deuxième code c'est un sacré bordel, il fonctionne mais plutôt lent à cause des boucles for imbriquées. Sinon il n'est pas si compliqué qu'il en a l'air, ce que j'ai fait avec Linreg et Equ>String est un code classique pour convertir un nombre en chaîne de caractère, le reste en plutôt intuitif si tu y regardes de près.
Ah oui si on fait plusieurs fois l'opération on va bel et bien avoir besoin de carchaine pour voir les positions des piles.
Ou alors : une idée serait de garder dans une liste à part les longueurs les piles et de la changer à chaque fois que l'on fait l'opération. De cette manière, on pourra faire très rapidement les déplacements, et sans boucle For(). Je me penche là dessus et j'édite mon message quand j'ai un truc viable.
EDIT :
Avec l'idée des listes et une généralisation de la fonction Y1, on peut proposer ceci :
L6 est la liste des longueurs des piles. Initialement elle va être à {1,2,3,4,5,6,7,26} sur ton exemple
Code
L6+3cumSum(L6ü (
) L5
L5(Aü (
) U:L5(Eü (
) V
length(Str9ü (
) Z
3B-2+L5(A-1ü (
) Y
sub(Str9,Y+1,3(A-B+1ü (
) Str0
If E<A and L6(A
sub(Str9,1,V)+Ans+sub(Str9,V+1,Y-V)+sub(Str9,U+1,Z-Uü (
) Str9
If E>A and L6(A
sub(Str9,1,Y)+sub(Str9,U+1,V-U)+Ans+sub(Str9,V+1,Z-Vü (
) Str9
length(Str0)/3ü (
) C
L6(A)-Cü (
) L6(A:C+L6(Eü (
) L6(E
(L6>0)L6ü (
) L6
Normalement c'est fonctionnel avec n'importe quelle chaîne, il me semble qu'il n'y avait que la fonction Y1 qui était spécifique aux longueurs des piles.
Pas testé encore une fois, j'espère qu'il n'y a pas de problèmes avec les exécutions successives, c'est courant sur ce genre de programme.
J'ai ajouté quelques tests, ca doit être optimisable encore
m@thieu41 le 28/05/2017 à 14:56
Salut!
J'ai une petite question avant de me pencher sur l'optimisation:
Est-ce que c'est normal qu'au début tu t'embêtes à mettre 1 ou 0, 1 si c'est la dernière valeur de la pile, 0 si c'est pas la dernière pour ne plus en prendre compte lorsque tu déplace les piles ? (""[001002003[[004005006[007008009010["" ici aucun nombre n'a 1 en préfixe c'est normal ?)
Citation
Et si quelqu'un me dit "Pourquoi tu fais pas des listes ou une matrice?", je lui répond : "J'aime pas la simplicité". Et c'est pour des raisons de place aussi
Tu aimes bien les chaines de caractère toi

C'est vraiment pas la manière simple haha
Homer_Dalor le 28/05/2017 à 21:23
Perfect Mingerton ton code <3 Il marche super bien

Faut que je vois ce qui prend le plus de place, mon code, ou le tien en comptant les listes (Ouai c'est pas vraiment de la performance que je veux c'est surtout le moins de place possible, bon, après entre un code qui prend 2 octets de plus et un qui fait perdre 2min, mon choix est vite fait \o )
************************************************************************
M@thieu41, oui, c'est normal que je me fasse chier, parce que après quand y aura des modif dans les valeurs, ça sera pas tout le temps que la dernière de la pile qui aura un 1, parfois même il n'y en aura aucun :p
(Après, faut que je vois aussi si ça prendrait pas moins de place en mettant une liste avec le nombre de valeurs qui ont un 1 devant, je verrai :p )
Oui, j'aime les chaînes de caractères B| C'est la classe !
Mingerton le 28/05/2017 à 21:47
Quand tu travailles avec des chaînes ou des listes très longues le truc à éviter à tout prix c'est de parcourir avec deux boucles For (ce que tu fais dans ton code d'origine), c'est aussi ca une partie du travail d'optimisation.
J'ai pas vérifié quel code était le plus lourd, mais à vue de nez le code final va dépasser les 1000 octets si il y a d'autres fonctionnalités, donc tu seras pas à 100 octets près je pense

m@thieu41 le 29/05/2017 à 09:25
Vu que je pense savoir quel jeu tu veux faire, pour te simplifier la vie je te propose de stocker dans une liste le rang à partir duquel les valeurs sont déplaçables, plutôt que de le faire avec un 1 ou un 0 devant. Ca te permettra de déterminer le B pour ton deuxième code beaucoup plus vite.
(Une liste à 7 éléments avec au rang i le nombre de valeurs déplaçables sur la pile i).
Combiné avec la proposition de Mingerton de stocker les longueurs des piles, tu devrais pouvoir faire un déplacement beaucoup plus efficace.Homer_Dalor le 19/06/2017 à 02:59
Yo les gars !
Merci M@th, en effet j'avais voulu voir trop compliqué, j'ai refait avec ta méthode, c'est beaucoup mieux :p
Je reviens tout de même vers vous, car j'ai du coup un nouveau code, que je trouve classe. Ouai, je me lance moi-même des fleurs.
Du coup maintenant, voilà comment ça se passe :
J'ai 52 valeurs (Parce que ouai en fait c'est pas 54 mais 52 et quand je m'en suis rendu compte j'ai voulu m'insulter en allemand.).
J'ai donc 52 valeurs que j'ai foutu dans une chaîne (Bah ouai, j'aime les chaînes donc je reste dessus).
Pour chaque valeur, deux chiffre, donc pour 5 dans la chaîne ça sera 05.
Ma chaîne est donc de ce style :
J'ai à coté une liste qui recense la nombre de valeur dans chaque pile.
(La liste commence à partir de Lx(8 ))
Au début du programme, la liste devra être exactement celle ci :
Code
{0,1,2,3,4,5,6,1,2,3,4,5,6,7,24,1}
Donc pour cette partie voilà mon code :
Code
:NbrAleat(52->L2
:suite(X,X,1,52->L1
:TriCroi(L2,L1
:"
:For(A,1,52
:Rép+sous-chaîne("012345",1+PartEnt(.1L1(A)),1)+sous-chaîne("0123456789",1+10PartDec(.1L1(A)),1
:End
:sous-Chaîne(Rép,2,104->Chaîne9
:suite(X,X,1,7
:chaîne(Rép-1,Rép
:chaîne(Rép,{24,1->Lx
Ensuite c'est comme avant, on déplace toutes les valeurs de la pile A en partant de la valeur N° B et on les met à la fin de la pile C.
Voilà le code :
Code
:somme(suite(Lx(X),X,8,A+7->D
:somme(suite(Lx(X),X,A+8,15->E
:0
:If A-1:somme(suite(Lx(7+X),X,1,A-1
:Rép->F
:sous-Chaîne(Chaîne9,2F+2B-1,2(Lx(A+7)-B+1->Chaîne8
:expr(sous-Chaîne("sous-chaîne(Chaîne9,1,2F+2B-2)+sous-Chaîne(Chaîne9,2D+1,longueur(Chaîne9)-2D",1+14(A+B=2),13+(A+B=2)+15(E et A+B!=2->Chaîne9
:Lx(A)-B+1+Lx(C->H
:B-1->Lx(A+7
:somme(suite(Lx(X),X,C+8,15->G
:somme(suite(Lx(X),X,8,C+7
:expr(sous-chaîne("sous-Chaîne(Chaîne9,1,2Rép)+Chaîne8+sous-Chaîne(Chaîne9,2Rép+1,longueur(Chaîne9)-2Rép",1+9non(Rép),10+6non(Rép)+15(Rép et G->Chaîne9
:H->Lx(C+7
Sauf que j'ai l'impression d'être parti beaucoup trop loin pour pas grand chose B|
Bref, il manque juste une condition au cas où c'est toute la chaîne qu'on déplace en même temps, mais je sais comment faire ça :p
Auriez-vous quelconque optimisation/façon de mieux faire ?
m@thieu41 le 03/07/2017 à 12:03
Yo !
Désolé pour le temps de réponse
------------------
Personnellement, je pense à une autre solution n'utilisant pas les chaines:
En utilisant 2 listes.
La première contient 8+52 valeurs.
Les 8 premières contiennent le numéro de la première carte sur la i eme pile (pour une ième valeur <= 8 ), et 0 s'il n'y en a pas.
Les 52 suivantes contiennent le numéro de la carte sur laquelle repose la ( i-8 )ème carte (pour un indice i>=9), et 0 si c'est la dernière.
Par exemple:
{5,0,3,8,9,15,12,14, 0,22,13,11,1...
Signifie que la pile 1 contient les cartes 5 et 1 dans cet ordre, la pile 2 n'en contient pas, la 3e contient les cartes 13...
La seconde liste indique à l'indice i si la ième carte est retournée. (par valeurs 0/1)
--
La génération sera un peu pénible (et encore pas tant que ça, et pas forcément plus que celui avec des chaines) mais le déplacement est instantané et facile à faire (il suffit de modifier les 1ères cartes des 2 piles concernées et la carte suivant de celle déplacée)
--------------------------------
Pour revenir à tes chaines
Ton code me parait assez bien, je ne vois pas d'optimisation flagrante dans la façon de faire.
A quel moment c'est possible de déplacer toute la chaine ?
Homer_Dalor le 11/07/2017 à 22:30
Coucou, désolé aussi pour le temps de réponse
Il est possible de déplacer toute la chaîne si il ne reste plus de carte dans le tas et qu'il n'y a plus qu'une seule pile de carte qu'on lui demande de déplacer sur une autre pile.
Ton idée de deux listes est sympa, je vais voir ce qui serait le mieux

m@thieu41 le 24/08/2017 à 20:40
J'étais pas en France, je n'ai pas pu suivre le forum depuis un moment ^^
Tu en es où dans ton code ?
Dans ce cas une simple condition longueur de la chaine = nombre de cartes dans la pile à déplacer * 2 suffit à détecter le cas problématique (mais qui normalement dans ton jeu n'arrive jamais

)
Avertissement :Il s'agit d'une page optimisée pour la navigation mobile. Voir la
page originale.