Advertisement
Guest User

Untitled

a guest
Feb 8th, 2015
2,272
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.15 KB | None | 0 0
  1. #   Implementation of this algorithm:
  2. #       https://www.reddit.com/r/mathriddles/comments/2v6eaj/doubling_and_adding_1/coey1j7
  3. #
  4. #   Save the code as filename.py. Then run something like
  5. #       python filename.py 8 1
  6.  
  7. import sys
  8.  
  9. def getL(k):
  10.     L=1
  11.     Llist = []
  12.  
  13.     # We first create a list of L's that satisfy the inequalities
  14.     while 2**L+L-2 <= 3*k:
  15.         L = L+1
  16.         if 2**L + L - 2 > k and 2**L + L - 2 < 3*k:
  17.             Llist = Llist + [[L,abs(2**L+L-2*k-2)]]
  18.  
  19.     # We could use any L for our purpose but we choose one
  20.     # that gets us as close to our goal as possible, by taking
  21.     # as large steps as possible. Note that there's no reason to
  22.     # believe a priori that this actually provides a more efficient
  23.     # solution but it seems reasonable.
  24.  
  25.     minL = Llist[0][0]
  26.     minval = Llist[0][1]
  27.     for l in Llist:
  28.         if l[1] < minval:
  29.             minL = l[0]
  30.     return minL
  31.  
  32. def op1(a,b):
  33.     global operations
  34.     operations = operations + 1
  35.     print 2*a,b+1
  36.     return 2*a,b+1
  37.  
  38. def op2(a,b):
  39.     global operations
  40.     operations = operations + 1
  41.     print a+1,2*b
  42.     return a+1,2*b
  43.  
  44. #   When (a,b) = (x,x+1) we will use the operations that always work in this case.
  45. def fixone(x):
  46.     return op2(*op2(*op1(*op2(*op1(*op1(*op1(*op1(*op2(*op2(x,x+1))))))))))
  47.  
  48. #   Figuring out the minimal number of needed operations is interesting.
  49. #   Here's a plot of how well the algorithm at hand does:
  50. #       https://i.imgur.com/z4CssvV.png
  51.  
  52. def operationsNeeded(k):
  53.     if k == 0:
  54.         return 0
  55.     if k == 1:
  56.         return 10
  57.     L = getL(k)
  58.     return 2*k+2+operationsNeeded(abs(2*k+2-2**L-L))
  59.  
  60. def makeOperationsNeededData():
  61.     f = open('data','w')
  62.     for i in range(1000000):
  63.         f.write(str(operationsNeeded(i))+"\n")
  64.  
  65. def main():
  66.     a = int(sys.argv[1])
  67.     b = int(sys.argv[2])
  68.     print a,b
  69.    
  70.     global operations
  71.     operations = 0
  72.    
  73.     while 1:
  74.         if a > b:
  75.             print "Swapped the numbers"
  76.             c = a
  77.             a = b
  78.             b = c
  79.         k = b-a
  80.  
  81.         if k == 0:
  82.             break
  83.         if k == 1:
  84.             a,b = fixone(a)
  85.             break
  86.  
  87.         for i in range(k):
  88.             a,b = op2(a,b)
  89.         L = getL(k)
  90.         for i in range(k-L+1):
  91.             a,b = op1(a,b)
  92.         a,b = op2(a,b)
  93.         for i in range(L):
  94.             a,b = op1(a,b) 
  95.  
  96.     print "Number of operations:", operations
  97.  
  98. if __name__ == '__main__':
  99.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement