Skip to main content
Notice removed Reward existing answer by fairytale
Bounty Ended with fgrieu's answer chosen by fairytale
Notice added Reward existing answer by fairytale
Bounty Started worth 50 reputation by fairytale
Fix the LaTex
Source Link
fgrieu
  • 145.5k
  • 12
  • 319
  • 611

I have one hundred integers in $\{0,1,2,3,4,5\}$ which I suspect are consecutive values of $⌊𝑥_𝑛/2^{16}⌋\bmod6$$\lfloor x_n/2^{16}\rfloor\bmod6$ computed as $𝑥_{𝑛+1}:=𝑎⋅𝑥_𝑛+𝑏\bmod𝑚$$x_{n+1}:=a\cdot x_n+b\bmod m$, with $𝑚=2^{31}$$m=2^{31}$, and $(𝑎,𝑏)∈{(214013,2531011),(22695477,1)}$$(a,b)\in{(214013,2531011),(22695477,1)}$. How do I validate that hypothesis, find the $(𝑎,𝑏)$$(a,b)$ used, and predict what follows in the sequence?

What is the better way to do it? I just started to learn c++ two weeks ago, please forgive my ignorance.

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <iostream>
#include <inttypes.h>

using namespace std;

const int RESULT[3][7] = {
    {0,1,0,1,1,1,1},
    {1,0,1,0,0,0,0},
    {0,1,1,0,1,0,0}
};
 

static unsigned long x;

int test_rand(void)
{
    x = 214013 * x + 2531011; // or is it 22695477*x+1
    return (int)((x >> 16) & 0x7FFF);
};

int onlyx16(void)
{
    x = 214013 * x + 2531011; // or is it 22695477*x+1
    return (x >> 16) & 1;
};

void chk_seed(unsigned long seed)
{
    int d1[241]{};
    int d2[241]{};
    int d3[241]{};

    x = seed;

    for (int i = 0; i < 2399; i++) {
        test_rand();
    }

    for (int i = 0; i < 241; i++)
    {
        d1[i] = onlyx16();
        d2[i] = onlyx16();
        d3[i] = onlyx16();
    };

    int correct = 0;

    for (int k = 0; k < 236; k++)
    {
        correct = 0;
        for (int i = 0; i < 7; i++)
        {
            if ((d1[i + k]) == RESULT[0][i])
            {
                correct += 1;
            }
            else {
                correct = 0;
                break;
            };
            if ((d2[i + k]) == RESULT[1][i])
            {
                correct += 1;
            }
            else {
                correct = 0;
                break;
            };
            if ((d3[i + k]) == RESULT[2][i])
            {
                correct += 1;
            }
            else {
                correct = 0;
                break;
            };
        };
        if (correct == 21)
        {
            printf("seed 0x%d is OK\n", seed);
            printf("results forecast:\n");
            for (int round = 0; round < 5; round++)
            {
                printf("round%d ", round + 1);
                int new_d[3]{};
                for (int i = 0; i < 3; i++)
                {
                    new_d[i] = test_rand()% 6;
                    printf("%d", new_d[i]);
                };
                printf("\n");
            }
        };
    }
};

int main()
{
    for (unsigned long seed = 0; seed < 0x100000000; seed++)
        chk_seed(seed);
};

I have one hundred integers in $\{0,1,2,3,4,5\}$ which I suspect are consecutive values of $⌊𝑥_𝑛/2^{16}⌋\bmod6$ computed as $𝑥_{𝑛+1}:=𝑎⋅𝑥_𝑛+𝑏\bmod𝑚$, with $𝑚=2^{31}$, and $(𝑎,𝑏)∈{(214013,2531011),(22695477,1)}$. How do I validate that hypothesis, find the $(𝑎,𝑏)$ used, and predict what follows in the sequence?

I just started to learn c++ two weeks ago, please forgive my ignorance.

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <iostream>
#include <inttypes.h>

