Kirjautuminen

Haku

Tehtävät

Keskustelu: Yleinen keskustelu: Vielä yksi random-olio

jone2712 [24.04.2025 13:57:42]

#

Ohessa 8 bittinen random-funktio, joka etsii pi-ketjuja. Joka kierroksella etsitään myös toistoa.

/********************
* *** Jouni Aro *** *
* *** 24.4.2025 *** *
********************/

#include <stdio.h>
#include <memory.h>

typedef unsigned char uint8;

class random
{
    public:

    random(void);
    ~random(void);

    unsigned rnd(unsigned);

    private:

    void inc4(void);
    uint8 tmp8(void);

    unsigned Z;
    uint8 R8A, R8B;
    uint8 avain[256];
    int p1, p2, p3, p4;
};

random::random(void)
{
    memset(this, 0, sizeof(random));
    Z=1+(2<<8)+(3<<16)+(4<<24);
    p1=1; p2=2; p3=3; p4=4;
    R8A=101; R8B=202;

    for (int i=0; i<256; i++)
    avain[i]=(uint8)i;
}

random::~random(void)
{
}

inline void random::inc4(void)
{
    ++Z; p1=Z&255;
    p2=(Z>>8)&255;
    p3=(Z>>16)&255;
    p4=(Z>>24)&255;
}

inline uint8 random::tmp8(void)
{
    R8A+=(uint8)((avain[p1]>>4)^(avain[p2]<<4));
    R8B-=(uint8)((avain[p1]<<4)^(avain[p2]>>4));

    R8A-=avain[p3]&(uint8)255;
    R8B+=avain[p4]&(uint8)255;

    inc4();
    return R8A^R8B;
}

inline void swap(uint8 &x, uint8 &y)
{
    register uint8 z=x; x=y; y=z;
}

inline unsigned random::rnd(unsigned max)
{
    register unsigned x=tmp8();
    register unsigned y=tmp8();
    swap(avain[x], avain[y]);
    return tmp8()%max;
}

/*
main-funktio tutkii, kuinka pitkiä pi-ketjuja
löytyy, samalla etsitään, koska toisto alkaa.
toistaako-funktio etsii rnd-syklistä toistoa.
*/

int toistaako(random &F0, random &F, double &loop)
{
    char *A=(char*)&F0;
    char *B=(char*)&F;
    int size=sizeof(random);

    for (int i=0; i<size; i++)
    if (A[i]!=B[i]) return 0;

    for (unsigned k=0x01; k!=0; k++)
    printf("toistaa %0.0f\n", loop);

    return 1;
}

int main(void)
{
    char *pi="1415926535897932384626433832795028841971693993751058209749445923";
    unsigned maxKpl=0, i=0;
    double loop=0.00;
    random F0, F;

    for (;; loop+=1.0)
    {
        int x=F.rnd(10)+(int)'0';

        if ((char)x==*(pi+i))
        {
            ++i;
        }
        else
        {
            if (i>maxKpl)
            {
                maxKpl=i;
                printf("pi %d numeron tarkkuudella\n", maxKpl);
                printf("loop=%0.0f\n\n", loop);
                i=0;
            }
            else i=0;
        }
        if (toistaako(F0, F, loop)) break;
    }
    return 1;
}

Ohjelma tulostaa pi-ketjuja, ja tulos näyttää tältä:

pi 1 numeron tarkkuudella
loop=16

pi 2 numeron tarkkuudella
loop=24

pi 3 numeron tarkkuudella
loop=2128

pi 4 numeron tarkkuudella
loop=17743

pi 5 numeron tarkkuudella
loop=52605

pi 6 numeron tarkkuudella
loop=1296831

pi 8 numeron tarkkuudella
loop=22506900

pi 9 numeron tarkkuudella
loop=5882993429

pi 10 numeron tarkkuudella
loop=15768925109

pi 11 numeron tarkkuudella
loop=47846462953

pi 12 numeron tarkkuudella
loop=1749902211599

jne...

Vastaus

Muista lukea kirjoitusohjeet.
Tietoa sivustosta