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

Répondre à