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 à