Trăn 781 731 605 579 Chars
Có rất nhiều câu trả lời hay hơn và tốt hơn từ khi tôi lần đầu tiên nhìn thấy điều này, nhưng tôi đã lãng phí rất nhiều thời gian cho kịch bản python của mình vì vậy tôi sẽ đăng nó bằng mọi cách, thật tuyệt vời khi thấy các đề xuất để rút ngắn hơn nữa,
Chỉnh sửa: nhờ các gợi ý của Ed H, 2 ký tự được cắt nhỏ, để đi xa hơn tôi có thể phải cơ cấu lại rất nhiều thứ ở đây sẽ mất một thời gian
s="e |nd|-We| a|-(Ooh|N| what|ive| go|ay it-|I|er|G|o |make5 |D| th| othH |A| tF|ing |nna |tell|'s been|'rS|-You|-N4| know|L5 up|PR | you|evHK>| how I'm feeling-|O, g7)|O)9gL, n4gL-(G7)|-I just wa>=53Gotta EuRHstaR-.|Q've8n eachBfor sFlong:r heart<Pch?but:;toFshy@sJInsidSwSboth8M<K?onQ8CSgame6we;go>plJ|9g79let5 down9runProuR6desHt59Ecry9sayKodbye9=P lie6hurt5-|\n|Q;nFstrangHs@love:8CSrules6sFdFI-A full commitment'sM I'mCink?of: wouldn't getCis fromPnyBguy0/AR if5Psk me3Don't = me5;toFbliR@see-..2211-/0..";i=83
exec"x,s=s.split('|',1);s=s.replace(chr(i),x);i-=1"*39
print s
Sau lần đầu tiên tôi tự sản xuất chuỗi (rất tẻ nhạt), tôi đã viết một hàm để tìm đệ quy mô hình thay thế có lợi nhất (ở bước đó), cho tôi một giải pháp nhưng hóa ra lại tăng kích thước lên 10 ký tự
Vì vậy, tôi đã làm cho thuật toán của mình bớt tham lam hơn một chút bằng cách thay vì chỉ xếp hạng cuối cùng trên 'ký tự giảm', xếp hạng theo chức năng 'giảm ký tự', 'chiều dài mẫu' và 'số mẫu'
chiều dài mẫu = đếm chiều dài = đếm
rank = [(length-1)*count - length - 2] + lengthWeight * length + countWeight * count
Sau đó, tôi yêu cầu máy tính xách tay nghèo của tôi chạy vô hạn, gán các giá trị ngẫu nhiên cho lengthWeight
vàcountWeight
và có được kích thước nén thức khác nhau, và lưu trữ dữ liệu cho kích thước nén tối thiểu trong một file
Trong nửa giờ hoặc lâu hơn, nó đã xuất hiện chuỗi trên (tôi đã cố gắng sửa lại nó để xem liệu tôi có thể rút ngắn mã không), và nó sẽ không giảm nữa, tôi đoán tôi đang thiếu một cái gì đó ở đây.
Đây là mã của tôi cho nó, cũng max_pattern
rất chậm (Lưu ý: mã tạo ra một chuỗi tương tự như trong phiên bản giải pháp trước đây của tôi, tôi đã làm việc thủ công thông qua nó để có được hình thức hiện tại, theo cách thủ công, theo cách thủ công trong vỏ python)
import itertools
global pretty
global split
split = False
pretty = False
# try to keep as much visibility as possible
def prefrange():
return range(32,127) + ([] if pretty else ([10, 9, 13] + [x for x in range(32) if x not in (10, 9, 13)] + [127]))
def asciichr():
return [chr(x) for x in prefrange()]
def max_pattern(s, o, lenw, numw):
l = len(s)
patts = []
for c in range(l/2+1,1,-1):
allsub = [s[i:i+c] for i in range(0, l, c)]
subcounts = [[a, s.count(a)] for a in allsub if len(a) == c]
repeats = [(x, y, ((c-o)*y - o*2 - c)) for x, y in subcounts if y > 1]
ranks = [(x, y, (z + lenw*c + numw*y)) for x,y,z in repeats if z > 0]
patts = patts + ranks
try:
return sorted(patts, key=lambda k: -k[2])[0]
except:
return None
def sep():
return '~~' if pretty else chr(127) + chr(127)
def newcharacter(s):
doable = [x for x in asciichr() if x not in s]
if len(doable) == 0:
doable = list(set(x+y for x in asciichr() for y in asciichr() if x+y not in s and x+y != sep()))
if len(doable) == 0:
return None
return doable[0]
def joined(s, l):
one = [x for x in l if len(x)==1]
two = [x for x in l if len(x)==2]
return ''.join(reversed(two)) + sep() + ''.join(reversed(one)) + sep() + s
def compress(s, l=[], lenw=0, numw=0):
newchr = newcharacter(s)
if newchr == None:
if not l:
return s
return joined(s,l)
else:
ptn = max_pattern(s, len(newchr), lenw, numw)
if ptn == None:
if not l:
return s
return joined(s, l)
s = s.replace(ptn[0], newchr)
s = ptn[0] + newchr + s
l.append(newchr)
return compress(s, l, lenw, numw)
def decompress(s):
lst2, lst, s = s.split(sep(),2)
li = [lst2[i:i+2] for i in xrange(0, len(lst2), 2)]+list(lst)
for c in li:
x, s = s.split(c, 1)
s = s.replace(c, x)
return s
def test(times):
import random
rnd = random.random
tested = {(1001, 1001): (10000, 10, False),}
org = open('text').read()
minfound = 1000
for i in xrange(times):
l,n = 1001,1001
while (l,n) in tested:
# i guess this would be random enough
xr = lambda: random.choice((rnd(), rnd()+rnd(), rnd()-rnd(), rnd()*random.choice((10,100,1000)), -1*rnd()*random.choice((10,100,1000)),))
n = xr()
l = xr()
sm = compress(org, l=[], lenw=l, numw=n)
try:
dc = decompress(sm)
except:
tested[l,n] = (len(sm), len(sm)/float(len(org)), 'err')
continue
tested[l,n] = (len(sm), len(sm)/float(len(org)), dc==org)
if len(sm) < minfound:
minfound = len(sm)
open('min.txt','a').write(repr(tested[l,n])+'\n')
print '~~~~~~~!!!!!!! New Minimum !!!!!!!~~~~'
return tested
if __name__ == '__main__':
import sys
split = False
try:
if sys.argv[2] == 'p':
pretty = True
except:
pretty = False
org = open(sys.argv[1]).read()
try:
l=float(sys.argv[3])
n=float(sys.argv[4])
except:
l,n=0,0
sm = compress(org,lenw=l,numw=n)
print 'COMPRESSED -->'
print sm, len(sm)
#open('new.py','w').write(sm)
print len(sm)/float(len(org))
print 'TRYING TO REVERT -->'
dc = decompress(sm)
#print dc
print dc==org