Autorisation : Membre
Nb de messages : 33
Inscrit le : Sam 22 Avr 2017, 16:00
Posté le : Mer 24 Mai 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)
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 :
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
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.
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.
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.
Autorisation : Membre
Nb de messages : 504
Inscrit le : Ven 07 Déc 2012, 20:09
Posté le : Jeu 25 Mai 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
Autorisation : Membre
Nb de messages : 856
Inscrit le : Mer 18 Juil 2012, 18:44
Posté le : Dim 28 Mai 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 ?)
Citer
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
Autorisation : Membre
Nb de messages : 33
Inscrit le : Sam 22 Avr 2017, 16:00
Posté le : Dim 28 Mai 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 !
Autorisation : Membre
Nb de messages : 504
Inscrit le : Ven 07 Déc 2012, 20:09
Posté le : Dim 28 Mai 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
Autorisation : Membre
Nb de messages : 856
Inscrit le : Mer 18 Juil 2012, 18:44
Posté le : Lun 29 Mai 2017, 9: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.
Autorisation : Membre
Nb de messages : 33
Inscrit le : Sam 22 Avr 2017, 16:00
Posté le : Lun 19 Jui 2017, 2: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 :
Code
4112030951342501
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 :
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 ?
Autorisation : Membre
Nb de messages : 856
Inscrit le : Mer 18 Juil 2012, 18:44
Posté le : Lun 03 Juil 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 ?
Autorisation : Membre
Nb de messages : 33
Inscrit le : Sam 22 Avr 2017, 16:00
Posté le : Mar 11 Juil 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
Autorisation : Membre
Nb de messages : 856
Inscrit le : Mer 18 Juil 2012, 18:44
Posté le : Jeu 24 Aoû 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 )