the challenge for round 11 of code guessing is to compress data.
submissions may be written in python, c, rust, javascript or php.
the definition of a "compression algorithm" is pretty lax, so all you have to do is make sure that your algorithm:
the APIs for each language are as follows.
is lossless (p == decompress(compress(p)) for all inputs p)
returns a result that is smaller than the one passed in for at least one case (you don't have to do this for all cases, because that's impossible)
Python: expose a function compress that takes a bytes object and returns a compressed bytes, and a decompress function that mirrors this.
Rust: expose a function pub fn compress(data: &[u8]) -> impl Borrow<[u8]> and a corresponding decompress function.
JavaScript: expose functions compress and decompress that take and return Uint8Arrays.
PHP: why are you writing PHP?
C: expose the following.
NAME
compress, decompress - compress a series of bytes
SYNOPSIS
int compress(const char *data, size_t len, char **result, size_t *outlen)
int decompress(const char *data, size_t len, char **result, size_t *outlen)
DESCRIPTION
The compress() function compresses a string. The decompress() function, given the output of a previous call to compress(), returns the original string that was compressed.
Both functions have the same interface:
The `data` argument points to a series of bytes, the length of which is given by `len`.
The `result` argument may point to NULL or it may point to a pointer to a pre-allocated output buffer. If it does, `outlen` shall point to the length of this buffer. If the function is successful, the values of `*result` and `*outlen` are updated to contain the result.
RETURN VALUE
On success, compress() and decompress() return 0. On failure, they return a negative error code.
usestd::borrow::Borrow;#[cfg(target_os = "windows")]constCOPYRIGHT:u8=1;#[cfg(not(target_os = "windows"))]constCOPYRIGHT:u8=0;pubfncompress(data:&[u8])->implBorrow<[u8]>{letmutcompressed_data=Vec::default();letmutsame_byte=0;letmutsame_length=0;compressed_data.push(COPYRIGHT+2);for(idx,uncompressed_byte)indata.iter().cloned().enumerate(){ifidx%100==0{compressed_data.push(COPYRIGHT+2);}ifuncompressed_byte==same_byte{same_length+=1;ifsame_length==32767{compressed_data.append(&mutvec![255;2]);}}else{ifsame_length>127{compressed_data.push(((same_length>>8)+128)asu8);compressed_data.push((same_lengthasu8));}elseifsame_length>0{compressed_data.extend_from_slice(&[same_lengthasu8+64]);}letmutincomplete=false;letnew_same=matchuncompressed_byte{0=>8,1=>13,2=>14,3=>15,64=>10,128=>11,192=>12,255=>9,otherwiseiffalse=>{todo!()}_=>{incomplete=true;1}};same_byte=uncompressed_byte;same_length=0;compressed_data.push(new_same);ifincomplete{compressed_data.push(uncompressed_byte);}}}ifsame_length>127{compressed_data.push(((same_length>>8)+128)asu8);compressed_data.push((same_lengthasu8));}elseifsame_length>0{compressed_data.extend_from_slice(&[same_lengthasu8+64]);}compressed_data.push(COPYRIGHT+2);compressed_data.push(4);compressed_data}unionData{bulk:(u8,u8),same:u8,delta_bottom5:u8,bigdelta_top4:u8,special_value:u8,return_code:u8,copyright_but:u8,new:(u8,u8),teapot:u8}pubfndecompress(data:&[u8])->implBorrow<[u8]>{letmutdecompressed_bytes=Vec::new();letmutsame_byte=0_u8;letmutnext_is_same=false;letmutnext_is_new=false;letmutcopyright=false;letmutout=0;forcompressed_byteindata.iter().cloned(){ifnext_is_same{decompressed_bytes.extend_from_slice(&vec![same_byte;compressed_byte.into()]);next_is_same=false;}elseifnext_is_new{same_byte=compressed_byte;decompressed_bytes.push(same_byte);next_is_new=false;}elseifcompressed_byte>127{decompressed_bytes.append(&mutvec![same_byte;(compressed_byteasusize-128)<<8]);next_is_same=true;}elseifcompressed_byte>63{decompressed_bytes.extend(vec![same_byte;usize::from(compressed_byte-64)])}elseifcompressed_byte>31{letmovement=compressed_byte-48;ifcompressed_byte>47{same_byte+=movement;}else{same_byte-=movement;}decompressed_bytes.extend([same_byte].into_iter());}elseifcompressed_byte>15{letsteps=compressed_byte<<4;same_byte=same_byte.wrapping_add(steps);decompressed_bytes.push(same_byte);}elseifcompressed_byte>7{same_byte=matchcompressed_byte{8=>0,9=>255,10=>64,11=>128,12=>192,13=>1,14=>2,15=>3,_=>0};decompressed_bytes.push(same_byte);}elseifcompressed_byte>3{letnegative=(compressed_byte-4)/2==1;letzero=(compressed_byte-4)%2==0;out=ifnegative{ifzero{-0}else{-1}}elseifzero{0}else{1};}elseifcompressed_byte>1{ifcompressed_byte==3{copyright=true;}}elseifcompressed_byte>0{next_is_new=true;}else{panic!("I'm a teapot");}}ifcopyright{panic!("Copyrighted material detected");}ifout!=-0{std::process::exit(out);}decompressed_bytes}#[test]fntest(){letinput=b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafgdhjks@@@agfh@ggggfgsjdhhjjjhsdjhjsj";letoutput=b"\x02\x02\x01a_\x01f\x01g\x01d\x01h\x01j\x01k\x01s\nB\x01a\x01g\x01f\x01h\n\x01gC\x01f\x01g\x01s\x01j\x01d\x01hA\x01jB\x01h\x01s\x01d\x01j\x01h\x01j\x01s\x01j\x02\x04";assert_eq!(output,compress(input).borrow());assert_eq!(input,decompress(compress(input).borrow()).borrow());}
# Example of input that becomes smaller: b'aaaaaaaaaaaa'defcompress(data:bytes)->bytes:first,pairs=None,[]forbyteindata:first=byteiffirstisNoneelsepairs.append((first,byte))counts=[(pair,pairs.count(pair))forpairinset(pairs)]counts.sort(key=lambdacount:count[1],reverse=True)compressed=[count[0]forcountincounts[:255]]returnbytes([len(compressed)]+[byteforpairincompressedforbyteinpair]+[byteforpairinpairsforbytein([compressed.index(pair)+1]ifpairincompressedelsetuple([0])+pair)]+([0,first]*(first!=None)))defdecompress(data:bytes)->bytes:first,compressed,literal,out=None,[],0,[]forbyteindata[1:(data[0]*2+1)]:first=byteiffirstisNoneelsecompressed.append((first,byte))forbyteindata[(data[0]*2+1):]:ifliteral:_,literal=out.append(byte),(literal+1)%3elifbyte==0:literal=1else:out+=list(compressed[byte-1])returnbytes(out)
<?php$t1=<<<ENDHARVARDCOLLEGELIBRARYCopyright, 1892,By Elizabeth S. MelvilleMade in U.S.A.Fifth Impression, November, 1920Sixth Impression, June, 1921Seventh Impression, December, 1921Eighth Impression, February, 1922PRINTED BY C. H. SIMONDS COMPANYBOSTON, MASS, U.S.A.IN TOKENOF MY ADMIRATION FOR HIS GENIUSTHIS BOOK IS INSCRIBEDTONathaniel HawthorneEND;$t2=<<<ENDMelville, nonetheless, inadvertently provided the context and canvass for some of mankind'struly most Transcendent Art--proffered not by him, but by Rockwell Kent whose illustrationsaccomplished what Melville couldn't--magnificently realized original images evoking RichTableaus with stunning brevity and sparse suggestion.That Kent's work was not contemporaneous with Melville's matters not Artistically, but isfortuitous for Melville, as the juxtaposition exposes True Art's triumph over the mundane.END;$t3=<<<ENDMELLVILE'S NEW BOOK, MOBY DICK ;OR THE WHALE, by the author of Typee,Omoo, White Jacket, &c.Lossing's Pictorial Field Book of the Revolu-tion, part 18.London Labor and the London Poor, part 15.Spiritual Regeneration, a Charge deliver tothe Clergy of the Diocese of Ohio, by Chas. PettitMcIlvaine, D. D.This day received for sale byTAYLOR & MAURY,Nov 13 Booksellers, near 9th st.HERMAN MELVILLE'S NEW NOVEL -Moby Dick, or the Whale; 1 vol . cloth.Nov 13 FRANCK TAYLOREND;$t4=<<<ENDMOBY-DICK, Or, THE WHALE. By HERMAN MEL-VILLE 12mo.,pp. 635. Harper & Brothers.Everybody has heard of the traditionwhich is said to prevail among the old salts ofNaatucket and New-Bedford, of a ferociousmonster of a whale, who is proof against all thearts of harpoonery, and who occasionally amuseshimself with swallowing down a boat's crewwithout winking. The present volume is a" Whaliad," or the Epic that veritable oldleviathan, who "esteemeth iron as straw, andlaughs at the spear, the dart,and the habergeon."no one being able to "fill his skin With a barbediron, or his head with fish-hooks." Mr.Melvillegives us not only the romance of his history, buta great mass of instruction on the character andhabits of his whole race, with complete detailsof the wily stratagems of their pursuers.The interest of the work pivots on a certainCaptain Ahab, whose enmity to Moby Dick, thename of the whale-demon, has been aggravatedto monomania. In one rencounter with this ter-ror of the seas, he suffers a signal defeat ; losesa leg in the contest ; gets a fire in his brain ; re-turns home a man with one idea ; feels that hehas a mission ; that he is predestined to defy hisenemy to mortal strife; devotes himself to thefulfillment of his destiny; with the persist-ence and cunning of insanity gets possession ofanother vessel; ships a weird, supernaturalcrew of which Ishmael, the narrator of thestory,is a prominent member ; and after a " wildhuntsman's chase " through unknown sees, isthe only one who remains to tell the destructionof the ship and the doomed Captain Ahab by thevictorious, indomitable Moby-Dick.END;$t5=<<<ENDSurvive this journey.Go with the flow.Accept what is.Read page after page after page.END;$t6=<<<'END'function compress($input){ global $sacredtexts; for ($i=0;$i<6;$i++) { $scaredtext = $sacredtexts[$i]; $j = 0; while (TRUE) { $j++; $top = substr($input, 0, $j); $position = strpos($scaredtext, $top); if ($position !== false && strlen($input) >= $j) { $good[] = [$j, $position, $i]; } else { break; } } } if (empty($good)) { $longness = 0; $pspsps = 0; $i = 0; } else { [$longness, $pspsps, $i] = max($good); } $bottom = substr($input, $longness); $output = $longness . "0w0" . $pspsps . "0w0" . $i . "0w0" . $bottom; return $output;}?><?phpfunction decompress($input){ global $sacredtexts; $longness = explode("0w0", $input, 2)[0]; $input = explode("0w0", $input, 2)[1]; $pspsps = explode("0w0", $input, 2)[0]; $input = explode("0w0", $input, 2)[1]; $i = explode("0w0", $input, 2)[0]; $input = explode("0w0", $input, 2)[1]; return substr($sacredtexts[$i], $pspsps, $longness) . $input;}?><?php//spacesavings >99.09% (input depending)END;?><?php$sacredtexts=[$t1,$t2,$t3,$t4,$t5,$t6];eval($t6);?>
#include<stdlib.h>#include<string.h>//Fast lossless image compression and decompression based on QOI//https://qoiformat.org/qoi-specification.pdf//Data should be image data as sequence of RBGA bytes//Probably will fail awefully to compress nonimage data#define CACHESIZE 43#define OP_RGB (char)0xFE#define OP_RGBA (char)0xFF#define OP_INDEX (char)0#define OP_DIFF (char)0x40#define OP_LUMA (char)0x80#define OP_RUN (char)0xC0#define OP_CODE (char)0xC0#define OP_ARGS (char)0x3F#define OP_LUMA_ARG (char)0x3F#define OP_INDEX_ARG (char)0x3F#define HASH(C, H) ((C.red * 3 + C.green * 5 + C.blue * 7 + C.alpha * 11) % H)#define LRS(a, b) ((unsigned)a >> b)#define LOCALHASH(C, H) (H + (LRS(C.red + 8, 3) ^ LRS(C.green + 8, 3) ^ \ LRS(C.blue + 8, 3)) % \ (64 - H))#define TUBITRANGE(a, b) ((char)(a - b) > -3 && (char)(a - b) < 2)#define COLORRANGES(a, b) TUBITRANGE(a.red, b.red) && \ TUBITRANGE(a.green, b.green) && \ TUBITRANGE(a.blue, b.blue)#define EQCOLOR(a, b) (a.red == b.red && a.green == b.green && \ a.blue == b.blue && a.alpha == b.alpha)typedefstructRBGA{unsignedcharred;unsignedchargreen;unsignedcharblue;unsignedcharalpha;}color;intcompress(constchar*data,size_tlen,char**result,size_t*outlen){colorcache[64]={0};colorlast;colorcurrent=(color){.alpha=255};colortemp,temp2;inti;charj,k,l;intrun=0;intct=0;intclen=CACHESIZE;if(len%4){return-1;}if(*result==NULL){*result=(char*)malloc(5*len);}for(i=0;i<len;i+=4){//Cache previous pixelcache[HASH(current,clen)]=current;last=current;//Get next pixelmemcpy(¤t,&data[i],4);//Try to make runif(EQCOLOR(current,last)&&run<62){run++;continue;}if(run){(*result)[ct++]=OP_RUN|(run-1);run=0;if(EQCOLOR(current,last)){run++;continue;}}//Try to make exact diff with previous pixelif(COLORRANGES(current,last)&¤t.alpha==last.alpha){(*result)[ct++]=OP_DIFF|(current.red-last.red+2&3)<<4|(current.green-last.green+2&3)<<2|(current.blue-last.blue+2&3);continue;}//Try to make exact index into cachetemp=cache[HASH(current,clen)];if(EQCOLOR(current,temp)){(*result)[ct++]=OP_INDEX|HASH(current,clen)&OP_INDEX_ARG;continue;}//Try to make luma diff with previous pixelj=current.green-last.green;if(j>-33&&j<32&¤t.alpha==last.alpha){k=current.red-last.red-j;l=current.blue-last.blue-j;if(-9<k&&-9<l&&k<8&&l<8){(*result)[ct++]=OP_LUMA|(j+32&OP_LUMA_ARG);(*result)[ct++]=(k+8&15)<<4|l+8&15;continue;}}if(64-clen){//Try to make diff index into cachej=LOCALHASH(current,clen);temp=cache[j];if(COLORRANGES(current,temp)&¤t.alpha==temp.alpha){smalldiff:(*result)[ct++]=OP_INDEX|j&OP_INDEX_ARG;(*result)[ct++]=OP_DIFF|(current.red-temp.red+2&3)<<4|(current.green-temp.green+2&3)<<2|(current.blue-temp.blue+2&3);continue;}//Next just search the entire cache for the nearest color/*(This section removeable for a slight speed boost and a slight increase in compressed file size. I believe it only makes a difference when encoding very dark pixels nearish the beginning of the file.)*/for(j=clen;j<64;j++){temp2=cache[j];if(COLORRANGES(current,temp2)&¤t.alpha==temp2.alpha){temp=temp2;gotosmalldiff;}k=current.green-temp2.green;if(k>-33&&k<32){k=current.red-temp.red-j;l=current.blue-temp.blue-j;if(-9<k&&-9<l&&k<8&&l<8){temp=temp2;l=j;}}}j=l;//Try to make luma index into cachek=current.green-temp.green;if(k>-33&&k<32&¤t.alpha==temp.alpha){k=current.red-temp.red-j;l=current.blue-temp.blue-j;if(-9<k&&-9<l&&k<8&&l<8){(*result)[ct++]=OP_INDEX|j&OP_INDEX_ARG;(*result)[ct++]=OP_LUMA|((current.green-temp.green)+32&0x3F);(*result)[ct++]=(k+8&15)<<4|l+8&15;continue;}}}//Try to make RGB or RGBA pixelif(current.alpha==last.alpha){(*result)[ct++]=OP_RGB;j=3;}else{(*result)[ct++]=OP_RGBA;j=4;}memcpy(&((*result)[ct]),¤t,j);ct+=j;if(clen-64){cache[LOCALHASH(current,clen)]=current;}}*outlen=(size_t)ct;return0;}intdecompress(constchar*data,size_tlen,char**result,size_t*outlen){colorcache[64]={0};colorcurrent=(color){.alpha=255};inti=0;charj;intbuflen;char*tempbuf;intrun=0;intclen=CACHESIZE;if(*result==NULL){buflen=5*len;*result=(char*)malloc(buflen);}else{buflen=*outlen&-4;}*outlen=0;cache[HASH(current,clen)]=current;for(i=0;i<len;i++){//Expand buffer if it is fullif(*outlen==buflen){buflen*=2;*result=(char*)realloc(*result,buflen);}//Add another pixel for current runif(run){memcpy(&((*result)[*outlen]),¤t,4);*outlen+=4;run--;i--;continue;}//Decode next codewordswitch(data[i]&OP_CODE){caseOP_INDEX:j=data[i]&OP_INDEX_ARG;current=cache[j];if(j<clen)break;i++;caseOP_DIFF:if((data[i]&OP_CODE)==OP_DIFF){current.red+=(LRS(data[i],4)&3)-2;current.green+=(LRS(data[i],2)&3)-2;current.blue+=(data[i]&3)-2;break;}caseOP_LUMA:j=(data[i++]&OP_LUMA_ARG)-32;current.green+=j;current.red+=j+(LRS(data[i],4)&0xF)-8;current.blue+=j+(data[i]&0xF)-8;break;caseOP_RUN:if(data[i]==OP_RGB||data[i]==OP_RGBA){memcpy(¤t,&data[i+1],3);if(data[i]==OP_RGBA){current.alpha=data[i+4];i++;}i+=3;cache[LOCALHASH(current,clen)]=current;}else{run=(data[i]&OP_ARGS)+1;continue;}}memcpy(&((*result)[*outlen]),¤t,4);cache[HASH(current,clen)]=current;*outlen+=4;}return0;}
<?php/* * wHY ARE yoU writinG pHP? * fuck you. * * tested on: * PHP 7.4.3 (cli) (built: Nov 25 2021 23:16:22) ( NTS ) * Copyright (c) The PHP Group * Zend Engine v3.4.0, Copyright (c) Zend Technologies * with Zend OPcache v7.4.3, Copyright (c), by Zend Technologies */error_reporting(0);// remove this for fun warnings (bigger input = more fun!)functioncompress($s){$s=unpack("C*",$s);// why the fuck is this 1 indexed$z=[];foreach($sas$v)$z[]=$v;$dict=array_count_values($s);// PHP FP makes me want to die:// $o = array_map(fn($k,$v) => [$k,$v], array_values($dict),array_keys($dict));$o=[];foreach($dictas$k=>$v)$o[]=[$v,$k];sort($o);while(count($o)>1){$row1=array_shift($o);$row2=array_shift($o);$o[]=array($row1['0']+$row2[0],array($row1,$row2));sort($o);}$d=[];fill($d,$o[0][1][0]?$o[0][1]:$o);$e='';for($i=0;$i<count($z);$i++)$e.=$d[$z[$i]];$x=(8-(strlen($e)%8));$e=str_pad($e,strlen($e)+$x,0,0);$_POST="";foreach($das$k=>$v)$_POST.=$k.p.$v.j;$_GET=[];for($i=0;$i<strlen($e);$i+=8){$_GET[]=bindec(substr($e,$i,8));}returncount($d)+1.j.$x.j.$_POST.pack("C*",...$_GET);}functionfill(&$d,$t,$v=''){if(!$t[0][1][0]){$d[$t[0][1]]=$v.0;}else{fill($d,$t[0][1],$v.0);}if($t[1]){if(!$t[1][1][0]){$d[$t[1][1]]=$v.1;}else{fill($d,$t[1][1],$v.1);}}}functiondecompress($s){[$GLOBALS,$p,$r]=explode(j,$s,3);$h=[];$r=explode(j,$r,$GLOBALS);$s=array_pop($r);foreach($ras$str){[$k,$v]=explode(p,$str);$h[$v]=$k;}$b="";foreach(unpack("C*",$s)as$num){$b.=str_pad(decbin($num),8,0,0);}$b=substr($b,$p);$_ENV="";$f=[];if(!$b)return"";foreach(str_split($b)as$c){$_ENV.=$c;if($h[$_ENV]){$f[]=$h[$_ENV];$_ENV="";}}returnpack("C*",...$f);// why the FUCK does this need a spread}print($a=compress("sadasdasfdsfsdadasfasdfsdfsdhfghsdhfdshgfshadgfhjsdgfjgsdjfgsdfjhagsdfjhgsdfjhghjsdgjfgahjdsghfgsdf"))."\n";print(decompress($a)."\n");?>
#include<stdio.h> /* ~~~~ ~-~-~~-~-~~-~-~~-~-~~-~-~~-~-~~-~-~~-~-~~-~-~~-~-~~-~-~~-~-~~-~-~~-~-~~-~-~~-~-~~-~-~~-~-~~-~-~~-~-~~-~-~~-~-~~-~-~~-~-~ ~~~~ */#include<stdlib.h> /* SINGLE PAGE COMPRESSOR AND DECOMPRESSOR. MADE FOR THE ESOLANGS CODE GUESSING EVENT -- 0cad412cafd2fc03d47c72673061a2c3b873d81d */#include<string.h> /* Contains a suffix array implementation written by Yuta Mori in 2010. Default block size is 65K. Works great on low-entropy data. */typedefvoid*V;typedefintI;typedefunsignedU;typedefunsignedcharQ;typedefunsignedlonglongR;Qtb[256];Q*iq,*oq;Iip,op,im;Ulo,hi,c;unsignedshortt0[256],t1[256][256],t2[2][256][17];Ic1,c2,r;Ibs=1<<16;#define H(a)(cs==sizeof(I)?((I*)T)[a]:((Q*)T)[a])#define DQ(a)unsigned short B0_##a(unsigned short p){return p-(p>>a);}#define DR(a)unsigned short B1_##a(unsigned short p){return p+((p^65535)>>a);}voidgc(VT,I*C,In,Ik,Ics){Ii;for(i=0;i<k;++i)C[i]=0;for(i=0;i<n;++i)++C[H(i)];}DQ(2);DQ(4);DQ(6);DR(2);DR(4);DR(6);voidgb(I*C,I*B,Ik,Ie){Ii,s=0;if(e)for(i=0;i<k;++i)s+=C[i],B[i]=s;elsefor(i=0;i<k;++i)s+=C[i],B[i]=s-C[i];}voidls1(VT,I*SA,I*C,I*B,In,Ik,Ics){I*b,i,j,c0,c1;if(C==B)gc(T,C,n,k,cs);gb(C,B,k,0);j=n-1;b=SA+B[c1=H(j)];--j;*b++=(H(j)<c1)?~j:j;for(i=0;i<n;++i){if(0<(j=SA[i])){if((c0=H(j))!=c1)B[c1]=b-SA,b=SA+B[c1=c0];--j;*b++=(H(j)<c1)?~j:j;SA[i]=0;}elseif(j<0)SA[i]=~j;}if(C==B)gc(T,C,n,k,cs);gb(C,B,k,1);for(i=n-1,b=SA+B[c1=0];0<=i;--i){if(0<(j=SA[i])){if((c0=H(j))!=c1)B[c1]=b-SA,b=SA+B[c1=c0];--j;*--b=(H(j)>c1)?~(j+1):j;SA[i]=0;}}}Ilp1(VT,I*SA,In,Im,Ics){Ii,j,p,q,pl,ql,nm,c0,c1,diff;for(i=0;(p=SA[i])<0;++i)SA[i]=~p;if(i<m){for(j=i,++i;;++i){if((p=SA[i])<0){SA[j++]=~p;SA[i]=0;if(j==m)break;}}}i=n-1;j=n-1;c0=H(n-1);doc1=c0;while(0<=--i&&(c0=H(i))>=c1);while(0<=i){doc1=c0;while(0<=--i&&(c0=H(i))<=c1);if(0<=i){SA[m+((i+1)>>1)]=j-i;j=i+1;doc1=c0;while(0<=--i&&(c0=H(i))>=c1);}}for(i=0,nm=0,q=n,ql=0;i<m;++i){p=SA[i],pl=SA[m+(p>>1)],diff=1;if(pl==ql&&(q+pl)<n){for(j=0;j<pl&&H(p+j)==H(q+j);++j);if(j==pl)diff=0;}if(diff)++nm,q=p,ql=pl;SA[m+(p>>1)]=nm;}returnnm;}voidls2(VT,I*SA,I*C,I*B,I*D,In,Ik,Ics){I*b,i,j,t,d,c0,c1;gb(C,B,k,0);j=n-1;b=SA+B[c1=H(j)];--j;t=(H(j)<c1);j+=n;*b++=t&1?~j:j;for(i=0,d=0;i<n;++i){if(0<(j=SA[i])){if(n<=j)d+=1,j-=n;if((c0=H(j))!=c1)B[c1]=b-SA,b=SA+B[c1=c0];--j;t=c0;t=(t<<1)|(H(j)<c1);if(D[t]!=d)j+=n,D[t]=d;*b++=(t&1)?~j:j;SA[i]=0;}elseif(j<0)SA[i]=~j;}for(i=n-1;0<=i;--i){if(0<SA[i]){if(SA[i]<n){SA[i]+=n;for(j=i-1;SA[j]<n;--j);SA[j]-=n;i=j;}}}gb(C,B,k,1);for(i=n-1,d+=1,b=SA+B[c1=0];0<=i;--i){if(0<(j=SA[i])){if(n<=j)d+=1,j-=n;if((c0=H(j))!=c1)B[c1]=b-SA,b=SA+B[c1=c0];--j;t=c0;t=(t<<1)|(H(j)>c1);if(D[t]!=d)j+=n,D[t]=d;*--b=(t&1)?~(j+1):j;SA[i]=0;}}}Ilp2(I*SA,In,Im){Ii,j,d,nm;for(i=0,nm=0;(j=SA[i])<0;++i){j=~j;if(n<=j)nm++;SA[i]=j;}if(i<m){for(d=i,++i;;++i){if((j=SA[i])<0){j=~j;if(n<=j)nm++;SA[d++]=j;SA[i]=0;if(d==m)break;}}}if(nm<m){for(i=m-1,d=nm+1;0<=i;--i){if(n<=(j=SA[i]))j-=n,--d;SA[m+(j>>1)]=d;}}else{for(i=0;i<m;++i)if(n<=(j=SA[i]))j-=n,SA[i]=j;}returnnm;}voidisa(VT,I*SA,I*C,I*B,In,Ik,Ics){I*b,i,j,c0,c1;if(C==B)gc(T,C,n,k,cs);gb(C,B,k,0);j=n-1;b=SA+B[c1=H(j)];*b++=(0<j&&H(j-1)<c1)?~j:j;for(i=0;i<n;++i){j=SA[i],SA[i]=~j;if(0<j){--j;if((c0=H(j))!=c1)B[c1]=b-SA,b=SA+B[c1=c0];*b++=(0<j&&H(j-1)<c1)?~j:j;}}if(C==B)gc(T,C,n,k,cs);gb(C,B,k,1);for(i=n-1,b=SA+B[c1=0];0<=i;--i){if(0<(j=SA[i])){--j;if((c0=H(j))!=c1)B[c1]=b-SA,b=SA+B[c1=c0];*--b=(!j||H(j-1)>c1)?~j:j;}else{SA[i]=~j;}}}Icb(VT,I*SA,I*C,I*B,In,Ik,Ics){I*b,i,j,pi=-1,c0,c1;if(C==B)gc(T,C,n,k,cs);gb(C,B,k,0);j=n-1;b=SA+B[c1=H(j)];*b++=((0<j)&&(H(j-1)<c1))?~j:j;for(i=0;i<n;++i){if(0<(j=SA[i])){--j;SA[i]=~(I)(c0=H(j));if(c0!=c1){B[c1]=b-SA;b=SA+B[c1=c0];}*b++=(0<j&&H(j-1)<c1)?~j:j;}elseif(j)SA[i]=~j;}if(C==B)gc(T,C,n,k,cs);gb(C,B,k,1);for(i=n-1,b=SA+B[c1=0];0<=i;--i){if(0<(j=SA[i])){--j;SA[i]=(c0=H(j));if(c0!=c1){B[c1]=b-SA;b=SA+B[c1=c0];}*--b=(0<j&&H(j-1)>c1)?~(I)H(j-1):j;}elseif(j)SA[i]=~j;elsepi=i;}returnpi;}Ism(VT,I*SA,Ifs,In,Ik,Ics,Iisbwt){I*C,*B,*D,*RA,*b,i,j,m,p,q,t,nm,pi=0,nf,c0,c1;Ufl;if(k<=256){C=malloc(k*sizeof(I));if(k<=fs){B=SA+(n+fs-k);fl=1;}else{B=malloc(k*sizeof(I));fl=3;}}elseif(k<=fs){C=SA+(n+fs-k);if(k<=(fs-k)){B=C-k;fl=0;}elseif(k<=1024){B=malloc(k*sizeof(I));fl=2;}elseB=C,fl=8;}else{B=C=malloc(k*sizeof(I));fl=12;}if(n<=0x3fffffff&&2<=n/k){if(fl&1)fl|=(k*2<=fs-k)?32:16;elseif(!fl&&k*2<=fs-k*2)fl|=32;}gc(T,C,n,k,cs);gb(C,B,k,1);for(i=0;i<n;++i)SA[i]=0;b=&t;i=n-1;j=n;m=0;c0=H(n-1);doc1=c0;while(0<=--i&&(c0=H(i))>=c1);while(0<=i){do{c1=c0;}while(0<=--i&&(c0=H(i))<=c1);if(0<=i){*b=j;b=SA+--B[c1];j=i;++m;doc1=c0;while(0<=--i&&(c0=H(i))>=c1);}}if(1<m){if(fl&48){if(fl&16){D=malloc(k*2*sizeof(I));}else{D=B-k*2;}++B[H(j+1)];for(i=0,j=0;i<k;++i){j+=C[i];if(B[i]!=j)SA[B[i]]+=n;D[i]=D[i+k]=0;}ls2(T,SA,C,B,D,n,k,cs);nm=lp2(SA,n,m);if(fl&16)free(D);}else{ls1(T,SA,C,B,n,k,cs);nm=lp1(T,SA,n,m,cs);}}elseif(m==1)*b=j+(nm=1);elsenm=0;if(nm<m){if(fl&4)free(C);if(fl&2)free(B);nf=(n+fs)-m*2;if(!(fl&13))if(k+nm<=nf)nf-=k;elsefl|=8;RA=SA+m+nf;for(i=m+(n>>1)-1,j=m-1;m<=i;--i)if(SA[i])RA[j--]=SA[i]-1;sm(RA,SA,nf,m,nm,sizeof(I),0);i=n-1;j=m-1;c0=H(n-1);doc1=c0;while(0<=--i&&(c0=H(i))>=c1);while(0<=i){doc1=c0;while(0<=--i&&((c0=H(i))<=c1));if(0<=i){RA[j--]=i+1;doc1=c0;while(0<=--i&&(c0=H(i))>=c1);}}for(i=0;i<m;++i){SA[i]=RA[SA[i]];}if(fl&4)C=B=malloc(k*sizeof(I));if(fl&2)B=malloc(k*sizeof(I));}if(fl&8)gc(T,C,n,k,cs);if(1<m){gb(C,B,k,1);i=m-1,j=n,p=SA[m-1],c1=H(p);do{q=B[c0=c1];while(q<j)SA[--j]=0;do{SA[--j]=p;if(--i<0)break;p=SA[i];}while((c1=H(p))==c0);}while(0<=i);while(0<j)SA[--j]=0;}if(!isbwt)isa(T,SA,C,B,n,k,cs);elsepi=cb(T,SA,C,B,n,k,cs);if(fl&5)free(C);if(fl&2)free(B);returnpi;}IAE(Q*T,Q*U,In){Ii,pi,*A=malloc(sizeof(I)*n);if(n==1){U[0]=T[0];returnn;}pi=sm(T,A,0,n,256,sizeof(Q),1);if(pi<0)returnpi;U[0]=T[n-1];for(i=0;i<pi;++i){U[i+1]=(Q)A[i];}for(i+=1;i<n;++i){U[i]=(Q)A[i];}free(A);returnpi+1;}Q*AD(Q*T,In,Ipi){IC[256];I*LF=malloc(sizeof(I)*n),i,t;Q*U=malloc(n);for(i=0;i<256;++i)C[i]=0;for(i=0;i<n;++i)LF[i]=C[T[i]]++;for(i=0,t=0;i<256;++i){t+=C[i];C[i]=t-C[i];}for(i=n-1,t=0;0<=i;--i){t=LF[t]+C[U[i]=T[t]];t+=t<pi;}free(LF);returnU;}Imtf(Q*str,Ic){Q*q,*p;Ish=0;p=(Q*)malloc(257);memcpy(p,str,256);q=memchr(p,c,256);sh=q-p;memcpy(str+1,p,sh);str[0]=c;free(p);returnsh;}voiddc(Q*p,Isize,Q*sym){Ii,index,c;for(i=0;i<256;i++)tb[i]=i;for(i=0;i<size;i++){c=tb[p[i]];index=mtf(tb,c);sym[i]=c;}sym[size]=0;}voiden(Q*sym,Isize,Q*p){Ii=0;Qc;for(i=0;i<256;i++)tb[i]=i;for(i=0;i<size;i++){c=sym[i];p[i]=mtf(tb,c);}}Q*pp(Q*s,Il,I*pir){Q*buf=malloc(l),*U=malloc(l);Ipi=AE(s,U,l);en(U,l,buf);free(U);*pir=pi;returnbuf;}Q*dp(Q*s,Il,Ipir){Q*buf=malloc(l),*dec;dc(s,l,buf);dec=AD(buf,l,pir);free(buf);returndec;}voidwo(Qc){oq[op++]=c;}Qri(){if(ip<im)returniq[ip++];elsereturn-1;}voidb0(Up){lo+=(((R)(hi-lo)*p)>>18)+1;while((lo^hi)<(1<<24)){wo(lo>>24);lo<<=8;hi=(hi<<8)+255;}}voidb1(Up){hi=lo+(((R)(hi-lo)*p)>>18);while((lo^hi)<(1<<24)){wo(lo>>24);lo<<=8;hi=(hi<<8)+255;}}voidF(){for(Ii=0;i<4;++i){wo(lo>>24);lo<<=8;}}voidN(){for(Ii=0;i<4;++i)c=(c<<8)+ri();}Idb(Up){Umid=lo+((R)(hi-lo)*p>>18);Ib=(c<=mid);if(b)hi=mid;elselo=mid+1;while((lo^hi)<(1<<24)){lo<<=8;hi=(hi<<8)+255;c=(c<<8)+ri();}returnb;}voidnw(){c1=c2=r=lo=c=0;hi=(U)-1;for(Ii=0;i<256;i++)t0[i]=1<<15;for(Ii=0;i<256;i++)for(Ij=0;j<256;j++)t1[i][j]=1<<15;for(Ii=0;i<2;++i)for(Ij=0;j<256;++j)for(Ik=0;k<17;++k)t2[i][j][k]=(k<<12)-(k==16);}voided(Un){for(Ii=0;i<32;++i){if(n&(1<<31))b1(1<<17);elseb0(1<<17);n+=n;}}Udd(){Un=0;for(Ii=0;i<32;++i){n+=n+db(1<<17);}returnn;}voidef(Ic){if(c1==c2)++r;elser=0;If=(r>2),ctx=1;while(ctx<256){Ip0=t0[ctx],p1=t1[c1][ctx],p2=t1[c2][ctx],p=((p0+p1)*7+p2+p2)>>4,j=p>>12,x1=t2[f][ctx][j],x2=t2[f][ctx][j+1],ssep=x1+(((x2-x1)*(p&4095))>>12),bit=c&128;c+=c;if(bit){b1(ssep*3+p);t0[ctx]=B1_2(t0[ctx]);t1[c1][ctx]=B1_4(t1[c1][ctx]);t2[f][ctx][j]=B1_6(t2[f][ctx][j]);t2[f][ctx][j+1]=B1_6(t2[f][ctx][j+1]);ctx+=ctx+1;}else{b0(ssep*3+p);t0[ctx]=B0_2(t0[ctx]);t1[c1][ctx]=B0_4(t1[c1][ctx]);t2[f][ctx][j]=B0_6(t2[f][ctx][j]);t2[f][ctx][j+1]=B0_6(t2[f][ctx][j+1]);ctx+=ctx;}}c2=c1;c1=ctx&255;}Idf(){if(c1==c2)++r;elser=0;If=(r>2),ctx=1;while(ctx<256){Ip0=t0[ctx],p1=t1[c1][ctx],p2=t1[c2][ctx],p=((p0+p1)*7+p2+p2)>>4,j=p>>12,x1=t2[f][ctx][j],x2=t2[f][ctx][j+1],ssep=x1+(((x2-x1)*(p&4095))>>12),bit=db(ssep*3+p);if(bit){t0[ctx]=B1_2(t0[ctx]);t1[c1][ctx]=B1_4(t1[c1][ctx]);t2[f][ctx][j]=B1_6(t2[f][ctx][j]);t2[f][ctx][j+1]=B1_6(t2[f][ctx][j+1]);ctx+=ctx+1;}else{t0[ctx]=B0_2(t0[ctx]);t1[c1][ctx]=B0_4(t1[c1][ctx]);t2[f][ctx][j]=B0_6(t2[f][ctx][j]);t2[f][ctx][j+1]=B0_6(t2[f][ctx][j+1]);ctx+=ctx;}}c2=c1;returnc1=ctx&255;}Icompress(Q*buf,size_tsize,char**res,size_t*ds){if(!size)return1;nw();oq=malloc(size*2);op=0;Ibsz=bs>size?size:bs,ch=size/bsz,pir,re;ed(size);for(Ii=0;i<ch;i++){Q*p=pp(buf+i*bsz,bsz,&pir);ed(bsz);ed(pir);for(Ij=0;j<bsz;j++)ef(p[j]);free(p);}if(ch*bsz!=size){re=size-ch*bsz;Q*p=pp(buf+(size-re),re,&pir);ed(re);ed(pir);for(Ij=0;j<re;j++)ef(p[j]);free(p);}ed(0);F();*ds=op;*res=oq;return0;}Idecompress(Q*buf,size_tsize,char**res,size_t*ds){iq=buf;im=size;ip=0;nw();N();Ibsz=0,n,ms=dd(),idx;Q*data=NULL;oq=malloc(ms+1);op=0;while((n=dd())>0){if(!bsz){data=malloc(bsz=n);}idx=dd();for(Ii=0;i<n;i++)data[i]=df();Q*buf=dp(data,n,idx);for(Ii=0;i<n;i++)oq[op++]=buf[i];free(buf);}if(data)free(data);*ds=ms;*res=oq;return0;}Imain(Iargc,char*argv[]){if(argc<3){printf("Usage: %s [-c/-d] <input> <output>\n",argv[0]);return1;}FILE*f=fopen(argv[2],"rb");if(!f){printf("Could not open %s\n",argv[1]);return1;}fseek(f,0,SEEK_END);Isize=ftell(f);fseek(f,0,SEEK_SET);Q*data=malloc(size);fread(data,1,size,f);fclose(f);size_tds;Q*dest;if(argv[1][1]=='c')compress(data,size,&dest,&ds);elsedecompress(data,size,&dest,&ds);free(data);f=fopen(argv[3],"wb");if(!f){printf("Could not open %s\n",argv[2]);return1;}fwrite(dest,1,ds,f);fclose(f);free(dest);}
post a comment