Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

fizzbuzz in Python using random, how does it work?

I am having a hard time figuring out how the code below works:

import random

for i in range(0, 100):
    if not i % 15:
        random.seed(1178741599)
    print [i+1, "Fizz", "Buzz", "FizzBuzz"][random.randint(0,3)]

I understand that when i is divisible by 15, random will use the same seed and hence randint(0, 3) will always return the same index, but when I tried

for i in range(100):
    random.seed(1178741599)
    print random.randint(0,3) #always print 0

the above code always prints 0, shouldn't it be 3 (as the "FizzBuzz"'s index in list [i+1, "Fizz", "Buzz", "FizzBuzz"]?(this is the correct behavior, and corresponds to i+1 in the list.)

And what about when i is divisible by 3 or 5?

What is the magic of seed 1178741599?

Edit: as jonrsharpe pointed out, the fizzbuzz code only works in python 2.x

like image 834
Skiptomylu Avatar asked Feb 15 '23 05:02

Skiptomylu


2 Answers

random.seed(n)

Means "reset the random number generator to some known position n". This means that the future outputs of the generator can be known in advance. It is useful for testing with the same "random" data over and over again.

What this code does is reset the generator every 15 steps, so you get the same sequence of 15 "random" integers (and, hence, of strings from the list) each time. In Python 2.x, the first "random" integer after the reset is always 0 (when I tried just now in Python 3, after random.seed(1178741599) I get random.randint(0, 3) == 1).

Note that this code does not do what a conventional FizzBuzz program does, and depends heavily on the random implementation. It works for me in 2.7.3 but does not work in 3.3.2 (see Why is seeding the random number generator not stable between versions of Python?).

like image 94
jonrsharpe Avatar answered Feb 19 '23 13:02

jonrsharpe


Here's a naive way to go about finding the seed for your random number generator:

import random

expected = [0, 0, 1, 0, 2,
            1, 0, 0, 1, 2,
            0, 1, 0, 0, 3]

def is_working_seed(s):
    random.seed(s)
    return all(random.randint(0, 3) == e for e in expected)

seed = 0
while not is_working_seed(seed):
    seed += 1

print seed

(obviously, looping over all 2^32 values of seed is not a good plan)

Since there are 4**15 == 1073741824 ways to generate a list of random numbers in 0:4, you'd expect there to be about 4 seeds in the space of 32-bit numbers.

like image 26
Eric Avatar answered Feb 19 '23 12:02

Eric