Browse Source

moved from https://github.com/epsylon/collatz

psy 5 years ago
parent
commit
e5f4451a3c
4 changed files with 471 additions and 2 deletions
  1. 64 2
      README.md
  2. 209 0
      collatz/LICENSE
  3. 13 0
      collatz/collatz
  4. 185 0
      collatz/main.py

+ 64 - 2
README.md

@@ -1,3 +1,65 @@
-# collatz
 
-An unsolved problem in mathematics...
+![c](https://03c8.net/images/collatz_banner.png)
+
+----------
+
+#### Info:
+
+ Problem: https://en.wikipedia.org/wiki/Collatz_conjecture
+
+ Collatz is a researching tool that simulates 'Collatz's conjecture' math problem on a computacional level.
+
+ It will provide you all maths requirements to see results of desided combinations, applying automatically conjeture rules. 
+
+ This is very useful to simplify human abstraction level.
+
+ There are 3 possible modes for interaction: single random, manual and learning.
+
+    - single random (default): Just a simple random test that will allow you to understand how it works.
+    - manual: You can search for results on any number you enter.
+    - learning: Your AI will like this feature a lot ;-)
+
+ You can visualize plotting graphs with results, store math 'tree' relationships (so the tool doesn't need to process again similar data) 
+ and organized auto-save your results, for example, to be used on a future for BigData processing or AI maths solving tasks.
+
+#### Installing:
+
+ This tool runs on many platforms and it requires Python (2.x.y). To generate graphs, you need 
+ to install the following library:
+
+       python-matplotlib - Python based plotting system in a style similar to Matlab
+
+ On Debian-based systems (ex: Ubuntu), run: 
+
+       sudo apt-get install python-matplotlib
+
+ Or:
+       
+       pip install matplotlib
+
+####  Source libs:
+
+ * PyMatplotlib: https://pypi.python.org/pypi/matplotlib
+
+#### License:
+
+ Collatz is released under the GPLv3.
+
+#### Contact:
+
+      - psy (epsylon@riseup.net)
+
+#### Contribute: 
+
+ To make donations use the following hash:
+  
+     - Bitcoin: 19aXfJtoYJUoXEZtjNwsah2JKN9CK5Pcjw
+
+----------
+
+####  Screenshots:
+
+  ![c](https://03c8.net/images/collatz_tree.png "Collatz Tree")
+
+  ![c](https://03c8.net/images/collatz_graph.png "Collatz Graph")
+

File diff suppressed because it is too large
+ 209 - 0
collatz/LICENSE


+ 13 - 0
collatz/collatz

@@ -0,0 +1,13 @@
+#!/usr/bin/env python 
+# -*- coding: utf-8 -*-"
+"""
+Collatz - 2017 - by psy (epsylon@riseup.net)
+
+You should have received a copy of the GNU General Public License along
+with Collatz; if not, write to the Free Software Foundation, Inc., 51
+Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+"""
+from main import Collatz
+if __name__ == "__main__":
+    app = Collatz()
+    app.run()

+ 185 - 0
collatz/main.py

@@ -0,0 +1,185 @@
+#!/usr/bin/env python 
+# -*- coding: utf-8 -*-"
+"""
+Collatz - 2017 - by psy (epsylon@riseup.net)
+
+You should have received a copy of the GNU General Public License along
+with Collatz; if not, write to the Free Software Foundation, Inc., 51
+Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+"""
+import os, sys
+import matplotlib.pyplot as plt
+
+class Collatz(object):
+    def __init__(self):
+        self.m=False
+
+    def banner(self):
+        print "  ____      _ _       _               "
+        print " / ___|___ | | | __ _| |_ ____        "
+        print "| |   / _ \| | |/ _` | __|_  /        "
+        print "| |__| (_) | | | (_| | |_ / /         "
+        print " \____\___/|_|_|\__,_|\__/___|        "
+        print " 'Natural integers always becomes 1?' "
+        print "\n", 75*"="
+        print " - RULE 1: if n is 'even' then n = n/2"
+        print " - RULE 2: if n is 'odd' then n = 3n+1"
+        print 75*"=","\n"
+
+    def generate_graph(self):
+        if not self.mode == "l" or self.mode == "L" or self.mode == "Learn" or self.mode == "learn":
+            print "[Info] Generating 'plots' for number:", self.root
+        if not os.path.exists("graphs/"):
+            os.mkdir("graphs/")
+        if not self.mode == "l" or self.mode == "L" or self.mode == "Learn" or self.mode == "learn":
+            print "\n   + Thread(s):", len(self.tree)
+            print '     - Tree =', self.tree
+        plt.figure()
+        fig = plt.figure(1)
+        ax = fig.add_subplot(111, facecolor='black')
+        for t in self.tree:
+            ax.scatter(self.tree.index(t)+1, t, color="red", s=2)
+        header = '"Tree" for number '+str(self.root)+' to becomes 1'
+        plt.title(header)
+        plt.ylabel('Number(s)')
+        plt.xlabel('Thread(s)')
+        if not self.mode == "l" or self.mode == "L" or self.mode == "Learn" or self.mode == "learn":
+            plt.show()
+        g = "graphs/"+self.root
+        if not os.path.exists(g):
+            os.mkdir(g)
+            f = open(g+"/"+self.root+"-collatz_tree.txt", 'wb')
+            fig.savefig(g+"/"+self.root+"-collatz_graph.png")
+            f.write(str(self.tree))
+            f.close
+            if not self.mode == "l" or self.mode == "L" or self.mode == "Learn" or self.mode == "learn":
+                print "\n[Info] Generated 'tree' secuence at folder: "+g+"/\n"
+        else:
+            if not self.mode == "l" or self.mode == "L" or self.mode == "Learn" or self.mode == "learn":
+                print "\n[Info] You have this 'tree' secuence previously saved. Exiting...\n"
+        ax.clear()
+
+    def generate_forest(self, rng):
+        srng = rng.split('-')
+        try:
+            x=int(srng[0])
+            y=int(srng[1])
+        except:
+            print "\n[Error] Numbers on range should be integers (ex: 427-8981318). Aborting...\n"
+            sys.exit(2)
+        print "[Info] Generating 'forest' for range:", rng, "\n"
+        if x < y:
+            for i in range(x,y+1):
+               n = i
+               self.root = str(n)
+               if not self.mode == "l" or self.mode == "L" or self.mode == "Learn" or self.mode == "learn":
+                   print "[Info] Generating 'tree' for number:", self.root
+               self.generate_tree(n)
+        else:
+            for i in range(y,x+1):
+               n = i
+               self.root = str(n)
+               print "[Info] Generating 'tree' for number:", self.root
+               self.generate_tree(n)
+
+    def generate_tree(self, n):
+        t=0 # threads counter
+        o=0 # odds counter
+        e=0 # evens counter
+        w=False # warning flag
+        self.tree = []
+        while True:
+            t=t+1
+            if not self.mode == "l" or self.mode == "L" or self.mode == "Learn" or self.mode == "learn":
+                print ""
+            try:
+                if int(n) != 1:
+                    if int(n) <= 0:
+                        self.m=True
+                        print "[Error] First number should be always > 0. Aborting...\n"
+                        sys.exit(2)
+                    else:
+                        self.m=False
+                        if not self.mode == "l" or self.mode == "L" or self.mode == "Learn" or self.mode == "learn":
+                            print "   + Thread:", t
+                        self.tree.append(int(n))
+                        if int(n) & 1:
+                            if not self.mode == "l" or self.mode == "L" or self.mode == "Learn" or self.mode == "learn":
+                                print '     - Root =', n, "[odd]"
+                            r=3*int(n)+1
+                            if not self.mode == "l" or self.mode == "L" or self.mode == "Learn" or self.mode == "learn":
+                                print '     - New  =', r, '[3*'+str(n)+'+1='+str(r)+"]"
+                            o=o+1
+                        else:
+                            if not self.mode == "l" or self.mode == "L" or self.mode == "Learn" or self.mode == "learn":
+                                print '     - Root =', n, "[even]"
+                            r=int(n)/2
+                            if int(r) == 1:
+                                w=True
+                            if not self.mode == "l" or self.mode == "L" or self.mode == "Learn" or self.mode == "learn":
+                                print '     - New  =', r, "["+str(n)+'/2='+str(r)+"]"
+                            e=e+1
+                    n = r
+                else:
+                    if w is False:
+                        if not self.mode == "l" or self.mode == "L" or self.mode == "Learn" or self.mode == "learn":
+                            print "   + Thread:", t
+                        self.tree.append(int(n))
+                        if not self.mode == "l" or self.mode == "L" or self.mode == "Learn" or self.mode == "learn":
+                            print '     - Root =', n, "[odd]"
+                        r=3*int(n)+1
+                        if not self.mode == "l" or self.mode == "L" or self.mode == "Learn" or self.mode == "learn":
+                            print '     - New  =', r, '[3*'+str(n)+'+1='+str(r)+"]"
+                        o=o+1
+                        w = True
+                        n = r
+                    else:
+                        break
+            except:
+                import random # generate pseudo-random number
+                n=(random.randint(1,9999))
+                print "[Error] First number should be an integer (ex: "+str(n)+"). Aborting...\n"
+                m = True
+                sys.exit(2)
+        if self.m is False:
+            print 100*"-"
+            print "[Info] Number "+self.root+ " takes "+str(int(t)-1)+" threads using "+str(o)+" odds and "+str(e)+" evens to becomes 1"
+            print 100*"-","\n"
+            if not self.mode == "l" or self.mode == "L" or self.mode == "Learn" or self.mode == "learn":
+                graph=raw_input("Wanna generate a 'graph'? (Y/n)")
+                if graph == "n" or graph == "N":
+                    print ""
+                    sys.exit(2)
+                else:
+                    self.generate_graph()
+            else:
+                self.generate_graph()
+
+    def run(self, opts=None):
+        self.banner()
+        self.mode=raw_input("Set mode: single random (default), manual, learning (S/m/l): ") 
+        print 40*"-"
+        if self.mode == "m" or self.mode == "M" or self.mode == "Manual" or self.mode == "manual": #mode manual
+            n=raw_input("Set a number: ")
+        elif self.mode == "l" or self.mode == "L" or self.mode == "Learn" or self.mode == "learn": #mode learning
+            rng=raw_input("Set range (ex: 1-100 or 345-890 (PRESS ENTER = 1-100) (STOP = CTRL+z): ")
+            if not rng:
+                rng="1-100"
+        else: # mode single random
+            r=raw_input("Set a max range (ex: 9999999) (PRESS ENTER = 9): ")
+            if not r:
+                r=9
+            import random # generate pseudo-random number
+            n=(random.randint(1,int(r)))
+        if not self.mode == "l" or self.mode == "L" or self.mode == "Learn" or self.mode == "learn":
+            self.root = str(n)
+            print " + Generating 'tree' for number:", self.root
+            self.generate_tree(n)
+        else:
+            print 75*"="
+            self.generate_forest(rng)
+            print "[Info] 'Forest' correctly generated. Exiting...\n"
+
+if __name__ == "__main__":
+    app = Collatz()
+    app.run()