using namespace std;

const int RESULT[3][7] = {
    {0,1,0,1,1,1,1},
    {1,0,1,0,0,0,0},
    {0,1,1,0,1,0,0}
};
 

static unsigned long x;

int test_rand(void)
{
    x = 214013 * x + 2531011; // or is it 22695477*x+1
    return (int)((x >> 16) & 0x7FFF);
};

int onlyx16(void)
{
    x = 214013 * x + 2531011; // or is it 22695477*x+1
    return (x >> 16) & 1;
};

void chk_seed(unsigned long seed)
{
    int d1[241]{};
    int d2[241]{};
    int d3[241]{};

    x = seed;

    for (int i = 0; i < 2399; i++) {
        test_rand();
    }

    for (int i = 0; i < 241; i++)
    {
        d1[i] = onlyx16();
        d2[i] = onlyx16();
        d3[i] = onlyx16();
    };

    int correct = 0;

    for (int k = 0; k < 236; k++)
    {
        correct = 0;
        for (int i = 0; i < 7; i++)
        {
            if ((d1[i + k]) == RESULT[0][i])
            {
                correct += 1;
            }
            else {
                correct = 0;
                break;
            };
            if ((d2[i + k]) == RESULT[1][i])
            {
                correct += 1;
            }
            else {
                correct = 0;
                break;
            };
            if ((d3[i + k]) == RESULT[2][i])
            {
                correct += 1;
            }
            else {
                correct = 0;
                break;
            };
        };
        if (correct == 21)
        {
            printf("seed 0x%d is OK\n", seed);
            printf("results forecast:\n");
            for (int round = 0; round < 5; round++)
            {
                printf("round%d ", round + 1);
                int new_d[3]{};
                for (int i = 0; i < 3; i++)
                {
                    new_d[i] = test_rand()% 6;
                    printf("%d", new_d[i]);
                };
                printf("\n");
            }
        };
    }
};

int main()
{
    for (unsigned long seed = 0; seed < 0x100000000; seed++)
        chk_seed(seed);
};

I have one hundred integers in $\{0,1,2,3,4,5\}$ which I suspect are consecutive values of $\lfloor x_n/2^{16}\rfloor\bmod6$ computed as $x_{n+1}:=a\cdot x_n+b\bmod m$, with $m=2^{31}$, and $(a,b)\in{(214013,2531011),(22695477,1)}$. How do I validate that hypothesis, find the $(a,b)$ used, and predict what follows in the sequence?

What is the better way to do it? I just started to learn c++ two weeks ago, please forgive my ignorance.

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <iostream>
#include <inttypes.h>

using namespace std;

const int RESULT[3][7] = {
    {0,1,0,1,1,1,1},
    {1,0,1,0,0,0,0},
    {0,1,1,0,1,0,0}
};

static unsigned long x;

int test_rand(void)
{
    x = 214013 * x + 2531011; // or is it 22695477*x+1
    return (int)((x >> 16) & 0x7FFF);
};

int onlyx16(void)
{
    x = 214013 * x + 2531011; // or is it 22695477*x+1
    return (x >> 16) & 1;
};

void chk_seed(unsigned long seed)
{
    int d1[241]{};
    int d2[241]{};
    int d3[241]{};

    x = seed;

    for (int i = 0; i < 2399; i++) {
        test_rand();
    }

    for (int i = 0; i < 241; i++)
    {
        d1[i] = onlyx16();
        d2[i] = onlyx16();
        d3[i] = onlyx16();
    };

    int correct = 0;

    for (int k = 0; k < 236; k++)
    {
        correct = 0;
        for (int i = 0; i < 7; i++)
        {
            if ((d1[i + k]) == RESULT[0][i])
            {
                correct += 1;
            }
            else {
                correct = 0;
                break;
            };
            if ((d2[i + k]) == RESULT[1][i])
            {
                correct += 1;
            }
            else {
                correct = 0;
                break;
            };
            if ((d3[i + k]) == RESULT[2][i])
            {
                correct += 1;
            }
            else {
                correct = 0;
                break;
            };
        };
        if (correct == 21)
        {
            printf("seed 0x%d is OK\n", seed);
            printf("results forecast:\n");
            for (int round = 0; round < 5; round++)
            {
                printf("round%d ", round + 1);
                int new_d[3]{};
                for (int i = 0; i < 3; i++)
                {
                    new_d[i] = test_rand()% 6;
                    printf("%d", new_d[i]);
                };
                printf("\n");
            }
        };
    }
};

