Advertisement
rdrewd

problem14.py

May 27th, 2013
25
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.02 KB | None | 0 0
  1. #! `env python` -t
  2. def seq(n):
  3.     """
  4.    Generate the sequence for Project Euler problem 14.
  5.    ===================================================
  6.  
  7.    n is a positive integer that is the first number in the sequence.
  8.  
  9.    I'm told that although it hasn't been proven, that it is believed that
  10.    regardless of the starting number, the sequence eventually gets to 1,
  11.    which is where we stop.
  12.             1         2          3         4         5         6         7         8
  13.    123456789012345678901234567989012345678901234567890123456789012345678901234567890
  14.    """
  15.  
  16.     while True:
  17.         if n % 2 == 0:
  18.             next=n/2
  19.         else:
  20.             next=3*n+1
  21.         yield n
  22.         if n == 1:
  23.             return
  24.         n=next
  25.  
  26. # end seq
  27.  
  28. class Cache:
  29.     """
  30.    A Cache is a place where a value can be associated with an integer.
  31.    When the Cache is created, an upper bound for the integer is set.
  32.    When a value is stashed into the cache, if the associated integer is out of
  33.    bounds, then the stash operation is a no-op.
  34.    The value associated with an integer can be retrieved using the value(i) routine.
  35.    If no value has ever been passed to stash for association with the given integer,
  36.    then a value of 0 is returned.
  37.    If the value of i is out of bounds, a value of 0 is returned.
  38.    """
  39.     def __init__(self, bound):
  40.         self.c=[0 for i in xrange(bound)]
  41.         self.bound=bound
  42.     # end "Cache.__init__"
  43.  
  44.     def stash(self, i, val):
  45.         if i >= self.bound:
  46.             return
  47.         self.c[i]=val
  48.      # end Cache.stash
  49.  
  50.     def value(self,  i):
  51.         if i >= self.bound:
  52.             return 0
  53.         return self.c[i]
  54.     # end Cache.value
  55.  
  56. def runlen(n, c):
  57.     """
  58.    runlen returns the length of the sequence
  59.    generated by seq(n)
  60.    c is a Cache where we remember runlen's of n's we've already done.
  61.    If we run into a remembered runlen, we don't have to generate the rest of the sequence,
  62.    but can just add on how long we remember the sequence goes from here.
  63.    """
  64.  
  65.     count=0
  66.     for s in seq(n):
  67.         lookupcount=c.value(s)
  68.         if lookupcount != 0:
  69.             count += lookupcount
  70.             break
  71.             # Need something to abort seq(n) since we are quitting the loop before running the
  72.             # generator to exhaustion?? XXX
  73.         count += 1
  74.     # end "for s"
  75.     c.stash(n, count)
  76.     return count
  77. # end runlen
  78.  
  79. def main():
  80.     c=Cache(100000)
  81.     # if we have lots of memory available, Cache(1000000) would be great for this problem,
  82.     # but I'm thinking that a smaller Cache than that would still help the runtime.
  83.     # For this run I'm trying 100,000 for the Cache size.
  84.     longest=0
  85.     basis=0
  86.     for i in xrange(1, 1000000):
  87.         r=runlen(i, c)
  88.         if r > longest:
  89.             basis=i
  90.             longest=r
  91. #        print 'runlen(', i, ',c)=', runlen(i,c)
  92.         #   end "for i"
  93.     print "longest=", longest,\
  94.         "generated from", basis
  95.     return basis
  96. # end main
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement