main.py 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-"
  3. """
  4. Goldbach - 2017/2020 - by psy (epsylon@riseup.net)
  5. You should have received a copy of the GNU General Public License along
  6. with Goldbach; if not, write to the Free Software Foundation, Inc., 51
  7. Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  8. """
  9. import os, sys
  10. import matplotlib.pyplot as plt
  11. from mpl_toolkits.mplot3d import Axes3D
  12. plt.rcParams.update({'figure.max_open_warning': 0})
  13. class Goldbach(object):
  14. def __init__(self):
  15. self.l="love"
  16. self.dimX=[]
  17. self.dimY=[]
  18. def banner(self):
  19. print(" ____ _ _ _ _ ")
  20. print(" / ___| ___ | | __| | |__ __ _ ___| |__ ")
  21. print("| | _ / _ \| |/ _` | '_ \ / _` |/ __| '_ \ ")
  22. print("| |_| | (_) | | (_| | |_) | (_| | (__| | | |")
  23. print(" \____|\___/|_|\__,_|_.__/ \__,_|\___|_| |_|")
  24. print("\n", 75*"=")
  25. print(" 'Every even integer greater than 2 can")
  26. print(" be expressed as the sum of two odd primes'")
  27. print(75*"=","\n")
  28. def is_prime(self, n):
  29. for i in range(3, n):
  30. if n % i == 0:
  31. return False
  32. return True
  33. def is_odd(self, n):
  34. if int(n) & 1:
  35. return True
  36. return False
  37. def is_valid_root(self, r):
  38. import random # generate pseudo-random number
  39. while True:
  40. n=(random.randint(4,100))
  41. r=self.is_odd(n)
  42. if r is False:
  43. break
  44. return n
  45. def threads(self, n):
  46. while True:
  47. n=n-1
  48. ion = self.is_odd(n)
  49. if ion is True:
  50. ipn = self.is_prime(n)
  51. if ipn is True:
  52. self.dimX.append(int(n))
  53. if n == 1:
  54. break
  55. else:
  56. pass
  57. else:
  58. pass
  59. def generate_graph(self):
  60. if not self.mode == "l" or self.mode == "L" or self.mode == "Learn" or self.mode == "learn":
  61. print("\n[Info] Generating 'plots' for number:", self.root)
  62. if not os.path.exists("graphs/"):
  63. os.mkdir("graphs/")
  64. if not self.mode == "l" or self.mode == "L" or self.mode == "Learn" or self.mode == "learn":
  65. print("\n + Thread(s):", len(self.tree))
  66. print(' - Tree =', self.tree)
  67. plt.figure()
  68. fig = plt.figure(1)
  69. ax = plt.gca(projection="3d")
  70. xs = []
  71. ys = []
  72. zs = []
  73. for t in self.tree:
  74. z = float(t.rsplit('=',1)[0])
  75. l = t.rsplit("+",2)[0]
  76. x = float(l.rsplit("=",1)[1])
  77. y = float(t.rsplit('+',1)[1])
  78. xs.append(x)
  79. ys.append(y)
  80. zs.append(z)
  81. ax.scatter(xs,ys,zs, c='red',s=100)
  82. ax.plot(xs,ys,zs, color='green')
  83. header = '"Tree" for number '+str(self.root)
  84. plt.title(header)
  85. plt.ylabel('Number(s)')
  86. plt.xlabel('Thread(s)')
  87. if not self.mode == "l" or self.mode == "L" or self.mode == "Learn" or self.mode == "learn":
  88. plt.show()
  89. g = "graphs/"+self.root
  90. if not os.path.exists(g):
  91. os.mkdir(g)
  92. f = open(g+"/"+self.root+"-Goldbach_tree.txt", 'wb')
  93. fig.savefig(g+"/"+self.root+"-Goldbach_graph.png")
  94. for t in self.tree:
  95. f.write(t.encode('utf-8'))
  96. f.close
  97. if not self.mode == "l" or self.mode == "L" or self.mode == "Learn" or self.mode == "learn":
  98. print("\n[Info] Generated 'tree' secuence at folder: "+g+"/\n")
  99. else:
  100. if not self.mode == "l" or self.mode == "L" or self.mode == "Learn" or self.mode == "learn":
  101. print("\n[Info] You have this 'tree' secuence previously saved...\n")
  102. ax.clear()
  103. plt.clf()
  104. print(75*"=", "\n")
  105. def generate_forest(self, rng):
  106. print("\n[Info] Generating 'forest' until range:", rng, "\n")
  107. rng=int(rng)
  108. for i in range(rng):
  109. i=i+1
  110. if i > 2:
  111. t = self.is_odd(i)
  112. if t is False:
  113. n = i
  114. self.root = str(n)
  115. print("[Info] Generating 'tree' for number:", self.root)
  116. self.generate_tree(n)
  117. def generate_tree(self, n):
  118. s=0 # seed counter
  119. t=0 # threads counter
  120. x=0 # x counter
  121. y=0 # y counter
  122. w=False # warning flag
  123. self.tree = []
  124. try:
  125. if int(n) & 1:
  126. print("\n[Error] Number should be always an even. Aborting...\n")
  127. return
  128. else:
  129. if int(n) <= 2:
  130. print("\n[Error] Number should be always an integer > 2. Aborting...\n")
  131. return
  132. else:
  133. self.threads(n)
  134. if not self.mode == "l" or self.mode == "L" or self.mode == "Learn" or self.mode == "learn":
  135. print("\n[Info] Prime numbers detected on serie:", len(self.dimX))
  136. self.dimY = self.dimX
  137. if not self.mode == "l" or self.mode == "L" or self.mode == "Learn" or self.mode == "learn":
  138. print("\n[Info] Calculating all possible permutations...\n")
  139. for p in self.dimX:
  140. for d in self.dimY:
  141. t = t + 1
  142. r = p + d
  143. if r == n:
  144. if not self.mode == "l" or self.mode == "L" or self.mode == "Learn" or self.mode == "learn":
  145. print(" Thread:" +str(t) , "->", p, "+", d, "=", r, "-> FOUND!")
  146. l = str(r)+ " = " + str(p)+" + "+str(d)
  147. if l not in self.tree:
  148. self.tree.append(l)
  149. else:
  150. if not self.mode == "l" or self.mode == "L" or self.mode == "Learn" or self.mode == "learn":
  151. print(" Thread:" + str(t), "->", p, "+", d, "=", r, "-> DISCARDED...")
  152. except:
  153. print("\n[Error] Number should be always an integer > 2. Aborting...\n")
  154. return
  155. print("\n[Info] Combinations found:", str(len(self.tree)), "\n")
  156. if not self.mode == "l" or self.mode == "L" or self.mode == "Learn" or self.mode == "learn":
  157. for t in self.tree:
  158. print(" ", t)
  159. graph=input("\nWanna generate a 'graph'? (Y/n)")
  160. if graph == "n" or graph == "N":
  161. print("")
  162. return
  163. else:
  164. self.generate_graph()
  165. else:
  166. self.generate_graph()
  167. def run(self, opts=None):
  168. self.banner()
  169. self.mode=input("Set mode: single random (default), manual, learning (S/m/l): ")
  170. print(40*"-")
  171. if self.mode == "m" or self.mode == "M" or self.mode == "Manual" or self.mode == "manual": #mode manual
  172. n=input("Set a number: ")
  173. try:
  174. n = int(n)
  175. except:
  176. print("\n[Error] Number should be always an even INTEGER greater than 2. Aborting...\n")
  177. sys.exit(2)
  178. elif self.mode == "l" or self.mode == "L" or self.mode == "Learn" or self.mode == "learn": #mode learning
  179. rng=input("Set max range (ex: 100 or 9000000) (PRESS ENTER = 100) (STOP = CTRL+z): ")
  180. if not rng:
  181. rng=100
  182. else: # mode single random
  183. r=input("Set max range (ex: 100 or 9000000) (PRESS ENTER = 100): ")
  184. if not r:
  185. r=100
  186. n = int(self.is_valid_root(r))
  187. if not self.mode == "l" or self.mode == "L" or self.mode == "Learn" or self.mode == "learn":
  188. self.root = str(n)
  189. print("[Info] Generating 'tree' for number:", self.root)
  190. self.generate_tree(n)
  191. else:
  192. try:
  193. rng = int(rng)
  194. except:
  195. print("\n[Error] Max range should be always an even INTEGER greater than 2. Aborting...\n")
  196. sys.exit(2)
  197. if not int(rng) > 2:
  198. print("\n[Error] Max range should be always an even integer GREATER THAN 2. Aborting...\n")
  199. sys.exit(2)
  200. else:
  201. t = self.is_odd(rng)
  202. if t is True:
  203. print("\n[Error] Max range should be always an EVEN integer greater than 2. Aborting...\n")
  204. sys.exit(2)
  205. else:
  206. self.generate_forest(rng)
  207. print("[Info] 'Forest' correctly generated. Exiting...\n")
  208. if __name__ == "__main__":
  209. app = Goldbach()
  210. app.run()