int main()
{
    for (unsigned long seed = 0; seed < 0x100000000; seed++)
        chk_seed(seed);
};
Fix the LaTex
Source Link
fgrieu
  • 145.5k
  • 12
  • 319
  • 611

I have one hundred integers in ${0,1,2,3,4,5}$$\{0,1,2,3,4,5\}$ which I suspect are consecutive values of $⌊𝑥_𝑛/216⌋\bmod6$$⌊𝑥_𝑛/2^{16}⌋\bmod6$ computed as $𝑥_{𝑛+1}:=𝑎⋅𝑥_𝑛+𝑏\bmod𝑚$, with 𝑚=231$𝑚=2^{31}$, and $(𝑎,𝑏)∈{(214013,2531011),(22695477,1)}$. How do I validate that hypothesis, find the $(𝑎,𝑏)$ used, and predict what follows in the sequence?

What is the better way to do it? I just started to learn c++ two weeks ago, please forgive my ignorance.

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <iostream>
#include <inttypes.h>

using namespace std;

const int RESULT[3][7] = {
    {0,1,0,1,1,1,1},
    {1,0,1,0,0,0,0},
    {0,1,1,0,1,0,0}
}; 


static unsigned long x;

int test_rand(void)
{
    x = 214013 * x + 2531011; // or is it 22695477*x+1
    return (int)((x >> 16) & 0x7FFF);
};

int onlyx16(void)
{
    x = 214013 * x + 2531011; // or is it 22695477*x+1
    return (x >> 16) & 1;
};

void chk_seed(unsigned long seed)
{
    int d1[241]{};
    int d2[241]{};
    int d3[241]{};

    x = seed;

    for (int i = 0; i < 2399; i++) {
        test_rand();
    }

    for (int i = 0; i < 241; i++)
    {
        d1[i] = onlyx16();
        d2[i] = onlyx16();
        d3[i] = onlyx16();
    };

    int correct = 0;

    for (int k = 0; k < 236; k++)
    {
        correct = 0;
        for (int i = 0; i < 7; i++)
        {
            if ((d1[i + k]) == RESULT[0][i])
            {
                correct += 1;
            }
            else {
                correct = 0;
                break;
            };
            if ((d2[i + k]) == RESULT[1][i])
            {
                correct += 1;
            }
            else {
                correct = 0;
                break;
            };
            if ((d3[i + k]) == RESULT[2][i])
            {
                correct += 1;
            }
            else {
                correct = 0;
                break;
            };
        };
        if (correct == 21)
        {
            printf("seed 0x%d is OK\n", seed);
            printf("results forecast:\n");
            for (int round = 0; round < 5; round++)
            {
                printf("round%d ", round + 1);
                int new_d[3]{};
                for (int i = 0; i < 3; i++)
                {
                    new_d[i] = test_rand()% 6;
                    printf("%d", new_d[i]);
                };
                printf("\n");
            }
        };
    }
};

int main()
{
    for (unsigned long seed = 0; seed < 0x100000000; seed++)
        chk_seed(seed);
};

