from vpython import *
from random import *

primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271]

scene.width = 600
scene.height = 600

graphone = gcurve(color=color.cyan)

##graphtwo = gcurve(color=color.red)
##graphthree = gcurve(color=color.yellow)

##newlist1 = list()
##newlist2 = list()

##graphpos = list()
##graphipos = list()
##graphdpos = list()

##thesum = 0
##total = 0
##
##maxRun = 1
##
##run = 0
##
##v = 0
##l = -v


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

maxN = 128     #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)
    l3=gcd(n,N-n+1)
    
##    if l1==l2 and primes.count(n) == 1:
##        continual.append("T")
##    if l1==l2 and primes.count(n) != 1:
##        continual.append("F")
##    if l1 != l2 and primes.count(n) == 1:
##        continual.append("O")
##    if l1 != l2 and primes.count(n) != 1:
##        continual.append("C")

    print(l1,l2,-l3)


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

##makeRandomString(continual)

e = 2.718281828
a = 6
k = 0
l = 0
n = 0
o = 0
g = 0
p = 0
r = 0
m = maxN
irr = 0
kappa = 1.0
length = len(continual)
setsize = length
N = setsize
convergecount = 120

while o < setsize:
    o += 1
    k = o
    l = 1	    # with l = 1 e(e-1), with l = 2
    j = 1
    b = 0
    p = 0
    n = k
    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)

    graphone.plot(pos=(n,irr))
        
    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






# this is a form of universality in disease prevention.... disease has no complete universal attribute, but there do exist some universal processes of prevention.





##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]))    

