Alte crâmpeie programatorice din iarna lui 2014 (asta este puțin mai lungă)

Aici plănuiam să obțin abundențele unor numere bazându-mă pe modificarea punctuală a sumei divizorilor altor numere, care trebuiau înmulțite sau împărțite cu ceva, dar fără să calculez de la zero și suma numărului nou, ci doar pe cea a numărului de la care plecam: în sus prin înmulțire sau în jos prin împărțire.
Așa încât modificam suma lui de divizori atât cât trebuia, ca să aflu ce era de aflat despre numărul nou, pe câtă vreme recalcularea din temelii a sumei noi ar fi cerut ceva mai mult timp.
Astfel că operațiunea MODIFSUM, din anul 2014, se voia și-a și reușit să fie o îmbunătățire a lucrului la numere.

Și-avem mai jos situația de atunci:

**

Pentru situația în care căutarea se face în jos, împărțind numărul din vectorul mare la elementele vectorului de coeficienți de legătură:


Vectorii y (mpir_ui) și z (mpz_t) conțin factorii primi ai numărului.
divInt[] și divMpz[] conțin puterile factorilor primi, în care se împarte numărul de bază (A).
sumInt și sumMpz sunt vectorii care au sumele parțiale de divizori, produsul tuturor elementelor ocupate pentru un număr mare este suma de divizori a numărului.
În primă fază fără coeficienți pari de legătură (se poate face și pentru puteri de 2).

Toți vectorii au aceleași dimensiuni (y, divInt și sumInt, respectiv z, divMpz și sumMpz care vor fi mai mici la numărul de elemente).

Varianta 3:

Se face o variantă de LOTVEC() unde sunt extrași în y și z factorii primi ai numărului, dar trebuie făcută și suma lui de divizori, și populați vectorii de puteri și de sume parțiale.

j = 0;

for(i = 0; i < w; i++) {//Dacă puterile factorilor primi și sumele parțiale se încadrează în 64 de biți, și când factorii primi apar foarte probabil la puteri peste 1
    t = b[i];
    while(1) {
        t *= b[i];
        if (!mpz_divisible_ui_p(A, t) )
            break;
    }
   
    if (t ^ b[i]) {//Nu sunt egale
        sumInt[j] = (t - 1) / (b[i] - 1);
        mpz_mul_ui(SUM, sumInt[j], SUM);
        divInt[j++] = t/b[i];
    }
}


j = 0;

for(i = 0; i < x; i++) {//Dacă nu se încadrează în 64 de biți, dar e zona cu puteri peste 1
    mpz_set_ui(t, b[i]);

    while(1){   
        mpz_mul_ui(t, b[i], t);
        if( !mpz_divisible_p(A, t) )
            break;
        }
   
    mpz_divexact_ui(divMpz[j], t, b[i]);
    mpz_divexact_ui(t, t, b[i] - 1);
    mpz_set(sumMpz[j++], t);
    mpz_mul(SUM, t, SUM);
}


//Factori primi întregi, la puterea 1

j = 0;

for(i = 0; i < x; i++)
    if(mpz_divisible_ui_p(A, b[i])) {

        t = b[i];
        divInt[j] = t++;
        mpz_mul_ui(SUM, t, SUM);
        sumInt[j++] = t;
}


//Pentru factorii primi mpz_t (puterea 1)

for(i = 0; i < e; i++)
    if(mpz_divisible(A, c[i]) {
        //mpz_set(divMpz[j], c[i]); //nu are rost dacă este putere-unitate
        //mpz_add_ui(sumMpz[j++], c[i], 1);//pentru sumă
        mpz_addmul_ui(SUM, c[i], SUM);
    }

int pDoi = mpz_scan0(A, 0);


//Apoi trebuie să se treacă prin vectorul de coeficienți și să se vadă divizorii lui A (numiți f, sau sub-numere), ca să se schimbe SUM2 (suma divizorilor lui A, atribuită) în funcție de împărțiri.
//Factorii primi ai lui A sunt în vectorii y (întregi pe 64 de biți, mpir_ui *) și z (mpz_t).

mpz_set(SUM2, SUM);//La fiecare sub-număr

/*
a1 = pDoi - mpz_scan0(f, 0);
if (a1) {
    mpz_setbit(unu, ++pDoi);
    mpz_sub_ui(unu, 1);
    mpz_divexact(SUM2, SUM, unu);   
    a1 = (--pDoi) - a1;
    mpz_tdiv_q_2exp(unu, unu, a1);
    mpz_mul(SUM2, unu, SUM2);
    }*/

for(i = 0; i < yDim; i++) {//Când puterile factorilor primi și sumele parțiale nu depășesc mpir_ui
    if (!mpz_divisible_ui_p (f, y[i])) {
        mpz_divexact_ui(SUM2, SUM2, sumInt[i]);
    } else if (!mpz_divisible_ui_p (f, divInt[i]) ) {

        mpz_divexact_ui(SUM2, SUM2, sumInt[i] );
        a1 = y[i];

        while(1) {
            a1 *= y[i];
            if (!mpz_divisible_ui_p (f, a1)
                break;
            }

        mpz_mul_ui(SUM2, (--a1)/(y[i] - 1), SUM2);
    }

//Pentru schimbarea SUM2

/*if (!(e%2)) {
    a1 = pDoi - mpz_scan1(d1, 0);
    mpz_set_ui(unu, 0);
    mpz_setbit(unu, ++pDoi);
    mpz_sub_ui(unu, 1);

    mpz_divexact(SUM2, SUM2, unu);
    a1 = (--pDoi) - a1;
    mpz_tdiv_q_2exp(unu, unu, a1);
    mpz_mul(SUM2, unu, SUM2);
    }


//mpz_divexact(SUM2, SUM2, sumMpz[Y]);
//mpz_divexact_ui(f, sumMpz[Y], a);
//mpz_mul(SUM2, SUM2, f);//pentru inmultirea cu Mpz


while(1) {
    if(!(Y-- ^ d))
        break;
    if(!(coef % y[Y])) {
        coef /= y[Y];
        mpz_divexact_ui(SUM2, SUM2, sumInt[Y]);
        mpz_mul_ui(SUM2, SUM2, 1 + sumInt[Y]*y[Y]);
        //if(!(coef - 1) )
            //return 0;
        }
    }
    */

Comentarii

Postări populare