I have one hundred integers in ${0,1,2,3,4,5}$ which I suspect are consecutive values of $⌊𝑥_𝑛/216⌋\bmod6$ computed as $𝑥_{𝑛+1}:=𝑎⋅𝑥_𝑛+𝑏\bmod𝑚$, with 𝑚=231, and $(𝑎,𝑏)∈{(214013,2531011),(22695477,1)}$. How do I validate that hypothesis, find the $(𝑎,𝑏)$ used, and predict what follows in the sequence?

What is the better way to do it? I just started to learn c++ two weeks ago, please forgive my ignorance.

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <iostream>
#include <inttypes.h>

using namespace std;

const int RESULT[3][7] = {
    {0,1,0,1,1,1,1},
    {1,0,1,0,0,0,0},
    {0,1,1,0,1,0,0}
};

static unsigned long x;

int test_rand(void)
{
    x = 214013 * x + 2531011; // or is it 22695477*x+1
    return (int)((x >> 16) & 0x7FFF);
};

int onlyx16(void)
{
    x = 214013 * x + 2531011; // or is it 22695477*x+1
    return (x >> 16) & 1;
};

void chk_seed(unsigned long seed)
{
    int d1[241]{};
    int d2[241]{};
    int d3[241]{};

    x = seed;

    for (int i = 0; i < 2399; i++) {
        test_rand();
    }

    for (int i = 0; i < 241; i++)
    {
        d1[i] = onlyx16();
        d2[i] = onlyx16();
        d3[i] = onlyx16();
    };

    int correct = 0;

    for (int k = 0; k < 236; k++)
    {
        correct = 0;
        for (int i = 0; i < 7; i++)
        {
            if ((d1[i + k]) == RESULT[0][i])
            {
                correct += 1;
            }
            else {
                correct = 0;
                break;
            };
            if ((d2[i + k]) == RESULT[1][i])
            {
                correct += 1;
            }
            else {
                correct = 0;
                break;
            };
            if ((d3[i + k]) == RESULT[2][i])
            {
                correct += 1;
            }
            else {
                correct = 0;
                break;
            };
        };
        if (correct == 21)
        {
            printf("seed 0x%d is OK\n", seed);
            printf("results forecast:\n");
            for (int round = 0; round < 5; round++)
            {
                printf("round%d ", round + 1);
                int new_d[3]{};
                for (int i = 0; i < 3; i++)
                {
                    new_d[i] = test_rand()% 6;
                    printf("%d", new_d[i]);
                };
                printf("\n");
            }
        };
    }
};

int main()
{
    for (unsigned long seed = 0; seed < 0x100000000; seed++)
        chk_seed(seed);
};

I have one hundred integers in $\{0,1,2,3,4,5\}$ which I suspect are consecutive values of $⌊𝑥_𝑛/2^{16}⌋\bmod6$ computed as $𝑥_{𝑛+1}:=𝑎⋅𝑥_𝑛+𝑏\bmod𝑚$, with $𝑚=2^{31}$, and $(𝑎,𝑏)∈{(214013,2531011),(22695477,1)}$. How do I validate that hypothesis, find the $(𝑎,𝑏)$ used, and predict what follows in the sequence?

I just started to learn c++ two weeks ago, please forgive my ignorance.

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <iostream>
#include <inttypes.h>

using namespace std;

const int RESULT[3][7] = {
    {0,1,0,1,1,1,1},
    {1,0,1,0,0,0,0},
    {0,1,1,0,1,0,0}
}; 


static unsigned long x;

int test_rand(void)
{
    x = 214013 * x + 2531011; // or is it 22695477*x+1
    return (int)((x >> 16) & 0x7FFF);
};

int onlyx16(void)
{
    x = 214013 * x + 2531011; // or is it 22695477*x+1
    return (x >> 16) & 1;
};

