from visual.graph import *
from random import *

scene.width = 600
scene.height = 600

graphone = gcurve(color=color.cyan,xpos="400",ypos="200")

k=0
limit = 2000

As=list()           # list of natural numbers
Bs=list()           # list of primes
Cs=list()           # list of product numbers

As.append(1)
As.append(2)

Bs.append(1)
Bs.append(2)

Cs.append(1)
Cs.append(2)



def su(element1,element2):
    if element1 == "T" and element2 == "T":
        return('T')
    if element1 == "T" and element2 == "F":
        return('O')
    if element1 == "T" and element2 == "O":
        return('O')
    if element1 == "T" and element2 == "C":
        return('T')

        
    if element1 == "F" and element2 == "T":
        return('O')
    if element1 == "F" and element2 == "F":
        return('F')
    if element1 == "F" and element2 == "O":
        return('O')
    if element1 == "F" and element2 == "C":
        return('F')
        
        
    if element1 == "O" and element2 == "T":
        return('O')
    if element1 == "O" and element2 == "F":
        return('O')
    if element1 == "O" and element2 == "O":
        return('O')
    if element1 == "O" and element2 == "C":
        return('O')

    if element1 == "C" and element2 == "T":
        return('T')
    if element1 == "C" and element2 == "F":
        return('F')
    if element1 == "C" and element2 == "O":
        return('O')  
    if element1 == "C" and element2 == "C":
        return('C')

def ci(element1,element2):
    if element1 == "T" and element2 == "T":
        return('T')
    if element1 == "T" and element2 == "F":
        return('C')
    if element1 == "T" and element2 == "O":
        return('T')
    if element1 == "T" and element2 == "C":
        return('C')

        
    if element1 == "F" and element2 == "T":
        return('C')
    if element1 == "F" and element2 == "F":
        return('F')
    if element1 == "F" and element2 == "O":
        return('F')
    if element1 == "F" and element2 == "C":
        return('C')
        
        
    if element1 == "O" and element2 == "T":
        return('T')
    if element1 == "O" and element2 == "F":
        return('F')
    if element1 == "O" and element2 == "O":
        return('O')
    if element1 == "O" and element2 == "C":
        return('C')

    if element1 == "C" and element2 == "T":
        return('C')
    if element1 == "C" and element2 == "F":
        return('C')
    if element1 == "C" and element2 == "O":
        return('C')  
    if element1 == "C" and element2 == "C":
        return('C')

def gcd(m,n):
    while n:
        m,n=n,m%n
    return m

def lcm(a, b):
    return a*b/gcd(a,b)

def fac(N):
    m=1
    for x in xrange(1,int(N)):
        m=m*(int(N)-x+1)
    return m

def choose(a,b):
    return int(fac(a)/(fac(b)*fac(a-b)))

    
def product(newlist):
    product = "O"
    for m in xrange(len(newlist)-1):
        product = su(newlist[m],product)
    return product

def graphlist(givenlist):
    total = 0.0
    outlist = list()
    for n in xrange(maxN-1):
        if givenlist[n] == "T":
            total += 1
        if givenlist[n] == "F":
            total -= 1
        average = total/(n+1)
        outlist.append(average)
    return outlist

def makeRandomString(listtowrite):
    l = 0
    while l < maxN:  
        l += 1
        
        U = random()
        if 0 < U < .3333:
            W = "T"
        if .3333 < U < .6666:
            W = "O"
        if .6666 < U < 1:
            W = "F"
        listtowrite.append(W)

def multiplySU(listone,listtwo):
    output = list()
    for m in xrange(maxN-1):
        output.append(su(listone[m],listtwo[m]))
    return output

def multiplyCI(listone,listtwo):
    output = list()
    for m in xrange(maxN-1):
        output.append(ci(listone[m],listtwo[m]))
    return output

def reverseMap(inputlist):
    output = list()
    for m in xrange(maxN-1):
        element = inputlist[m]
        if element == "T":
            elementout = "F"
        if element == "F":
            elementout = "T"
        if element == "O":
            elementout = "C"
        if element == "C":
            elementout = "O"
        output.append(elementout)
    return output

