/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        G E N E R A T I O N   D E   V A L E U R S   C O R R E S P O N D A N T   A U X                                              */
/*        N O M B R E S   D E   D I V I S E U R S   D E S   N O M B R E S   E N T I E R S  :                                         */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*        Definition :                                                                                                               */
/*                                                                                                                                   */
/*                    Cette commande (inspiree de la fonction                                                                        */
/*                  'v $ximf/nombres$FON Inombres_premiers')                                                                         */
/*                  donne le nombre de diviseurs d'une liste                                                                         */
/*                  de nombres entiers. Les nombres premiers                                                                         */
/*                  sont obtenus en regardant ceux qui ont 2                                                                         */
/*                  Diviseurs...                                                                                                     */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*        Nota :                                                                                                                     */
/*                                                                                                                                   */
/*                    Je rappelle le 20161019093452 que pour                                                                         */
/*                  simplement lister les nombres premiers,                                                                          */
/*                  il suffira d'utiliser :                                                                                          */
/*                                                                                                                                   */
/*                                      $xci/valeurs_Goldbach$X                 premiere=1 derniere=N                             \  */
/*                                                                              editer_nombres_premiers=VRAI                      \  */
/*                                                                              calculer_decompositions=FAUX                         */
/*                                                                                                                                   */
/*                  ou 'N' designe le nombre de nombres                                                                              */
/*                  premiers que l'on souhaite calculer...                                                                           */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*        Author of '$xci/valeurs_prem$K' :                                                                                          */
/*                                                                                                                                   */
/*                    Jean-Francois COLONNA (LACTAMME, 19990202091459).                                                              */
/*                                                                                                                                   */
/*************************************************************************************************************************************/

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        I N T E R F A C E   ' listG '  :                                                                                           */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*        :Debut_listG:                                                                                                              */
/*        :Fin_listG:                                                                                                                */
/*                                                                                                                                   */
/*************************************************************************************************************************************/

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        D I R E C T I V E S   S P E C I F I Q U E S   D E   C O M P I L A T I O N  :                                               */
/*                                                                                                                                   */
/*************************************************************************************************************************************/

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        F I C H I E R S   D ' I N C L U D E S  :                                                                                   */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
#include  INCLUDES_MINI

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        P A R A M E T R E S  :                                                                                                     */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
#include  xci/sequence.01.I"

#define   EDITER_DES_EN_TETES                                                                                                           \
                    FAUX                                                                                                                \
                                        /* Faut-il editer des en-tetes (introduit le 20121109171704) ?                               */
#define   EDITER_LES_NOMBRES                                                                                                            \
                    FAUX                                                                                                                \
                                        /* Faut-il editer les nombres eux-memes (introduit le 20100102101009) ?                      */
#define   EDITER_LES_DIVISEURS                                                                                                          \
                    FAUX                                                                                                                \
                                        /* Faut-il editer la liste des diviseurs de chaque nombre.                                   */
#define   EDITER_LA_SOMME_DES_DIVISEURS                                                                                                 \
                    FAUX                                                                                                                \
                                        /* Faut-il editer la somme des diviseurs de chaque nombre (introduit le 20121109170802) ?    */

#define   CALCULER_LA_FONCTION_DE_LIOUVILLE                                                                                             \
                    FAUX                                                                                                                \
                                        /* Faut-il calculer la fonction de Liouville et donc editer sa valeur (introduit le          */ \
                                        /* 20100102101009) ?                                                                         */

#define   EDITER_LA_FONCTION_DU_NOMBRE_DE_DIVISEURS                                                                                     \
                    VRAI                                                                                                                \
                                        /* Faut-il editer la fonction calculee du nombre de diviseurs, c'est-a-dire le nombre de     */ \
                                        /* diviseurs ou fonction de Liouville (introduit le 20121110071338) ?                        */

#define   RECHERCHER_LES_DIVISEURS_PREMIERS                                                                                             \
                    FAUX                                                                                                                \
                                        /* Faut-il ne rechercher que les diviseurs premiers (introduit le 20100102103922) ou         */ \
                                        /* tous, quel qu'ils soient...                                                               */
