using Plots
using StatsBase
function GetNum(X,n=1)
local Rx
function BuildRegEx(n)
n<=1 && return Regex("([a-z])")
Regex("([a-z])\\s."*BuildRegEx(n-1).pattern)
end
Rx=BuildRegEx(n)
countmap([join(m.captures)
for m in eachmatch(Rx,lowercase(X))])
end
function GenSubst(X)
local alpha, state
alpha = collect('a':'z')
state=Dict{Char,Char}()
for x in 1:length(alpha)
state[alpha[x]]=X[x]
end
return m->state[m]
end
function GenInvSubst(X)
local alpha, state
alpha = collect('a':'z')
state=Dict{Char,Char}()
for x in 1:length(alpha)
state[X[x]]=alpha[x]
end
return m->state[m]
end
function ApplySubst(σ)
m->join( [σ(x) for x in m ] )
end
function EncodeMono(m,K)
σ=GenSubst(K)
ApplySubst(σ)(lowercase(filter(isletter,m)))
end
function DecodeMono(m,K)
θ=GenInvSubst(K)
ApplySubst(θ)(lowercase(filter(isletter,m)))
end
function CaesarSub(x)
GenSubst(join(x:'z')*join('a':(x-1)))
end
function CaesarInvSub(x)
GenInvSubst(join(x:'z')*join('a':(x-1)))
end
function EncodeCaesar(m,K)
σ=CaesarSub(K)
ApplySubst(σ)(lowercase(filter(isletter,m)))
end
function DecodeCaesar(m,K)
θ=CaesarInvSub(K)
ApplySubst(θ)(lowercase(filter(isletter,m)))
end
function PolySubst(m,K)
local m0
local c
c=""
m0=lowercase(filter(isletter,m))
for i in 1:length(m0)
σ=CaesarSub(K[mod1(i,length(K))])
c=c*σ(m0[i])
end
join(c)
end
function PolyInvSubst(m,K)
local m0
local c
c=""
m0=lowercase(filter(isletter,m))
for i in 1:length(m0)
σ=CaesarInvSub(K[mod1(i,length(K))])
c=c*σ(m0[i])
end
join(c)
end
function κ(m)
local m0
local d
local fr
fr=GetNum(m)
d::Float64=sum(values(fr))
sum([ i*(i-1)/(d*(d-1)) for i::Float64 in values(fr) ])
end
function computeIk(m,tgt=20)
local r
r=[]
for i in 1:tgt
push!(r, κ(m[1:i:end]))
end
r
end
function findLen(m)
gcd(sortperm(computeIk(m),rev=true)[1:3])
end