Skip to main content
5 of 6
convert Sage to Python(2 & 3); comment on output length for various alphabet sizes
r.e.s.
  • 3.1k
  • 22
  • 32

Python (output-length: 18 or 19, mean 18.80)

#list of the 24 possible words 
Lbase = ['GTAC','GTCA','GATC','GACT','GCTA','GCAT','TGAC',\
'TGCA','TAGC','TACG','TCGA','TCAG','AGTC','AGCT','ATGC',\
'ATCG','ACGT','ACTG','CGTA','CGAT','CTGA','CTAG','CAGT','CATG']

#function to convert a word to its index(+1) in Lbase
num = lambda w: Lbase.index(w)+1

#base-64 alphabet (used only in the output string-representation) 
alph = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/'

#change a bijective list-representation base from b to newb 
def chg_bij_base(L, b, newb):
    n = sum([L[i]*b**i for i in range(len(L))])
    L = []
    while n > 0:
        nn = (n-1)//newb
        a = n - nn*newb
        L.append(a)
        n = nn
    return L

#convert a bijective list-repr. to base-64 string-repr.
def list_to_str(Lin):
    L24 = [num(w) for w in Lin]
    L64 = chg_bij_base(L24,24,64) 
    return ''.join([alph[i-1] for i in L64])
    
#convert a base-64 string to the corresponding base-64 list-repr.
def str_to_list(s):
    L64 = [alph.index(c)+1 for c in s]
    L24 = chg_bij_base(L64,64,24)
    return [Lbase[i-1] for i in L24]

Test run:

Lin = ["GTAC", "CATG", "TACG", "GACT", "GTAC", "CATG", "TACG", "GACT", "GTAC", "CATG", "TACG", "GACT", "GTAC", "CATG", "TACG", "GACT", "GTAC", "CATG", "TACG", "GACT", "GTAC", "CATG", "TACG", "GACT"]

#convert input list to a base-64 string  
lts = list_to_str(Lin) 

#convert the base-64 str back to the list   
stl = str_to_list(lts)

print(len(lts))
print(lts)
print(stl == Lin)

Test output:

18
acFZIBuiiZJ+dwUn2V
True

This uses bijective numeration (which has no 0 digit) to get invertibility.

NB: When using base-64 with this method, all output strings for the above problem are either 18 or 19 characters. (A million random inputs gave an average of 18.80.) The same method works with other bases:

base         output-length
---------    -------------
56 - 58      19
59 - 69      18 or 19
70 - 73      18
74 - 88      17 or 18
89 - 96      17
...          ...
233 - 256    14
r.e.s.
  • 3.1k
  • 22
  • 32