펄, 438 291 자
Jeff Burdges의 DEFLATE compression 사용 , Ventero의 압축 Ruby 코드 및 JB의 Lingua :: EN :: Numbers 사용에서 영감을 얻어 압축 해제 코드를 포함하여 291 자 (웰, 바이트)로 항목을 압축 할 수있었습니다. 프로그램에 인쇄 할 수없는 문자가 포함되어 있으므로 MIME Base64 형식으로 제공했습니다 .
dXNlIENvbXByZXNzOjpabGliO2V2YWwgdW5jb21wcmVzcyAneNolkMFqAkEMhu8+RVgELdaIXmXB
S2/FFyhF4k7cHTqTsclMZd++M3pJvo+QH5JiDJ9exkKrj/PqXOKV1bod77qj9b2UeGBZ7w/bpd9s
3rCDruf3uWtwS3qS/vfROy0xsho+oWbB3d+b19YsJHWGhIHp5eQ8GzqSoWkk/xxHH36a24OkuT38
K21kNm77ND81BceCWtlgoBAq4NWrM7gpyzDhxGKQi+bA6NIfG5K4/mg0d0kgTwwdvi67JHVeKKyX
l3acoxnSDYZJveVIBnGGrIUh1BQYqZacIDKc5Gvpt1vEk3wT3EmzejcyeIGqTApZmRftR7BH3B8W
/5Aze7In
프로그램의 인코딩을 해제하려면 다음 도우미 Perl 스크립트를 사용할 수 있습니다.
use MIME::Base64;
print decode_base64 $_ while <>;
이름이 지정된 파일에 출력을 저장 12days.pl하고로 실행하십시오 perl -M5.01 12days.pl. 언급 한대로 코드가 작동 하려면 Lingua :: EN :: Numbers 모듈이 설치되어 있어야합니다.
궁금한 점이 있다면 코드에서 읽을 수있는 부분은 다음과 같습니다.
use Compress::Zlib;eval uncompress '...'
여기서 ...254 바이트의 RFC 1950 압축 Perl 코드를 나타냅니다. 압축되지 않은 코드의 길이는 361 자이며 다음과 같습니다.
use Lingua'EN'Numbers"/e/";s==num2en(12-$i++)." "=e,y"." "for@n=qw=drummers.drumming pipers.piping lords.a.leaping ladies.dancing maids.a.milking swans.a.swimming geese.a.laying golden.rings calling.birds french.hens turtle.doves.and=;say"on the ".num2en_ordinal($_)." day of christmas my true love gave to me @n[$i--..@n]a partridge in a pear tree
"for 1..12
이 코드를 작성하는 것은 이상한 종류의 골프 연습이었습니다. 그것은 반복을 최대화하고 사용 된 고유 문자 수를 최소화하는 것이 관련 메트릭이 압축 후 크기 일 때 원시 문자 수를 최소화하는 것보다 훨씬 중요하다는 것을 알 수 있습니다.
마지막 몇 문자를 짜기 위해이 코드의 작은 변형을 시도하여 가장 압축되는 코드를 찾는 간단한 프로그램을 작성했습니다. 압축을 위해 Ken Silverman의 KZIP 유틸리티를 사용했는데, 이는 최대 압축 설정에서도 표준 Zlib보다 더 나은 압축 비율 (속도 비용)을 산출합니다. 물론 KZIP는 ZIP 아카이브 만 생성하므로 아카이브에서 원시 DEFLATE 스트림을 추출하여 RFC 1950 헤더 및 체크섬으로 래핑해야했습니다. 내가 사용한 코드는 다음과 같습니다.
use Compress::Zlib;
use 5.010;
@c = qw(e i n s);
@q = qw( " );
@p = qw( = @ ; , );
@n = ('\n',"\n");
$best = 999;
for$A(qw(e n .)){ for$B(@q){ for$C(@q,@p){ for$D(@p){ for$E(@q,@p){ for$F(qw(- _ . N E)){ for$G("-","-"eq$F?():$F){ for$H(@c){ for$I(@c,@p){ for$N(@n){ for$X(11,"\@$I"){ for$Y('$"','" "',$F=~/\w/?$F:()){ for$Z('".num2en_ordinal($_)."'){
$M="Lingua'EN'Numbers";
$code = q!use MB/A/B;sDDnum2en(12-$H++).YDe,yCFC Cfor@I=qwEdrummersFdrumming pipersFpiping lordsGaGleaping ladiesFdancing maidsGaGmilking swansGaGswimming geeseGaGlaying goldenFrings callingFbirds frenchFhens turtleFdovesFandE;say"on the Z day of christmas my true love gave to me @I[$H--..X]a partridge in a pear treeN"for 1..12!.$/;
$code =~ s/[A-Z]/${$&}/g;
open PL, ">12days.pl" and print PL $code and close PL or die $!;
$output = `kzipmix-20091108-linux/kzip -b0 -y 12days.pl.zip 12days.pl`;
($len) = ($output =~ /KSflating\s+(\d\d\d)/) or die $output;
open ZIP, "<12days.pl.zip" and $zip = join("", <ZIP>) and close ZIP or die $!;
($dfl) = ($zip =~ /12days\.pl(.{$len})/s) or die "Z $len: $code";
$dfl = "x\xDA$dfl" . pack N, adler32($code);
$dfl =~ s/\\(?=[\\'])|'/\\$&/g;
next if $best <= length $dfl;
$best = length $dfl;
$bestcode = $code;
warn "$A$B$C$D$E$F$G$H$I $X $Y $best: $bestcode\n";
open PL, ">12days_best.pl" and print PL "use Compress::Zlib;eval uncompress '$dfl'" and close PL or die $!;
}}}}}}
print STDERR "$A$B$C$D$E$F\r";
}}}}}}}
이것이 끔찍한 kluge처럼 보인다면, 그것이 바로 그것이 기 때문입니다.
역사적 관심을 끌기 위해 줄 바꿈과 문장 부호를 포함하여 더 나은 출력을 생성하는 원래의 438 문자 솔루션이 있습니다.
y/_/ /,s/G/ing/for@l=qw(twelve_drummers_drummG eleven_pipers_pipG ten_lords-a-leapG nine_ladies_dancG eight_maids-a-milkG seven_swans-a-swimmG six_geese-a-layG five_golden_rGs four_callG_birds three_french_hens two_turtle_doves);s/e?t? .*/th/,s/vt/ft/for@n=@l;@n[9..11]=qw(third second first);say map("\u$_,\n","\nOn the $n[11-$_] day of Christmas,\nMy true love gave to me",@l[-$_..-1]),$_?"And a":A," partridge in a pear tree."for 0..11
이 버전의 주요 특징은 정규 표현식 쌍 s/e?t? .*/th/,s/vt/ft/으로, 선물 행의 시작 부분에서 추기경에서 4-12의 서수를 구성합니다.
물론이 코드는 위에서 설명한 Zlib 트릭을 사용하여 압축 할 수도 있지만 단순히 출력을 압축하는 것이 더 효율적이며 다음 338 바이트 프로그램 (Base64 형식)이 생성됩니다.
dXNlIENvbXByZXNzOjpabGliO3NheSB1bmNvbXByZXNzICd42uWTwU7DMAyG730KP8DGOyA0bsCB
vYBp3MYicSo7W9e3xx3ijCIQDHZIUjn683+/k3ZPAjUSDKxWIeACZYC7qGw1o226hwWqHghSORKM
6FMtkGnT3cKEWpXDSMACCBOhQlWim+7jUKO+SGg5dT8XqAetiSD4nrmPBMDPvXywtllF18OgJH2E
SGJfcR+Ky2KL/b0roMeUWEZ4cXb7biQeGol4LZQUSECdyn4A0vjUBvnMXCcYiYy2uE24ONcvgdOR
pBF9lYDNKObwNnPOTnc5kYjH2JZotyogI4c1Ueb06myXH1S48eYeWbyKgclcJr2D/dnwtfXZ7km8
qOeUiXBysP/VEUrt//LurIGJXCdSWxeHu4JW1ZnS0Ph8XOKloIecSe39w/murYdvbRU+Qyc=
또한 동일한 DEFLATE 스트림으로 구성된 가사의 312 바이트 gzip 아카이브가 있습니다. "zcat 스크립트"라고 부를 수 있다고 생각합니다. :)