Advertisement
wheatwizard

Generative program

Oct 5th, 2016
235
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.35 KB | None | 0 0
  1. import re
  2. cache = {0:"<()>"}
  3. def complement(character):
  4. dict = {"(":")","{":"}","<":">","[":"]",")":"(","}":"{",">":"<","]":"["}
  5. return dict[character]
  6. def findMatch(snippet, index):
  7. increment = 1 if snippet[index] in "({<[" else -1
  8. stack = []
  9. if snippet[index] in "(){}<>[]":
  10. stack.append(snippet[index])
  11. while len(stack) > 0 and index + increment < len(snippet):
  12. index += increment
  13. if snippet[index] in "(){}<>[]":
  14. if complement(snippet[index]) == stack[-1]:
  15. stack = stack[:-1]
  16. else:
  17. stack.append(snippet[index])
  18. return index
  19. def isTriangular(n):
  20. #Triangles must be between sqrt(2n) and cbrt(2n)
  21. if n < 0: return isTriangular(-n)
  22. for x in range(int((2*n)**(1/3.)),int((2*n)**.5)+1):
  23. if (x**2+x) == 2*n:
  24. return True
  25. return False
  26. def getTriangle(n):
  27. if n < 0: return -getTriangle(-n)
  28. #Triangles must be between sqrt(2n) and cbrt(2n)
  29. for x in range(int((2*n)**(1/3.)),int((2*n)**.5)+1):
  30. if (x**2+x) == 2*n:
  31. return x
  32. #If we don't find one we made a mistake
  33. assert False
  34. def getPolygon(n):
  35. sides = 1
  36. while sides < n:
  37. acc = 1
  38. size = 1
  39. while acc <= n:
  40. if acc == n:
  41. return (sides, size)
  42. acc += size * sides
  43. size += 1
  44. sides += 1
  45. def isPrime(n):
  46. return not [0 for x in range(2,int(n**.5)+1) if n%x==0] and n>1
  47. def getPrimeFactors(n):
  48. return [x for x in range(2,n/2) if n%x==0 and isPrime(x)]
  49. def divHardcode(n,m):
  50. assert n%m == 0
  51. return "("*(m-1)+getBF(n/m)+")"*(m-1)+"{}"*(m-1)
  52. def getSimpleBF(n):
  53. if n in cache:return cache[n]
  54. if n < 0:
  55. # There is room for better solutions here
  56. return "["+getSimpleBF(-n)+"]"
  57. elif n == 0:
  58. return ""
  59. elif n < 6:
  60. return "()"*n
  61. else:
  62. #Non-edge cases
  63. solutions = []
  64. if n >= 78 and isTriangular(n):
  65. solutions.append(
  66. min(["("+getBF(getTriangle(n))+"){({}[()])}{}","<("+getBF(getTriangle(n)+1)+")>{({}[()])}{}"],key=len)
  67. )
  68. # The second try used to be more useful but now it seems like vesigial code
  69. # I should look into whether or not it actually improves anything significantly
  70. # There are 655 values in the first 10000 that are improved by this code
  71. # That makes a rate of 0.7%
  72. if isPrime(n):
  73. return getSimpleBF(n-1) + "()"
  74. else:
  75. #TODO multithread
  76. factors = getPrimeFactors(n)
  77. solutions += map(lambda m:divHardcode(n,m),factors)
  78. return min(solutions,key=len)
  79. def getBF(n):
  80. global cache
  81. if n in cache: return cache[n]
  82. result = getSimpleBF(n)
  83. index = n - 1
  84. while index > n-(len(result)/2):
  85. score = getSimpleBF(index)+getSimpleBF(n-index)
  86. if len(score) < len(result):result = score
  87. index -= 1
  88. index = n + 1
  89. while index < n+(len(result)/2):
  90. score = getSimpleBF(index)+getSimpleBF(n-index)
  91. if len(score) < len(result):result = score
  92. index += 1
  93. cache[n] = result
  94. return result
  95. def unpack(string):
  96. reMatch = re.match("\(*<",string)
  97. if reMatch:
  98. location =reMatch.span()
  99. return string[location[1]:findMatch(string,location[1]-1)] +string[:location[1]-1] + string[findMatch(string,location[1]-1)+1:]
  100. return string
  101. def push(n):
  102. return unpack("("+getBF(n)+")")
  103. def Triangle(n):return n**2+n
  104. print map(lambda x:push(ord(x)),'++*2J*4\++j"[]"+\-j"><"J">.'[::-1])
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement