Grand merci! Avec ceci: somchiffre(n):=block([q:[]],q:divide(n,10),if q[1]=0 then q[2] else q[2]+somchiffre(q[1])); ordre(m,n):= if evenp(somchiffre(m)) then ordre(m+n,n) else m/n-1; compile(ordre,somchiffre); resultat:[]$for n in [11, 101, 1001, 1001001001] do push([ordre(n,n),n],resultat);elapsed_run_time();
j'ai le résultat en quelques secondes! Le 19 décembre 2015 à 13:43, Jean-François Ingenbleek <[email protected]> a écrit : > Grand merci ! > Je regarde tout cela avec attention. > Le 19 déc. 2015 12:26 PM, "couraud" <[email protected]> a écrit : > >> La list de variables après le mot clé « block » est la façon de déclarer >> des >> variables locale au block dans le langage Maxima. (Voir la doc de ce mot >> clé). >> >> >> >> La commande « map » est probablement optimisée mais c’est surtout les >> nombreuses conversions >> de nombres vers « string » et vise versa qui coûte dans vôtre version. >> >> Les quelques mesures que j’ai réalisées suggèrent que la version purement >> numérique est >> 150 fois plus rapide. >> >> Peut être qu’une version purement numérique mais utilisant « map » serais >> un peut plus rapide. >> >> Elle pourrait sûrement être encore optimisé en particulier puisqu’elle >> fait intervenir essentiellement des calculs numériques elle pourrait être >> compilé. >> (Voir la doc de « compile », « compfile » etc.). >> >> Il y aurait sûrement intérêt à ce que la liste de valeurs initiales ainsi >> que la limite du multiple soit >> des paramètres de la fonction. >> >> Enfin 10^19 est une limite vraiment optimiste. Si la boucle doit >> atteindre cette valeur cela impliquera >> des heures, voire des jours de calculs. >> >> >> >> PS : Si vous pouvez répondre à la liste plutôt que en privé. D’autre >> personne peuvent apporté >> de meilleurs solution voire même corriger mes dires (je ne suis pas un >> expert). >> >> >> >> PPS : je me demande si il ne serait pas plus efficace de tester la parité >> de la somme des digits >> et ssi elle est impair alors calculer n, plutôt que d’extraire les digits >> a partir de n. >> >> >> >> >> >> -----Message d'origine----- >> *De :* Jean-François Ingenbleek [mailto:[email protected]] >> *Envoyé :* samedi 19 décembre 2015 10:32 >> *À :* couraud >> *Objet :* Re: RE : [Maxima-lang-fr] programmation efficace >> >> >> >> Merci pour cette réponse rapide. >> >> Je n'avais pas pensé à cela: [q, r] : divide(q, 10) >> >> Par contre je ne comprends pas ceci:[n, sum_digit, k, q, r, stop, result >> : []] >> >> Maladroitement sans doute j'ai voulu écrire en "style" maxima avec des >> "map" ... >> >> Mais qu'elles sont les instructions qui coûte en temps d’exécution? je >> pensais que précisément que "map" était optimisé... >> >> >> >> encore merci >> >> >> >> Le 19 décembre 2015 à 01:28, couraud <[email protected]> a écrit : >> >> Hi, >> >> >> >> The following version seems faster : >> >> >> >> odd_sum_digit() := block([n, sum_digit, k, q, r, stop, result : []], >> >> for n in [11, 101, 1001, 2002, 3003, 4004, 5005, 6006, 7007, 8008, >> 9009] do ( >> >> stop : false, >> >> k : 1, >> >> while (k * n < 10 ^ 19) and not stop do ( >> >> sum_digit : 0, >> >> q : k * n, >> >> while q > 0 do ( >> >> [q, r] : divide(q, 10), >> >> sum_digit : sum_digit + r >> >> ), >> >> stop : oddp(sum_digit), >> >> if stop then ( >> >> result : cons([k, n], result) >> >> ), >> >> k : k + 1 >> >> ) >> >> ), >> >> result >> >> ); >> >> >> >> Hope this help. >> >> >> >> >> >> PS: Je vous réponds en anglais et je mets la mailing liste anglaise en >> copie car c’est la plus active et c’est aussi là >> >> que ce trouvent les développeurs / experts de Maxima. >> >> >> >> Best regards. >> >> >> >> -----Message d'origine----- >> *De :* Jean-François Ingenbleek [mailto:[email protected]] >> *Envoyé :* vendredi 18 décembre 2015 17:42 >> *À :* [email protected] >> *Objet :* [Maxima-lang-fr] programmation efficace >> >> >> >> Il s'agit d'un problème de programme efficace ou inefficace dont voici >> les lignes de code: >> >> lesfin:[]$for n in [11,101,1001,2002,3003,4004,5005,6006,7007,8008,9009] >> do block( >> arret:oddp(apply("+",map(eval_string,charlist(string(n))))), >> for i:n step n thru 10^19 while not arret do block( >> arret: oddp(apply("+",map(eval_string,charlist(string(i))))), >> if arret then push([i/n-1,n],lesfin)))$ >> elapsed_run_time(); >> >> Elles évaluent ceci: >> * un nombre est digitalement paire si la somme de ces chiffres est paire >> -> arret:oddp(apply("+",map(eval_string,charlist(string(n))))) >> * on regarde les multiples successifs d'un nombre digitalement paire -> >> for i:n step n thru 10^19 while not arret do block( avec thru 10^19 comme >> test d'arrêt en parachute ventral... >> * on détermine le nombre de ces multiples digitalement paire jusqu'au >> premier non paire ->arret: >> oddp(apply("+",map(eval_string,charlist(string(i))))), >> * ce nombre est l'"ordre" -> push([i/n-1,n],lesfin))) >> >> Que vaut cet ordre? etc... >> >> J'explore quelque nombres pour voir: ->for n in >> [11,101,1001,2002,3003,4004,5005,6006,7007,8008,9009] >> >> Voilà le contexte. >> >> Le problème c'est que tout cela me semble bien "lent" à l’exécution et >> devient même de plus en plus lent quand je change la liste à explorer.... >> >> Y-a-t-il plus efficace que ces lignes? >> >> Merci à tous par avance >> >> >> >
------------------------------------------------------------------------------
_______________________________________________ Maxima-lang-fr mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/maxima-lang-fr