#define   PRENDRE_EN_COMPTE_LA_MULTIPLICITE_DES_DIVISEURS_PREMIERS                                                                      \
                    VRAI                                                                                                                \
                                        /* Faut-il preendre en compte la multiplicite de chaque diviseur premier ou bien ne les      */ \
                                        /* compter qu'une seule fois chacun meme s'ils apparaissent plusieurs fois (introduit le     */ \
                                        /* 20100110134420) ?                                                                         */

#include  xci/valeurs.01.I"

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        M A C R O S   U T I L E S  :                                                                                               */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
#include  xci/valeurs.02.I"

#define   NOMBRE_DE_NOMBRES                                                                                                             \
                    NBRE(premiere_image,derniere_image)                                                                                 \
                                        /* Nombre de nombres...                                                                      */

#define   INDEX_DU_PREMIER_NOMBRE_PREMIER                                                                                               \
                    INDEX0                                                                                                              \
                                        /* Index du premier nombre premier...                                                        */
#define   PREMIER_NOMBRE_PREMIER                                                                                                        \
                    SUCC(UN)                                                                                                            \
                                        /* Definition a priori du premier nombre premier...                                          */

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        G E N E R A T I O N   D E   V A L E U R S   C O R R E S P O N D A N T   A U X                                              */
/*        N O M B R E S   D E   D I V I S E U R S   D E S   N O M B R E S   E N T I E R S  :                                         */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
BCommande(nombre_d_arguments,arguments)
/*-----------------------------------------------------------------------------------------------------------------------------------*/
     Bblock
     DEFV(Int,INIT(premiere_image,PREMIERE_IMAGE));
                                        /* Numero de la premiere image,                                                              */
     DEFV(Int,INIT(derniere_image,DERNIERE_IMAGE));
                                        /* Numero de la derniere image.                                                              */
     DEFV(Int,INIT(numero_d_image,UNDEF));
                                        /* Numero de l'image courante.                                                               */
     DEFV(Int,INIT(pas_des_images,PAS_DES_IMAGES));
                                        /* Pas de passage d'un numero d'image a une autre.                                           */

     DEFV(Logical,INIT(editer_des_en_tetes,EDITER_DES_EN_TETES));
                                        /* Faut-il editer des en-tetes (introduit le 20121109171704) ?                               */
     DEFV(Logical,INIT(editer_les_nombres,EDITER_LES_NOMBRES));
                                        /* Faut-il editer les nombres eux-memes (introduit le 20100102101009) ?                      */
     DEFV(Logical,INIT(editer_les_diviseurs,EDITER_LES_DIVISEURS));
                                        /* Faut-il editer la liste des diviseurs de chaque nombre.                                   */
     DEFV(Logical,INIT(editer_la_somme_des_diviseurs,EDITER_LA_SOMME_DES_DIVISEURS));
                                        /* Faut-il editer la somme des diviseurs de chaque nombre (introduit le 20121109170802) ?    */

     DEFV(Logical,INIT(calculer_la_fonction_de_Liouville,CALCULER_LA_FONCTION_DE_LIOUVILLE));
                                        /* Faut-il calculer la fonction de Liouville et donc editer sa valeur (introduit le          */
                                        /* 20100102101009) ?                                                                         */

     DEFV(Logical,INIT(editer_la_fonction_du_nombre_de_diviseurs,EDITER_LA_FONCTION_DU_NOMBRE_DE_DIVISEURS));
                                        /* Faut-il editer la fonction calculee du nombre de diviseurs, c'est-a-dire le nombre de     */
                                        /* diviseurs ou fonction de Liouville (introduit le 20121110071338) ?                        */

     DEFV(Logical,INIT(rechercher_les_diviseurs_premiers,RECHERCHER_LES_DIVISEURS_PREMIERS));
                                        /* Faut-il ne rechercher que les diviseurs premiers (introduit le 20100102103922) ou         */
                                        /* tous, quel qu'ils soient...                                                               */
     DEFV(Logical,INIT(prendre_en_compte_la_multiplicite_des_diviseurs_premiers
                      ,PRENDRE_EN_COMPTE_LA_MULTIPLICITE_DES_DIVISEURS_PREMIERS
                       )
          );
                                        /* Faut-il preendre en compte la multiplicite de chaque diviseur premier ou bien ne les      */
                                        /* compter qu'une seule fois chacun meme s'ils apparaissent plusieurs fois (introduit le     */
                                        /* 20100110134420) ?                                                                         */