void chk_seed(unsigned long seed)
{
    int d1[241]{};
    int d2[241]{};
    int d3[241]{};

    x = seed;

    for (int i = 0; i < 2399; i++) {
        test_rand();
    }

    for (int i = 0; i < 241; i++)
    {
        d1[i] = onlyx16();
        d2[i] = onlyx16();
        d3[i] = onlyx16();
    };

    int correct = 0;

    for (int k = 0; k < 236; k++)
    {
        correct = 0;
        for (int i = 0; i < 7; i++)
        {
            if ((d1[i + k]) == RESULT[0][i])
            {
                correct += 1;
            }
            else {
                correct = 0;
                break;
            };
            if ((d2[i + k]) == RESULT[1][i])
            {
                correct += 1;
            }
            else {
                correct = 0;
                break;
            };
            if ((d3[i + k]) == RESULT[2][i])
            {
                correct += 1;
            }
            else {
                correct = 0;
                break;
            };
        };
        if (correct == 21)
        {
            printf("seed 0x%d is OK\n", seed);
            printf("results forecast:\n");
            for (int round = 0; round < 5; round++)
            {
                printf("round%d ", round + 1);
                int new_d[3]{};
                for (int i = 0; i < 3; i++)
                {
                    new_d[i] = test_rand()% 6;
                    printf("%d", new_d[i]);
                };
                printf("\n");
            }
        };
    }
};

int main()
{
    for (unsigned long seed = 0; seed < 0x100000000; seed++)
        chk_seed(seed);
};
added 3260 characters in body
Source Link

Question about "A competent implementation in a compiled language would take like a second on a modern desktop PC."

I wrote some code but they are expected to run 20 hours.

I am trying to find the random seed. First, I input my data in an array. Since I don't know my first data is what-th number generated by the server, I need to find it out. I only know the server shut down every thursday 2:00pm, and restart around 2:45-3:45pm the same day. When the server is on, ir generates 3 numbers every 45 seconds. The data I have is collected on fri 1:50 am, so my first data maybe the 2400-2640th number of the LCG.

I first run the rand 2399 times to discard the first 2399 numbers. Next, I loop 241 times to find my first data is what-th number generated by the server. (the uncertainity of the server restart time 2:45-3:45pm, 240 numbers per hour)

My method is: If 2400th x's bit 16 equal to bit 0 of $y_1$, then I check 2401th x's bit 16 and bit 0 of $y_2$, and so on. If there is unequal, break the loop then start another loop, compare 2401th x and bit 0 of $y_1$.

What is the better way to do it? I just started to learn c++ two weeks ago, please forgive my ignorance.

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <iostream>
#include <inttypes.h>

using namespace std;

const int RESULT[3][7] = {
    {0,1,0,1,1,1,1},
    {1,0,1,0,0,0,0},
    {0,1,1,0,1,0,0}
};

static unsigned long x;

int test_rand(void)
{
    x = 214013 * x + 2531011; // or is it 22695477*x+1
    return (int)((x >> 16) & 0x7FFF);
};

int onlyx16(void)
{
    x = 214013 * x + 2531011; // or is it 22695477*x+1
    return (x >> 16) & 1;
};

void chk_seed(unsigned long seed)
{
    int d1[241]{};
    int d2[241]{};
    int d3[241]{};

    x = seed;

    for (int i = 0; i < 2399; i++) {
        test_rand();
    }

    for (int i = 0; i < 241; i++)
    {
        d1[i] = onlyx16();
        d2[i] = onlyx16();
        d3[i] = onlyx16();
    };

    int correct = 0;

    for (int k = 0; k < 236; k++)
    {
        correct = 0;
        for (int i = 0; i < 7; i++)
        {
            if ((d1[i + k]) == RESULT[0][i])
            {
                correct += 1;
            }
            else {
                correct = 0;
                break;
            };
            if ((d2[i + k]) == RESULT[1][i])
            {
                correct += 1;
            }
            else {
                correct = 0;
                break;
            };
            if ((d3[i + k]) == RESULT[2][i])
            {
                correct += 1;
            }
            else {
                correct = 0;
                break;
            };
        };
        if (correct == 21)
        {
            printf("seed 0x%d is OK\n", seed);
            printf("results forecast:\n");
            for (int round = 0; round < 5; round++)
            {
                printf("round%d ", round + 1);
                int new_d[3]{};
                for (int i = 0; i < 3; i++)
                {
                    new_d[i] = test_rand()% 6;
                    printf("%d", new_d[i]);
                };
                printf("\n");
            }
        };
    }
};

