Random Number Generation

The "random" numbers produced by computers aren't purely random. They are actually pseudo-random , meaning that they are produced by mathematical formulas that simulate randomness.

The linear congruential generator takes a seed X 0 X_0 and generates subsequent pseudo-random numbers using the formula: X n + 1 = ( a X n + c ) m o d m X_{n + 1} = (aX_n + c) \mod m

X 1 X_1 is the first pseudo-random number generated, X 2 X_2 is the second, and so on.

Let R be the 2000th pseudo-random number generated by the linear congruential generator when X 0 = 42 X_0 = 42 , a = 25 a = 25 , c = 31 c = 31 , and m = 2 20 m = 2^{20} . What are the last three digits of R ?


The answer is 938.

This section requires Javascript.
You are seeing this because something didn't load right. We suggest you, (a) try refreshing the page, (b) enabling javascript if it is disabled on your browser and, finally, (c) loading the non-javascript version of this page . We're sorry about the hassle.

41 solutions

Brian Chen
Jul 22, 2013

One line Haskell.

(iterate (\x -> (25 * x + 31) `rem` (2 ^ 20)) 42) !! 2000

you can use excel if you can't use python. and get R=902938 then the last three digit is 938

Tan Likai
Jul 28, 2013

My program utilised a list in which an element is generated from the previous element. Recursion was difficult due to the recursion limit of Python.

seeds = [0] * 2001 seeds[0] = 42

for num in range(1, 2001): seeds[num] = (25 * seeds[num - 1] + 31) % (2 ** 20)

print(seeds[2000])

Taylor Sarrafian
Jul 27, 2013

in Racket:

#lang racket

(define (pseudo s [r 0] [x 42] [a 25] [c 31] [m (expt 2 20)])
  (if (= s r)
      x
      (pseudo s (+ r 1) (modulo (+ (* a x) c) m))
      )
  )

(pseudo 2000)
Otávio Sales
Jul 26, 2013

In Excel =MOD(25*I2+31;(2^20))

Jeffrey Robles
Jul 26, 2013

MatLab script:

x 0 = 42 ; a = 25 ; c = 31 ; m = 2 20 ; f o r k = 1 : 2000 x = r e m ( a x 0 + c , m ) ; x 0 = x ; e n d d i s p ( x ) x_0=42; \\ a=25; \\ c=31; \\ m=2^{20}; \\ for \ k=1:2000 \\ \quad x=rem(a \cdot x_0+c,m); \\ \quad x_0=x; \\ end \\ disp(x) \\

which returns 938 .

Poulis Samir
Jul 25, 2013

http://codepad.org/NXy6MdOh the program

Solution

randomNumber = 42
for x in range(2000):
  randomNumber = (25*randomNumber+31)%(2**20)
Parixit Prasad
Jul 24, 2013

the program is as follows

long x=42, a=25, c=31, m=1048576;

for(int i=1;i<=2000;i++)

    x=(a*x+c)%m;

cout<<x;

Here I provide the Python code for the problem:

x=42
a=25
c=31
n=1
m=2**20
while(n<=2000):
    x=(a*x + c)%m
    n=n+1
print(x)

Finally the value of x comes out to be 902938. Hence, the last three digits of R are 938 which is our answer

Ygor Machado
Jul 24, 2013

Assuming the previous assignment of all the required variables, basically I filled a list "x" until the n-th term (in this case, the 2000th), and then returned the n-th term of x. The procedure code:

def find_nth_num(n):
    for i in range(1,n+1):
        next_num = ((a * x[i-1]) + c) % m
        x.append(next_num)
    return x[n]
Jan J.
Jul 24, 2013

Recursion in Python 3.

import sys
sys.setrecursionlimit(3000)
def pseudo(n):
    if n == 0:
        return 42
    return (25*pseudo(n - 1) + 31) % (2**20)

print(pseudo(2000) % 1000)
Zi Song Yeoh
Jul 24, 2013

C++ Solution :

#include <iostream>
#include <cmath>

using namespace std;

int main()
{
    int i, r = 42;

    for(i = 0; i < 2000; i++)
    {
        r = (25*r + 31)%((int)(pow(2, 20)));
    }
    cout << (r % 1000) << endl;

    return 0;
}
Razvan Barbu
Jul 24, 2013

include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])
{
    int a=25, x=42, c=31; 
    long int m=1048576;
    for(int i=1;i<=2000;i++)
    {
        x=(a*x+c)%m;
    }

    printf("%d",x);

    return 0;
}
Siddharth Kannan
Jul 24, 2013

The code is:

code

The solution:

I simply iterated 2000 times so as to get the 200th random number which I found out to be: 902938. And thus the last three digits were 938!!

Bob Krueger
Jul 23, 2013

Here is my original code (in python) with comments:

# These are the variables as defined in the problem.
x = 42
a = 25
c = 31
m = 2**20

# This will be my index for the while loop.
i = 0

while i < 2000:
    x = (a * x + c) % m
    i += 1
    # These lines perform the formula in the problem on x,
    # store this new value of x to x,
    # and add one to our index.
    # Notice how I used i < 2000,
    # so that when the loop ended,
    # I would get the correct x value.

print x

If you don't like while loops, try this for loop program:

x = 42
a = 25
c = 31
m = 2**20

for i in range(1, 2001):
    x = (a * x + c) % m
    # Note the change to 2001 in the range.
    # This is because range(a, b) only goes from a to b - 1.

print x
Patrick Lu
Jul 23, 2013

import sys

sys.setrecursionlimit(3000)

def seed(end, value):
    if end == 0:
        return value
    next_value = (25 * value + 31) % (2 ** 20)
    return seed(end - 1, next_value)

Recursive function that calculates each X_n with the formula given .

William Wang
Jul 23, 2013

Um, I used my TI-84 Plus Silver Edition. (Those -> are "store" commands)

PROGRAM:BRILLIANT
:A+1 -> A
:remainder(25X+31,1048576) -> X
:If A ≠ 2000
:Then
:prgmBRILLIANT
:Else
:Disp X

Before I ran the program, I set A=0 and X=42. A simulates X's subscript.

Incidentally, my calculator was unable to do this in one run of the program due to a memory error. This is not a problem, since my calculator timed out at the "If A \neq 2000" step, so I simply re-ran my program from the beginning, since A and X values were kept. Eventually, the calculator will display the correct answer, 902938 instead of an error.

Gabriel Lucas
Jul 23, 2013

include <stdio.h>

main() { long long int i, x = 42, m = 1048576; for (i = 0; i < 2000; i++) { x = (25 * x + 31) % m; } printf("\n%lld\n",x); getch(); }

Kevin Larsen
Jul 23, 2013

In C++:

#include <cmath>
#include <iostream>

using namespace std;

int x = 42;
int a = 25;
int c = 31;
int m = pow(2,20);

cout << "x0 == " << x << " a == " << a << " c == " << c <<
        " m == " << m << endl;

for (int i = 1; i < 2001; i++){
    x = (a*x + c) % m;
    cout << "x" << i << " == " << x << endl;
}
Drew Cummins
Jul 23, 2013

In Ruby:

x = 42
p 2000.times.map{x = (25 * x + 31) % 2**20}.last.to_s[-3..-1]
Antonius Yonathan
Jul 23, 2013
// JavaScript code start

var a = 25;
var c = 31;
var m = 2^20;
var x0 = 42

function generateRandom(n) {
    if (n == 0) {
        return (a*x0 + c) % m;
    }
    if (n > 0) {
        return (a*generateRandom(n-1) + c) % m;
    }
}

console.log(generateRandom(1999));
Andrias Meisyal
Jul 23, 2013

You can solve this problem using recursive function or loop function. Actually, the recursive function will get you on the depth error case. The simple idea, you use loop function, because it more effective. See my code here * in Pyhton version:

def pseudo_numbers(n):

if n == 0:

    return 42

else:

    current=42

    i = 0

    while(i < n):

        new = (25*current+31)%2**20

        current = new

        i = i + 1

    return current

then, just Call it . But, I don't know how to solve using '<idea> 2' .

Randolf Rebrick
Jul 22, 2013
def get_prandom(seed,a=25,c=31):
    retval = ((a * seed) + c) % (2**20)
    return retval

if __name__ == '__main__':
    r = 42
    for n in range(2000):
        r = get_prandom(r)      
    print('r=%d' % (r,))
Lea Fairbanks
Jul 22, 2013
<?php 

$m = pow(2, 20);
$c = 31;
$a = 25;

$x = 42;

for($i = 0; $i < 2000; $i++) {
    $x = (($a * $x) + $c) % $m;
}

echo substr($x, -3, 3);
x0, a, c, m = 42, 25, 31, (1 << 20) - 1
for i in range(2000) :
    x0 = (a * x0 + c) & m
print(x0)
Akshata Mohanty
Jul 22, 2013

Simple recursion function.

Yun Kai Lim
Jul 22, 2013

Just do as what problem said. C++ code.

int main()
{
    long long pre = 42, now, a = 25, c = 31, mod = 1<<20;
    for(int i = 0; i < 2000; i++){
        now = (a*pre + c)%mod;
        pre = now;
    }
    cout << now << endl;
    return 0;
}

Simple code solution:

