from visual import *
from numpy import *
import time
from sys import *
from random import *


#  Generate with the modular program, a stepwise process.
#  The idea is to freeze and reverse the modular structure of the virus,
#  hypothetically, inserting a prime at each stage.
#  so the modular structure is reversed with each modular sequence in
#  this stepwise process, with incremental primes.
#  we also need an initial prime to kick it out of place, although this may enable it, we would need a very specific prime
#  as in the number of modular steps that exist within the virus.

#  it must be very specific, as in a prime number of bases
#  at the end we need one, then three that 'commute' in the sense that primes may do so
#  and another prime.  These three primes must be evenly spaced, along the 1/logarithmic distribution.

#  These change the modular structure into a diamond, which is more symmetric, and
#  which leads to an inversion of its symmetry along the axis upon which it acts.

#  The inserted primes cause jump dislocations in the aperiodic structure, weakening it,
#  and retromorphing it into a symmetric and defused molecule that essentially cannot replicate
#  As well, the symmetry means the immune system will have an easier time defeating the virus.



infty = 2
infty2 = 2

var1 = 0
var2 = 0
                            # Modular ring variable initialization
M=210*30                    # up to this total ring size

sumo = 1                    # new total number of sets with property of commensurability
sump = 1                    # new total number of sets with or without property of commensurability

set_ratio = 1
set_with = 0                # average number of sets each new set contains
net_without = 1             # average number of sets each previous set contained

agreement_ratio = 1
property_ratio = 1
kappa = 1
beta = 1

                            # Accumulated average of ratios of combinatorial sets with the property of commensurability to total sets within sets.
                            # This is equivalent to finding, those sets that agree (or ones contained in each other), in combinatorial number.
                            # This ratio is the number of sets without this property to those with and without this property
                            # These are the contained and containing because it is the number with the agreement condition to those with or without it.
                            # Each set takes part in both processes of containment and being contained.  The total is the number of sets.
                            # This is the proportion of sets that are neither contained nor the container.
                            # This is with the agreement condition.

totalwithproperty = 1
total = 1
k = 0                       # for the average




k=0                         # Prime sequence initialization.
limit = M

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)

maxN = 210*30
N = maxN
continual = list()





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 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

def primenumber(k):
    k += 1
    
    for x in xrange(len(As)):
        for y in xrange(len(As)):
            if As[x] != 1 and As[y] != 1:
                b = As[x]*As[y]

                if b > limit:
                    pass
                else:            
                    if Cs.count(b) == 0:
                        Cs.append(b)

    r = subtraction(subtraction(As,intersection(Cs,As)),Bs)
    r.sort()

    if len(r)==0:
        pass
    else:
        if Bs.count(r[0])==0:
            Bs.append(r[0])
    if As.count(k+1) == 0:
        As.append(k+1)
        
    As.sort()
    Cs.sort()            
    Bs.sort()
    
    return(Bs[k])


def between(x):
    return go(x)

def go(x,t,k):
    y = naturalnumbers(x)[0]
    z = naturalnumbers(x)[1]
    v = 1-y/z
    if k == 1:
        t = 0
        pass
    else:
        t = y**(between(x))/(1-(y/z)**v)
        k = 1
    return [t]

def naturalnumbers(l):
    total = 1
    k = 0
    for n in xrange(1,int((l+1)/2)+1):
        k += 1

        l1=lcm(n,l)/n
        l2=lcm(l-n+1,l)/(l-n+1)

        a = choose(l,n-1)
        b = choose(l,l-n-1)

        if n == (l+1)/2:        
            total += 1
        else:
            total += 2
            
        sump += (a*b)
        
        if l1==l2 and n != (l+1)/2:
            totalwithproperty += 2
            sumo += 2*(a*b)
        if l1==l2 and n == (l+1)/2:
            totalwithproperty += 1
            sumo += (a*b)

        kappa = float(sump-sumo)/float(sump)
        beta = float(totalwithproperty)/float(total)
        
        set_ratio = set_ratio + kappa
        property_ratio = property_ratio + beta

        print("Property Ratio (pi):",1/(property_ratio/k),"Set Ratio (pi*?):",1/(set_ratio/k),"Their Ratio (?):",set_ratio/property_ratio)

    return [1/(set_ratio/k),1/(property_ratio/k)]      # e






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")

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


             # Modular structure initialization of variables
a = 1
k = 0
l = 0
n = 0
o = 0
g = 0
p = 0
r = 0
m = maxN
irr = 0
irro = 0
kappa = 1.0
length = len(continual)
setsize = length
N = setsize
convergecount = 30


for o in xrange(maxN):
    k = o
    l = 1	    # with l = 1 e(e-1), with l = 2
    j = 1
    b = 0
    h = 0
    p = 0
    n = k
    irro = irr
    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)*naturalnumbers(l)[0]**(-m*l/n)

    print(irro)
    print(irr)

    if abs(irr-irro) > .0005:
        element = primenumber(n)
        print(element)
        
    print(go(k,t,y)[0])
    print(modularstruct(k))
    print(primenumber(k))
    
    if irr != 0.0:
        inv = 1/irr
    else:
        inv = 1
        
    print("Number:",irr,"o:",o,"Inverse Number:",inv)
        






    
