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 and generates subsequent pseudo-random numbers using the formula: X n + 1 = ( a X n + c ) m o d m
X 1 is the first pseudo-random number generated, 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 = 4 2 , a = 2 5 , c = 3 1 , and m = 2 2 0 . What are the last three digits of R ?
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.
you can use excel if you can't use python. and get R=902938 then the last three digit is 938
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])
#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)
In Excel =MOD(25*I2+31;(2^20))
MatLab script:
x 0 = 4 2 ; a = 2 5 ; c = 3 1 ; m = 2 2 0 ; f o r k = 1 : 2 0 0 0 x = r e m ( a ⋅ x 0 + c , m ) ; x 0 = x ; e n d d i s p ( x )
which returns 938 .
http://codepad.org/NXy6MdOh the program
randomNumber = 42
for x in range(2000):
randomNumber = (25*randomNumber+31)%(2**20)
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
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]
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)
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;
}
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;
}
The code is:
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!!
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
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 .
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 = 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.
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(); }
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;
}
In Ruby:
x = 42
p 2000.times.map{x = (25 * x + 31) % 2**20}.last.to_s[-3..-1]
// 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));
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' .
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,))
<?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)
Simple recursion function.
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)
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
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);
}
}
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
m = 2**20
a = 25
c = 31
x = 42
for i in range(2000):
x = (a*x+c)%m
print x%1000
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'
for( int i = 0; i < 2000; i++) { x*=a; x+=c; x%=m; }
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.
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.
Log in to reply
There is a closed form for the recurrence which is explained here
#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;
}
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
Problem Loading...
Note Loading...
Set Loading...
One line Haskell.