Advertisement
wheatwizard

value

Jan 14th, 2017
414
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.39 KB | None | 0 0
  1. import re
  2. import math
  3.  
  4. cache = {0:"<()>"}
  5.  
  6. def find(x,i,j):
  7.     return i*((x**2+x)/2)+(j+1)*((x**2-x)/2)
  8.  
  9. def solve(x, i, j):
  10.     a = (i + j + 1)/2.
  11.     b = (i - j - 1)/2.
  12.     c = -x
  13.     return (-b + math.sqrt(b**2 - 4*a*c))/(2*a)
  14.  
  15. def size(i,j=0):
  16.     return 4*(i+j)+14
  17.  
  18. def polynomials(n):
  19.     upperBound = int(4*math.log(n,2))
  20.     i = 0
  21.     answers = []
  22.     while size(i) < upperBound:
  23.         for j in range(i):
  24.             sol = int(solve(n, i-j, j)+.5)
  25.             if find(sol, i-j, j) == n:
  26.                 answers.append((sol, i-j, j))
  27.         i += 1
  28.     return answers
  29.  
  30. def complement(character):
  31.         dict = {"(":")","{":"}","<":">","[":"]",")":"(","}":"{",">":"<","]":"["}
  32.         return dict[character]
  33.  
  34. def findMatch(snippet, index):
  35.         increment = 1 if snippet[index] in "({<[" else -1
  36.         stack = []
  37.         if snippet[index] in "(){}<>[]":
  38.                 stack.append(snippet[index])
  39.         while len(stack) > 0 and index + increment < len(snippet):
  40.                 index += increment
  41.                 if snippet[index] in "(){}<>[]":
  42.                         if complement(snippet[index]) == stack[-1]:
  43.                                 stack = stack[:-1]
  44.                         else:
  45.                                 stack.append(snippet[index])
  46.         return index
  47.  
  48. def isPrime(n):
  49.     return not [0 for x in range(2,int(n**.5)+1) if n%x==0] and n>1
  50.  
  51. def getPrimeFactors(n):
  52.     return [x for x in range(2,n/2) if n%x==0 and isPrime(x)]
  53.  
  54. def divHardcode(n,m):
  55.     assert n%m == 0
  56.     assert m != 1
  57.     assert n != 1
  58.     binary = bin(m)[3:]
  59.     return (binary.count("1")+len(binary))*"("+getBF(n/m)+")"*binary.count("1")+binary.replace("1","){}{}").replace("0","){}")
  60.  
  61. def isTriangular(n):
  62.     #Triangles must be between sqrt(2n) and cbrt(2n)
  63.     if n < 0: return isTriangular(-n)
  64.     for x in range(int((2*n)**(1/3.)),int((2*n)**.5)+1):
  65.         if (x**2+x) == 2*n:
  66.             return True
  67.     return False
  68.  
  69. def getTriangle(n):
  70.     if n < 0: return -getTriangle(-n)
  71.     #Triangles must be between sqrt(2n) and cbrt(2n)
  72.     for x in range(int((2*n)**(1/3.)),int((2*n)**.5)+1):
  73.         if (x**2+x) == 2*n:
  74.             return x
  75.     #If we don't find one we made a mistake
  76.     assert False
  77.  
  78. def getSimpleBF(n):
  79.     if n in cache:return cache[n]
  80.     if n < 0:
  81.         # There is room for better solutions here
  82.         return "["+getSimpleBF(-n)+"]"
  83.     elif n == 0:
  84.         return ""
  85.     elif n < 6:
  86.         return "()"*n
  87.     else:
  88.         #Non-edge cases
  89.         solutions = []
  90.     factors = getPrimeFactors(n)
  91.         if n >= 78 and isTriangular(n):
  92.             solutions.append(
  93.                 min([push(getTriangle(n))+"{({}[()])}{}","<"+push(getTriangle(n)+1)+">{({}[()])}{}"],key=len)
  94.             )
  95.     polynomialSolutions = polynomials(n)
  96.     for polynomial in polynomialSolutions:
  97.         solutions.append("<%s>{%s({}[()])%s}{}"%(push(polynomial[0]),"({})"*polynomial[1],"({})"*polynomial[2]))
  98.         #Mod 3 tricks
  99.         if n % 3 == 2:
  100.            solutions.append(("((%s)()){}{}")%getBF(n/3))
  101.         elif n % 3 == 1:
  102.            solutions.append(("((%s)()()){}{}")%getBF(n/3-1))
  103.         #Basic solutions
  104.         if isPrime(n):
  105.             solutions.append(getSimpleBF(n-1) + "()")
  106.         else:
  107.             #TODO multithread
  108.             solutions += map(lambda m:divHardcode(n,m),factors)
  109.         return min(solutions,key=lambda x:len(unpack(x)))
  110.  
  111. def getBF(n):
  112.     if n in cache: return cache[n]
  113.     result = getSimpleBF(n)
  114.     index = n - 1
  115.     while index > n-(len(result)/2):
  116.         score = getSimpleBF(index)+getSimpleBF(n-index)
  117.         if len(score) < len(result):result = score
  118.         index -= 1
  119.     index = n + 1
  120.     while index < n+(len(result)/2):
  121.         score = getSimpleBF(index)+getSimpleBF(n-index)
  122.         if len(score) < len(result):result = score
  123.         index += 1
  124.     cache[n] = result
  125.     return result
  126.  
  127. def unpack(string):
  128.     reMatch = re.match("\(*<",string)
  129.     if reMatch:
  130.         location =reMatch.span()
  131.         return string[location[1]:findMatch(string,location[1]-1)] +string[:location[1]-1] + string[findMatch(string,location[1]-1)+1:]
  132.     return string
  133.  
  134. def push(n):
  135.     return unpack("("+getBF(n)+")")
  136.  
  137. def kolmo(string):
  138.     code = push(ord(string[-1]))
  139.     stringVector = map(ord,string)
  140.     for x,y in zip(stringVector[-1:0:-1],stringVector[-2::-1]):
  141.         code = "("+code+getBF(y-x)+")"
  142.     code = code.replace("<()>)",")")
  143.     return code
  144.  
  145. if __name__ == "__main__":
  146.     print getBF(40)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement