펄, 1428 1099
여기에는 1193 개의 ASCII 문자 (960 개의 순열 이진수 포함)가 있습니다. 1193-94 = 1099
$s='010011100001100010101100111111101001101011101000100000101011011010100110111111011111101011101000100110111111011100101000011101011110100000101000100101011111111110101100101101011010011100100100011110110001011100100001011010100111100000011110111110011100101000100110111111101001011110101011100110101110101101011110101100111111100010101101101100011110100101011111111111101101101000111111011110100111011100101000011101011110111111011010111111101100101101101011100010100111100000111110';$_=q{$i=join'',A..Z,a..z,0..9,'. ';print map({substr$i,oct'0b'.$_,1}$s=~/.{6}/g),$/;chop($s=<>);$s=join'',map{sprintf"%06b",index$i,$_}$s=~/./g;$t=join'',map{$_ x(480-(()=$s=~/$_/g))}0,1;print"\$s='$s';\$_=q{$_};eval#$t"};eval#000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
내 첫 디자인
Dennis에서 바이너리로 전환하라는 제안을 받기 전에 내 프로그램은 8 진수를 순열했습니다.
첫 번째 디자인은 각 문자열을 문자 당 2 자리로 160 개의 8 진수로 인코딩합니다. 이 인코딩에는 100 8 = 64 개의 다른 문자가 있습니다. 8 진법은 8 개의 다른 숫자를 가지고 있습니다. 프로그램에는 각 자릿수마다 160 개의 사본이 있어야하므로 8 × 160 = 1280 자리를 바꿉니다.
160 자리 숫자를 유지 $s
하고 다른 1120 자리 숫자를에 유지 $t
합니다. 나는 quine 아닌 프로그램을 시작하지만에만 할당을 인쇄 $s
하고 $t
다음 실행을 위해. 이거 야:
$s = '2341425477515350405332467737535046773450353640504537765455323444366134413247403676345046775136534656553654774255543645377755507736473450353677327754555342474076';
$t = '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222223333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333334444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666667777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777';
# $i = character map of 64 characters, such that:
# substr($i, $_, 1) is the character at index $_
# index($i, $_) is the index of character $_
$i = join '', 'A'..'Z', 'a'..'z', '0'..'9', '. ';
# Decode $s from octal, print.
# 1. ($s =~ /../g) splits $s into a list of pairs of octal digits.
# 2. map() takes each $_ from this list.
# 3. oct() converts $_ from an octal string to a number.
# 4. substr() on $i converts number to character.
# 5. print() outputs the characters from map() and a final "\n".
print map({ substr $i, oct, 1 } $s =~ /../g), "\n";
# Read new $s, encode to octal.
# 1. ($s = <>) reads a line.
# 2. chop($s) removes the last character of $s, the "\n".
# 3. ($s =~ /./g) splits $s into characters.
# 4. map() encodes each character $_ as a pair of octal digits.
# 5. join() concatenates the pairs from map().
chop($s = <>);
$s = join '', map { sprintf "%02o", index $i, $_ } $s =~ /./g;
# Make new $t.
# 1. map() takes each $_ from 0 to 7.
# 2. $_ x (160 - (() = $s =~ /$_/g)) makes a string where $_ repeats
# 160 times, minus the number of times that $_ appears in $s.
# 3. join() concatentates the strings from map().
$t = join '', map { $_ x (160 - (() = $s =~ /$_/g)) } 0..7;
# Print the new assignments for $s and $t. This is not yet a quine,
# because it does not print the rest of the program.
print "\$s = '$s';\n\$t = '$t';\n";
(() = $s =~ /$_/g))
빈 변수 목록에 대한 할당입니다. PerlMonks 의 컨텍스트 자습서 에서이 트릭을 가져 옵니다 . 일치 연산자에 컨텍스트를 강제로 나열합니다 =~
. 스칼라 컨텍스트에서 일치는 true 또는 false이며 $i++ while ($s =~ /$_/g)
일치를 계산 하는 루프가 필요합니다 . 목록 컨텍스트에서 $s =~ /$_/g
일치하는 목록입니다. 이 목록을 빼기의 스칼라 컨텍스트에 넣으므로 Perl은 목록 요소를 계산합니다.
quine 을 만들기 위해 Rosetta Code$_=q{print"\$_=q{$_};eval"};eval
의 Perl quines에서 양식 을 가져옵니다 . 이것은 문자열 q{...}
을 할당 한 $_
다음을 호출 eval
하므로 문자열에 코드를 넣고 실행할 수도 있습니다. 내 프로그램은 내가 지난 라인에 세 번째 랩 quine하게 $_=q{
하고 };eval
, 내 마지막 변경 print
에 print "\$s = '$s';\n\$t = '$t';\n\$_=q{$_};eval"
.
마지막으로 첫 번째 과제를 $t
주석 으로 변경하고 추가 문자를 제거 하여 프로그램을 골프화 합니다.
여기에는 1522 개의 ASCII 문자 (1280 개의 순열 된 8 진수 포함)가 있습니다.
1522-94 = 1428
$s='2341425477515350405332467737535046773450353640504537765455323444366134413247403676345046775136534656553654774255543645377755507736473450353677327754555342474076';#0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222223333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333334444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666667777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777
$_=q{$i=join'','A'..'Z','a'..'z','0'..'9','. ';print map({substr$i,oct,1}$s=~/../g),"\n";chop($s=<>);$s=join'',map{sprintf"%02o",index$i,$_}$s=~/./g;$t=join'',map{$_ x(160-(()=$s=~/$_/g))}0..7;print"\$s='$s';#$t\n\$_=q{$_};eval"};eval
이진으로 전환
이 의견에서 Dennis는 960 개의 순열 된 이진수가 1280 개의 8 진수보다 적다는 것을 알았습니다. 그래서 저는 각 밑변에 대한 순열 자리수를 2에서 16까지 그래프로 표시했습니다.
Maxima 5.29.1 http://maxima.sourceforge.net
using Lisp ECL 13.5.1
...
(%i36) n : floor(x);
(%o36) floor(x)
...
(%i41) plot2d(n * ceiling(log(64) / log(n)) * 80, [x, 2, 16],
[xlabel, "base"], [ylabel, "number of permuted digits"]);
(%o41)
기수 8은 로컬 최소값이지만 기수 2와 3과 4는 960 개의 순열 자리에서 최상의 기수를 위해 묶습니다. 코드 골프의 경우 Perl은 기본 2에 대한 변환이 있으므로 기본 2가 가장 좋습니다.
1280 개의 8 진수를 960 개의 이진수로 바꾸면 320자가 절약됩니다.
8 진수에서 2 진수로 코드를 전환하려면 8자가 필요합니다
- 변경
oct
에 oct'0b'.$_
비용 7.
- 변경
/../g
에 /.{6}/g
비용이.
"%02o"
"% 06b"로 변경 하면 비용이 0입니다.
- 변경
160
에 480
비용이 0.
- 변경
0..7
하려면 0,1
1을 절약 할 수 있습니다.
나는 Perl 골프 팁을 배웠다 . 14자를 저장합니다.
- 변경
'A'..'Z','a'..'z','0'..'9'
에 A..Z,a..z,0..9
사용 barewords 및 노출 수는 12 개 문자를 저장합니다.
- 변경
"\n"
하려면 $/
2 개 문자를 저장합니다.
#$t
주석을 파일 끝 으로 이동하여 3자를 저장 합니다. 주석을 끝내는 줄 바꿈과 \n
quine 의 리터럴 을 제거합니다 .
이 변경 사항은 총 329자를 저장하고 점수를 1428에서 1099로 줄입니다.