Attempt at Infinite Monkey theorem using Python
Question: So , I've been trying to implement the infinite monkey theorem using
python.The problem statement is something like this.

The theorem states that a monkey hitting keys at random on a typewriter
keyboard for an infinite amount of time will almost surely type a given text,
such as the complete works of William Shakespeare. Well, suppose we replace a
monkey with a Python function. The sentence is: “methinks it is like a weasel”

The way we’ll simulate this is to write a function that generates a string
that is 27 characters long by choosing random letters from the 26 letters in
the alphabet plus the space. We’ll write another function that will score each
generated string by comparing the randomly generated string to the goal.

A third function will repeatedly call generate and score, then if 100% of the
letters are correct we are done. If the letters are not correct then we will
generate a whole new string.

    
    
    import random,string
    
    shakespeare = 'methinks it is a weasel'
    
    def generate():
     char = string.ascii_lowercase+' '
     randchars = ''.join(random.choice(char) for _ in range(27))
     return randchars
    
    def score():
     scorenum = 0
     randchars = generate()
     print randchars
     shake = shakespeare.split()
     randlist = randchars.split()
     for i,j in zip(shake,randlist):
      if i==j:
       scorenum = scorenum+1
      scorecount = (scorenum/27)*100
     return scorecount
    
    def main():
     run = 0
     while not(score()==100):
      score()
      run = run + 1
      print run
      if run ==1000:
       print score()
    
    if __name__ == '__main__':
     main()
    

So, the program is running fine, but I can see the randomized string appearing
twice when I print it, and I've reached 3 million mark without reaching any
success in terms of matching. I believe I've written the main function
wrongly, but I'm not sure of the problem yet.

Thanks in advance if you can help me fix this. :)


Answer: Each time you call score(), you will generate a new statement, which means
within this loop...

    
    
    while not(score()==100):
      score()
      run = run + 1
      print run
      if run ==1000:
          print score()
    

... you are generating the statement at least twice, and sometimes three
times.

You could replace it with something like:

    
    
    while not(score()==100):
      run = run + 1
      print run
    

The number of potential combinations is vast - the chances of you being able
to run this for long enough to see anything close to a readable sentence,
never mind one that matches the exact sentence you're looking for, are really
remote!

Here's an example that generates matches (I've seen several 33% matches on a 3
character quote):

    
    
    import random,string
    
    # shakespeare = 'methinks it is a weasel'
    shakespeare = 'abc'
    quoteLen = len(shakespeare)
    
    def generate():
     char = string.ascii_lowercase+' '
     randchars = ''.join(random.choice(char) for _ in range(quoteLen))
     return randchars
    
    def score():
     scorenum = 0
     randchars = generate()
     shake = shakespeare.split()
     randlist = randchars.split()
     for i,j in zip(shake,randlist):
      if i==j:
       scorenum = scorenum+1
     scorecount = (scorenum / quoteLen) * 100
     return scorecount
    
    def main():
     run = 0
     curScore = 0
     while not(curScore==100):
      curScore = score()
      if (curScore != 0):      
        print(run, " = ", curScore)
      run = run + 1;
    
    if __name__ == '__main__':
     main()
    

Example output:

    
    
    2246  =  33.33333333333333
    56731  =  33.33333333333333 
    83249  = 33.33333333333333 
    88370  =  33.33333333333333 
    92611  =  33.33333333333333 
    97535  =  33.33333333333333 
    