def sectionProduct(length,inputlist):
    output = list()
    for m in xrange(maxN-1):
        mini = list()
        for l in xrange(length):
            if (m+l) > maxN-2:
                mini.append(inputlist[m+l-maxN])
            else:
                mini.append(inputlist[m+l])
        element = product(mini)
        output.append(element)
    return output

def sectionProductBehind(length,inputlist):
    output = list()
    for m in xrange(maxN-1):
        mini = list()
        for l in xrange(length):
            if (m-l) < 0:
                mini.append(inputlist[m-l+maxN])
            else:
                mini.append(inputlist[m-l])
        element = product(mini)
        output.append(element)
    return output

def intersection(list1,list2):
    outlist = list()
    for x in xrange(len(list2)):
        if list1.count(list2[x]) == 0:
            pass
        else:
            if outlist.count(list2[x]) == 0:
                outlist.append(list2[x])
            else:
                pass
    return outlist

def subtraction(list1,list2):               ## list 2 from list 1
    outlist = list()
    for x in xrange(len(list1)):
        outlist.append(list1[x])
    for x in xrange(len(list2)):
        if outlist.count(list2[x]) == 0:
            pass
        else:
            outlist.pop(outlist.index(list2[x]))
    return outlist

def copylist(list1):
    outlist = list()
    for x in xrange(len(list1)):
        outlist.append(list1[x])
    return outlist






maxN = 1100     #210 - 4pi, 
N = maxN
continual = list()

for n in xrange(1,maxN+1):
    l1=lcm(n,N)/n
    l2=lcm(N-n+1,N)/(N-n+1)

    if l1 == l2:
        continual.append("T")
    else:
        continual.append("F")

makeRandomString(continual)

e = 2.718281828
avg = 0.0
a = 0
q = 0
l = 0
n = 0
o = 0
g = 0
p = 0
r = 0
z = 1
m = maxN
irr = 0
irro = 0
kappa = 1.0
length = len(continual)
setsize = length
N = setsize
convergecount = 120

while o < setsize:
    o += 1
    q = o
    l = 0	    # with l = 1 e(e-1), with l = 2
    j = 1
    b = 0
    p = 0
    n = q

    irr = 0
    
    while b < convergecount:
        
        b += 1
        p += 1
        index = (p*a+n)%m
        if continual[index] == "T":
            n += 1
        if continual[index] == "F":
            n -= 1
        l += 1
        if n < 1:
            n = -n
            n += 1
        if l < 0:
            l = -l
        
        irr = irr + float(j)*e**(-m*l/n)

##    if abs(irr-irro) > abs(irro-irrb):
##        z += 1
##        print("leap",z,"trial",o,"ratio",float(z)/float(o))
##    if o == 0:
##        pass
##    else:
##        avg = avg + float(z)/float(o)
##    graphone.plot(pos=(n,float(z)/float(o)))
        
    if irr != 0.0:
        inv = 1/irr
    else:
        inv = 1

    print("Number:",irr,"o:",o,"Inverse Number:",inv)







## m,n number setsize 7
## 1,2 0.0123456825561
## 1,3 0.0158125044765
## 1,4 0.0158125044765
## 2,3 0.0123456825561
## 3,5 2.36782204638e-07











##for n in xrange(maxN-1):
##    newlistone.append(su(newlist[n],newlist[n+1]))
##    newlisttwo.append(ci(newlist[n],newlist[n+1]))
##        
##print("New List",newlist)
##print("Integral",newlistone)
##print("Derivative",newlisttwo)
##
##graphpositions = graphlist(newlist)
##graphipositions = graphlist(newlistone)
##graphdpositions = graphlist(newlisttwo)
##    
##for n in xrange(maxN-1):
##    graphone.plot(pos=(n,graphpositions[n]))
##    graphtwo.plot(pos=(n,graphipositions[n]))
##    graphthree.plot(pos=(n,graphdpositions[n]))    