#include  xci/valeurs.03.I"
     /*..............................................................................................................................*/
     GET_ARGUMENTS_(nombre_d_arguments
                   ,BLOC(GET_ARGUMENT_I("premiere=""p=""D=",premiere_image);
                         GET_ARGUMENT_I("derniere=""d=""A=",derniere_image);
                         GET_ARGUMENT_I("pas=",pas_des_images);

                         GET_ARGUMENT_L("editer_en_tetes=""en_tetes=""et=",editer_des_en_tetes);
                                        /* Arguments introduits le 20121109171704...                                                 */
                         GET_ARGUMENT_L("editer_nombres=""nombres=""en=",editer_les_nombres);
                                        /* Arguments introduits le 20100102101009...                                                 */
                         GET_ARGUMENT_L("editer_diviseurs=""diviseurs=""ed=",editer_les_diviseurs);
                                        /* L'argument "editer=" a ete supprime le 20100102101009...                                  */
                         GET_ARGUMENT_L("editer_somme_diviseurs=""somme=""sd=",editer_la_somme_des_diviseurs);
                                        /* Arguments introduits le 20121109170802...                                                 */

                         GET_ARGUMENT_L("fonction_Liouville=""Liouville=""fl=",calculer_la_fonction_de_Liouville);
                                        /* Arguments introduits le 20100102101009...                                                 */

                         GET_ARGUMENT_L("editer_fonction=""fonction=""ef=",editer_la_fonction_du_nombre_de_diviseurs);
                                        /* Arguments introduits le 20121110071338...                                                 */

                         GET_ARGUMENT_L("diviseurs_premiers=""dp=",rechercher_les_diviseurs_premiers);
                                        /* Arguments introduits le 20100102103922...                                                 */
                         GET_ARGUMENT_L("multiplicite_diviseurs_premiers=""multiplicite=""mdp="
                                       ,prendre_en_compte_la_multiplicite_des_diviseurs_premiers
                                        );
                         GET_ARGUMENT_N("unicite_diviseurs_premiers=""unicite=""udp="
                                       ,prendre_en_compte_la_multiplicite_des_diviseurs_premiers
                                        );
                                        /* Arguments introduits le 20100110134420...                                                 */

                         GET_ARGUMENT_C("signe=",valeurs_signees);
                         )
                    );

     Test(IFLE(premiere_image,derniere_image))
          Bblock
          DEFV(Int,INIT(index_courant_des_nombres_premiers,INDEX_DU_PREMIER_NOMBRE_PREMIER));
          DEFV(Local,DEFV(Int,DdTb1(POINTERi,liste_des_nombres_premiers,NOMBRE_DE_NOMBRES,ADRESSE_NON_ENCORE_DEFINIE)));
          MdTb1(liste_des_nombres_premiers,NOMBRE_DE_NOMBRES,Int,ADRESSE_NON_ENCORE_DEFINIE);
                                        /* Definition de la liste des nombres premiers si besoin est (introduit le 20100129094657).  */
                                        /*                                                                                           */
                                        /* On notera que le nombre possible d'elements de 'liste_des_nombres_premiers' (soit         */
                                        /* 'NOMBRE_DE_NOMBRES') pourrait etre optimise grace au logarithme integral, mais avec       */
                                        /* cette valeur, au moins, je ne prends pas de risque...                                     */

          EGAL(IdTb1(liste_des_nombres_premiers,index_courant_des_nombres_premiers,NOMBRE_DE_NOMBRES),PREMIER_NOMBRE_PREMIER);
                                        /* Definition a priori du premier nombre premier...                                          */

          Test(IFET(IL_FAUT(calculer_la_fonction_de_Liouville)
                   ,IL_NE_FAUT_PAS(rechercher_les_diviseurs_premiers)
                    )
               )
               Bblock
               PRINT_ERREUR("le calcul de la fonction de Liouville implique et force la recherche des seuls diviseurs premiers");

               EGAL(rechercher_les_diviseurs_premiers,VRAI);
                                        /* Et on force la recherche des diviseurs premiers...                                        */
               Eblock
          ATes
               Bblock
               Eblock
          ETes

          DoIn(numero_d_image,premiere_image,derniere_image,pas_des_images)
               Bblock
               DEFV(Int,INIT(nombre_courant,numero_d_image));
                                        /* Nombre entier courant a tester (introduit le 20100102103741).                             */
               DEFV(Int,INIT(diviseur_courant_ou_index_du_diviseur_courant,UNDEF));
                                        /* Diviseur courant du nombre courant 'nombre_courant' ou son index dans le cas ou ne        */
                                        /* sont recherches que les diviseurs premiers...                                             */
               DEFV(Int,INIT(nombre_de_diviseurs_du_nombre_courant,ZERO));
                                        /* Nombre de diviseurs du nombre courant 'nombre_courant'.                                   */
               DEFV(Int,INIT(somme_des_diviseurs_du_nombre_courant,ZERO));
                                        /* Somme des diviseurs du nombre courant 'nombre_courant'.                                   */

               Test(IL_FAUT(editer_les_nombres))
                    Bblock
                    CAL2(Prin1(Cara(chain_Aconcaten5(COND(IL_FAUT(editer_des_en_tetes),"Nombre=",C_VIDE)
                                                    ,INTRODUCTION_FORMAT
                                                    ,valeurs_signees
                                                    ,"d"
                                                    ,":"
                                                     )
                                    )
                              ,nombre_courant
                               )
                         );
                                        /* Edition des nombres eux-memes (introduite le 20100102101009).                             */
                    Eblock
               ATes
                    Bblock
                    Eblock
               ETes

               DoIn(diviseur_courant_ou_index_du_diviseur_courant
                   ,COND(IL_FAUT(rechercher_les_diviseurs_premiers)
                        ,INDEX_DU_PREMIER_NOMBRE_PREMIER
                        ,UN
                         )
                   ,COND(IL_FAUT(rechercher_les_diviseurs_premiers)
                        ,index_courant_des_nombres_premiers
                        ,nombre_courant
                         )
                   ,I
                    )
                                        /* ATTENTION, on n'optimise pas avec 'INTE(RACX(nombre_courant))' afin d'etre sur d'avoir    */
                                        /* 'nombre_courant' comme diviseur de lui-meme et aussi, eviter des problemes au cas ou      */
                                        /* l'on utiliserait des nombres negatifs...                                                  */
                    Bblock
                    DEFV(Int,INIT(diviseur_courant_effectif
                                 ,COND(IL_FAUT(rechercher_les_diviseurs_premiers)
                                      ,IdTb1(liste_des_nombres_premiers
                                            ,diviseur_courant_ou_index_du_diviseur_courant
                                            ,NOMBRE_DE_NOMBRES
                                             )
                                      ,diviseur_courant_ou_index_du_diviseur_courant
                                       )
                                  )
                         );
                                        /* Introduit le 20100129094657...                                                            */

                    Test(IFET(IFGE(nombre_courant,diviseur_courant_effectif)
                             ,IZGT(diviseur_courant_effectif)
                              )
                         )
                         Bblock
                         DEFV(Logical,INIT(tester_le_diviseur_courant,VRAI));
                                        /* Afin de faire au moins une fois la boucle 'Tant(...)' qui suit...                         */

                         Tant(IL_FAUT(tester_le_diviseur_courant))
                              Bblock
                              Test(IZEQ(REST(nombre_courant,diviseur_courant_effectif)))
                                   Bblock
                                   INCR(nombre_de_diviseurs_du_nombre_courant,I);
                                        /* Comptage des diviseurs...                                                                 */
                                   INCR(somme_des_diviseurs_du_nombre_courant,diviseur_courant_effectif);
                                        /* Calcul de la somme des diviseurs...                                                       */

                                   Test(IL_FAUT(editer_les_diviseurs))
                                        Bblock
                                        CAL2(Prin1(Cara(chain_Aconcaten5(COND(IL_FAUT(editer_des_en_tetes),"Diviseur=",C_VIDE)
                                                                        ,"=%"
                                                                        ,valeurs_signees
                                                                        ,"d"
                                                                        ," "
                                                                         )
                                                        )
                                                  ,diviseur_courant_effectif
                                                   )
                                             );
                                        /* Edition de chacun des diviseurs lorsque cela est demande. Cela est fait sur la meme ligne */
                                        /* que 'nombre_de_diviseurs_du_nombre_courant' afin de simplifier le "tri" de toutes ces     */
                                        /* valeurs...                                                                                */
                                        Eblock
                                   ATes
                                        Bblock
                                        Eblock
                                   ETes

                                   Test(IL_FAUT(rechercher_les_diviseurs_premiers))
                                        Bblock
                                        DEFV(Logical,INIT(tester_le_diviseur_premier_courant,VRAI));
                                        /* Afin de faire au moins une fois la boucle 'Tant(...)' qui suit...                         */

                                        Tant(IL_FAUT(tester_le_diviseur_premier_courant))
                                             Bblock
                                             EGAL(nombre_courant,DIVI(nombre_courant,diviseur_courant_effectif));
                                        /* Lorsque l'on ne recherche que les diviseurs premiers, on itere sur le diviseur courant    */
                                        /* tant que cela est possible...                                                             */

                                             Test(IFOU(IFLT(nombre_courant,diviseur_courant_effectif)
                                                      ,IFEQ(nombre_courant,UN)
                                                       )
                                                  )
                                                  Bblock
                                                  EGAL(tester_le_diviseur_courant,FAUX);
                                                  EGAL(tester_le_diviseur_premier_courant,FAUX);
                                                  Eblock
                                             ATes
                                                  Bblock
                                                  Test(IL_FAUT(prendre_en_compte_la_multiplicite_des_diviseurs_premiers))
                                                       Bblock
                                                       EGAL(tester_le_diviseur_premier_courant,FAUX);
                                                       Eblock
                                                  ATes
                                                       Bblock
                                                       Test(IZNE(REST(nombre_courant,diviseur_courant_effectif)))
                                                            Bblock
                                                            EGAL(tester_le_diviseur_premier_courant,FAUX);
                                                            Eblock
                                                       ATes
                                                            Bblock
                                        /* Tant que le nombre courant est divisible par le nombre premier courant on continue        */
                                        /* a diviser par lui afin d'ignorer ainsi son degre de multiplicite (introduit le            */
                                        /* 20100110134420).                                                                          */
                                                            Eblock
                                                       ETes
                                                       Eblock
                                                  ETes
                                                  Eblock
                                             ETes
                                             Eblock
                                        ETan
                                        Eblock
                                   ATes
                                        Bblock
                                        EGAL(tester_le_diviseur_courant,FAUX);
                                        Eblock
                                   ETes
                                   Eblock
                              ATes
                                   Bblock
                                   EGAL(tester_le_diviseur_courant,FAUX);
                                   Eblock
                              ETes
                              Eblock
                         ETan
                         Eblock
                    ATes
                         Bblock
                         Eblock
                    ETes
                    Eblock
               EDoI

               Test(IL_FAUT(rechercher_les_diviseurs_premiers))
                    Bblock
                    Test(IFGT(nombre_courant,PREMIER_NOMBRE_PREMIER))
                         Bblock
                         Test(IZEQ(nombre_de_diviseurs_du_nombre_courant))
                              Bblock
                              INCR(index_courant_des_nombres_premiers,I);
                              EGAL(IdTb1(liste_des_nombres_premiers,index_courant_des_nombres_premiers,NOMBRE_DE_NOMBRES)
                                  ,nombre_courant
                                   );
                                        /* Un nouveau nombre premier a ete trouve, on le memorise...                                 */
                              EGAL(nombre_de_diviseurs_du_nombre_courant,UN);
                                        /* Et un nombre premier a au moins un diviseur : lui-meme...                                 */

                              Test(IL_FAUT(editer_les_diviseurs))
                                   Bblock
                                   CAL2(Prin1(Cara(chain_Aconcaten5(COND(IL_FAUT(editer_des_en_tetes),"Diviseur=",C_VIDE)
                                                                   ,"=%"
                                                                   ,valeurs_signees
                                                                   ,"d"
                                                                   ," "
                                                                    )
                                                   )
                                             ,nombre_courant
                                              )
                                        );
                                        /* Edition de l'unique diviseur (lui-meme) lorsque cela est demande...                       */
                                   Eblock
                              ATes
                                   Bblock
                                   Eblock
                              ETes
                              Eblock
                         ATes
                              Bblock
                              Eblock
                         ETes
                         Eblock
                    ATes
                         Bblock
                         Eblock
                    ETes
                    Eblock
               ATes
                    Bblock
                    Eblock
               ETes

               Test(IL_FAUT(editer_la_somme_des_diviseurs))
                    Bblock
                    CAL2(Prin1(Cara(chain_Aconcaten4("SommeDiviseurs=%",valeurs_signees,"d"," "))
                              ,somme_des_diviseurs_du_nombre_courant
                               )
                         );
                                        /* Edition de la somme des diviseurs lorsque cela est demande (introduit le 20121109170802). */
                                        /*                                                                                           */
                                        /* On notera que pour un nombre premier 'P', on a :                                          */
                                        /*                                                                                           */
                                        /*                  SommeDiviseur(P) = 1+P                                                   */
                                        /*                                                                                           */
                                        /* puisque, par definition il n'a comme diviseurs que {1,P}...                               */
                    Eblock
               ATes
                    Bblock
                    Eblock
               ETes

               Test(IL_FAUT(editer_la_fonction_du_nombre_de_diviseurs))
                                        /* Test introduit le 20121110071338...                                                       */
                    Bblock
                    CAL2(Prin1(Cara(chain_Aconcaten4(COND(IL_FAUT(editer_des_en_tetes),"FonctionNombreDiviseurs=",C_VIDE)
                                                    ,INTRODUCTION_FORMAT
                                                    ,valeurs_signees
                                                    ,"d"
                                                     )
                                    )
                              ,COND(IL_NE_FAUT_PAS(calculer_la_fonction_de_Liouville)
                                   ,nombre_de_diviseurs_du_nombre_courant
                                   ,INTE(PUIX(NEGA(UN),nombre_de_diviseurs_du_nombre_courant))
                                    )
                               )
                         );
                                        /* Et enfin, edition du nombre de diviseurs du nombre courant 'nombre_courant'.              */
                                        /*                                                                                           */
                                        /* Le calcul de la fonction de Liouville a ete introduit le 20100102101009. Cette fonction   */
                                        /* vaut -1 a la puissance le nombre de diviseurs premiers (eventuellement identiques et      */
                                        /* en excluant 1 evidemment...).                                                             */
                    Eblock
               ATes
                    Bblock
                    Eblock
               ETes

               CAL2(Prin0("\n"));
                                        /* Introduit sous cette forme le 20121110071338...                                           */
               Eblock
          EDoI

          FdTb1(liste_des_nombres_premiers,NOMBRE_DE_NOMBRES,Int,ADRESSE_NON_ENCORE_DEFINIE);
                                        /* Definition de la liste des nombres premiers si besoin est (introduit le 20100129094657).  */
          Eblock
     ATes
          Bblock
          PRINT_ERREUR("la relation d'ordre stricte ('premier < dernier') n'est pas respectee");
          Eblock
     ETes

     RETU_Commande;
     Eblock
ECommande



Copyright © Jean-François COLONNA, 2019-2024.
Copyright © CMAP (Centre de Mathématiques APpliquées) UMR CNRS 7641 / École polytechnique, Institut Polytechnique de Paris, 2019-2024.