int main()
{
    for (unsigned long seed = 0; seed < 0x100000000; seed++)
        chk_seed(seed);
};

$x_{n+1} = (a \cdot x_{n} + b) \mod m$

$x_{n+1} = (a \cdot x_{n} + b) \mod m$

Question about "A competent implementation in a compiled language would take like a second on a modern desktop PC."

I wrote some code but they are expected to run 20 hours.

I am trying to find the random seed. First, I input my data in an array. Since I don't know my first data is what-th number generated by the server, I need to find it out. I only know the server shut down every thursday 2:00pm, and restart around 2:45-3:45pm the same day. When the server is on, ir generates 3 numbers every 45 seconds. The data I have is collected on fri 1:50 am, so my first data maybe the 2400-2640th number of the LCG.

I first run the rand 2399 times to discard the first 2399 numbers. Next, I loop 241 times to find my first data is what-th number generated by the server. (the uncertainity of the server restart time 2:45-3:45pm, 240 numbers per hour)

My method is: If 2400th x's bit 16 equal to bit 0 of $y_1$, then I check 2401th x's bit 16 and bit 0 of $y_2$, and so on. If there is unequal, break the loop then start another loop, compare 2401th x and bit 0 of $y_1$.

What is the better way to do it? I just started to learn c++ two weeks ago, please forgive my ignorance.

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <iostream>
#include <inttypes.h>

using namespace std;

const int RESULT[3][7] = {
    {0,1,0,1,1,1,1},
    {1,0,1,0,0,0,0},
    {0,1,1,0,1,0,0}
};

static unsigned long x;

int test_rand(void)
{
    x = 214013 * x + 2531011; // or is it 22695477*x+1
    return (int)((x >> 16) & 0x7FFF);
};

int onlyx16(void)
{
    x = 214013 * x + 2531011; // or is it 22695477*x+1
    return (x >> 16) & 1;
};

void chk_seed(unsigned long seed)
{
    int d1[241]{};
    int d2[241]{};
    int d3[241]{};

    x = seed;

    for (int i = 0; i < 2399; i++) {
        test_rand();
    }

    for (int i = 0; i < 241; i++)
    {
        d1[i] = onlyx16();
        d2[i] = onlyx16();
        d3[i] = onlyx16();
    };

    int correct = 0;

    for (int k = 0; k < 236; k++)
    {
        correct = 0;
        for (int i = 0; i < 7; i++)
        {
            if ((d1[i + k]) == RESULT[0][i])
            {
                correct += 1;
            }
            else {
                correct = 0;
                break;
            };
            if ((d2[i + k]) == RESULT[1][i])
            {
                correct += 1;
            }
            else {
                correct = 0;
                break;
            };
            if ((d3[i + k]) == RESULT[2][i])
            {
                correct += 1;
            }
            else {
                correct = 0;
                break;
            };
        };
        if (correct == 21)
        {
            printf("seed 0x%d is OK\n", seed);
            printf("results forecast:\n");
            for (int round = 0; round < 5; round++)
            {
                printf("round%d ", round + 1);
                int new_d[3]{};
                for (int i = 0; i < 3; i++)
                {
                    new_d[i] = test_rand()% 6;
                    printf("%d", new_d[i]);
                };
                printf("\n");
            }
        };
    }
};

int main()
{
    for (unsigned long seed = 0; seed < 0x100000000; seed++)
        chk_seed(seed);
};

$x_{n+1} = (a \cdot x_{n} + b) \mod m$

added 387 characters in body
Source Link
Loading
Source Link
Loading