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']
#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:
L.append(1+(n-1)%newb)
n = (n-1)//newb
return L
#convert a bijective list-repr. to base-64 string-repr.
def list_to_str(Lin):
L24 = [Lbase.index(w)+1 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