Пітон 781 731 605 579 символів
Є набагато більше і набагато кращих відповідей, коли я вперше побачив це, але я витрачав багато часу на свій пітон сценарій, тому я збираюся його опублікувати будь-яким способом, було б дивним побачити пропозиції щодо його подальшого скорочення,
Редагувати: завдяки пропозиціям Е. Н 2 рубаються колоди, щоб піти далі, можливо, мені доведеться реструктурувати багато чого тут, що займе певний час
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
Після того, як я вперше створив рядок (дуже нудно), я написав функцію рекурсивно знаходити заміну шаблону, який був найбільш вигідним (на цьому кроці), що дало мені рішення, але виявилося збільшити розмір на 10 символів.
Отже, я зробив свій алгоритм трохи менш жадібним, замість того, щоб робити остаточний рейтинг лише на "зменшених символів", ранжируючи функцію "зменшені символи", "довжина шаблону" та "кількість зразків"
довжина візерунка = кількість довжин = кількість
rank = [(length-1)*count - length - 2] + lengthWeight * length + countWeight * count
Тоді я запитав мій бідний ноутбук бігти нескінченно, призначаючи випадкові значення lengthWeight
і countWeight
та отримати різні кінцеві розміри зберігати та стискати файли для мінімальних розмірів стиснення в файлі
Через півгодини або близько цього з'явилася вищевказана рядок (я намагався далі попрацювати з нею, щоб побачити, чи можу я скоротити код), і вона не піде нижче, я думаю, мені тут щось не вистачає.
ось мій код для нього, також max_pattern
дуже повільний (Примітка: код виплетає рядок, схожий на форму в попередній версії рішення, я вручну працював через нього, щоб отримати поточну форму, вручну я маю на увазі, вручну в оболонці 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