def pseudo_random(Xth,X_0,a,c,m):

    save = 0

    for i in range(1,Xth+1):
        if i == 1:
            save = ((a*X_0) + c) % m
        else:
            save = ((a*save) + c) % m

    return save

print pseudo_random(2000,42,25,31,2**20)
Adrian Obleton
Jul 22, 2013
public class PseudoRandom{
    public static void main(String args[]){
        PseudoRandom random = new PseudoRandom();
        int result = random.calc(2000);
        System.out.println(result);
    }

    public int calc(int nthIntInSeries){
        if(nthIntInSeries == 0)
            return 42;
        return (25*calc(nthIntInSeries-1) + 31) % 1048576;
    }
}
a, c, m = 25, 31, 2**20
x = 42
for j in range(2000):
    x = (a*x + c) % m
print x%1000

yields:

938
Lucas Carvalho
Jul 22, 2013

public class inteiros {

public static void main(String[] args) {
    double a=25,xn=42,c=31;

    for(int i=1;i<=2000;i++){
        xn=(a*xn+c)%Math.pow(2, 20);
    }
    System.out.println(xn);

}

}

Murtaza Ibrahim
Jul 22, 2013

The following code was written in order to generate the number:

x_val = input("enter seed:")

a = input("input coeficcient a:")

c = input("input varaible c:")

m = input("input modulus m:")

R = input("input random number serial:")

R_ser = R + 1

for i in range(1,R_ser):

x_val = ((a*x_val)+c)%m

print "the value of the required number is:"

print x_val

Bao Nguyen Le
Jul 22, 2013
m = 2**20
a = 25
c = 31
x = 42
for i in range(2000):
    x = (a*x+c)%m
print x%1000
Vinayak Garg
Jul 22, 2013

Simple 3 lines of code. Initialize variables and run a for loop 2000 times, which computes the X using given formula.

Last X value is the answer.

Well, I wrote C program to solve this. long double X(long double seed) { if(seed==0) return 42; return fmod(25*X(seed-1)+31,pow(2,20)); } int main() { cout << X(2000); return 0; }

You should avoid floating point arithmetic as much possible. And here it was totally unnecessary. A simple 'int' was enough. And instead of 'pow' use '1<<20'

Vinayak Garg - 7 years, 10 months ago
Alex Hong
Jul 21, 2013

for( int i = 0; i < 2000; i++) { x*=a; x+=c; x%=m; }

Palmer Adonis Lao
Jul 21, 2013

The following Haskell code calculates the 2000th output of the given linear congruential generator using arbitrary-precision integers, and prints the last three digits.

lcg :: Integer -> Integer -> Integer -> Integer -> Integer
lcg a c m seed = mod ((a*seed)+c)  m

getNthlcg :: Integer -> Integer -> Integer -> Integer -> Integer -> Integer
getNthlcg n a c m seed = 
  let getNthlcgAux n count prev = if (count < n) then getNthlcgAux n (count+1) (lcg a c m prev) else (lcg a c m prev)
  in  getNthlcgAux n 0 seed

main = putStrLn $ (reverse . (take 3) . reverse)  $ show $ getNthlcg 1999 25 31 (2^20) 42

Prelude.iterate is your friend.

Brian Chen - 7 years, 10 months ago
Jack Stephenson
Jul 21, 2013
x=42
a=25
c=31
m=2**20
for y in range(2000):
    x=(a*x+c)%m
print(x)

Pretty much the same method as mine, through sheer brute force. I think there is a faster, O(1) (constant timing) algorithm to solve this, but since it only requires 2000 iterations, it can solved with brute force in reasonable time too.

Yicheng Li - 7 years, 10 months ago

Log in to reply

There is a closed form for the recurrence which is explained here

Palmer Adonis Lao - 7 years, 10 months ago
Yicheng Li
Jul 21, 2013
#include <iostream>
#define A 25
#define C 31
#define M 1048576
//2^20 = 1048576, since this is still within int limits, it can be used.

using namespace std;

int rrnd(int seed)
{
    return (A*seed + C)%M;
}

int main(void)
{
    int num = 42; //the original seed
    for(int i=0;i<2000;i++)
        num = rrnd(num);
    cout << num << endl;
    return 0;
}
Kelson Ball
Jul 21, 2013

Since each value of X[n] is derived from X[n-1], I immediately jumped to recursion as the solution. The base case X[0] is equal to 42, and all other values of n recurse toward the base case.
The function does not check for infinite recursion errors, do not pass negative input
Using recursion, in ruby:
def lcg(n)
if (n == 0)
return 42
end
return ((25*lcg(n-1))+31)%1048576
end







0 pending reports

×

Problem Loading...

Note Loading...

Set Loading...