Perl, 1428 1,099
มีอักขระ 1193 ASCII (รวมถึงเลขฐานสองที่อนุญาต 960) 1193 - 94 = 1,099
$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
การออกแบบครั้งแรกของฉัน
ก่อนที่ฉันจะรับคำแนะนำจากเดนนิสเพื่อเปลี่ยนเป็นไบนารี่โปรแกรมของฉันใช้เลขฐานแปด
การออกแบบครั้งแรกของฉันเข้ารหัสสตริงแต่ละตัวในรูปแบบเลขฐานแปด 160 หลักโดยมี 2 หลักต่อตัวอักษร การเข้ารหัสนี้มี 100 8 = 64 ตัวอักษรที่แตกต่างกัน ระบบฐานแปดมี 8 หลักที่แตกต่างกัน โปรแกรมจะต้องมี 160 สำเนาของแต่ละหลักดังนั้นจึงอนุญาต 8 × 160 = 1280 หลัก
ฉันเก็บ 160 ตัวเลขใน$s
และอื่น ๆ 1,120 $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 =~
มันบังคับให้บริบทรายการกับผู้ประกอบการแข่งขัน ในบริบทสเกลาร์การแข่งขันจะเป็นจริงหรือเท็จและฉันต้องการวงวน$i++ while ($s =~ /$_/g)
เพื่อนับการแข่งขัน ในบริบทรายการ$s =~ /$_/g
คือรายการที่ตรงกัน ฉันใส่รายการนี้ในบริบทสเกลาร์ของการลบดังนั้น Perl นับองค์ประกอบของรายการ
ที่จะทำให้ควินผมใช้แบบฟอร์ม$_=q{print"\$_=q{$_};eval"};eval
จากquines Perl ที่ Rosetta รหัส อันนี้กำหนดสตริงq{...}
ให้$_
แล้วโทรeval
ดังนั้นฉันสามารถมีรหัสของฉันในสตริงและเรียกใช้ โปรแกรมของฉันจะกลายเป็นควินเมื่อฉันห่อที่สามของฉันกับเส้นสุดท้ายใน$_=q{
และ};eval
และการเปลี่ยนแปลงล่าสุดของฉันไปprint
print "\$s = '$s';\n\$t = '$t';\n\$_=q{$_};eval"
ในที่สุดฉันเล่นกอล์ฟโปรแกรมของฉันโดยเปลี่ยนการมอบหมายแรก$t
เป็นความคิดเห็นและโดยการลบอักขระพิเศษ
มีอักขระ ASCII 1522 ตัว (รวมทั้งตัวเลขฐานแปด 1280 หลักที่อนุญาต)
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
สลับเป็นไบนารี
ในความคิดเห็นเดนนิสสังเกตุว่าตัวเลขเลขฐานสองที่เปลี่ยนแปลง 960 ตำแหน่งจะน้อยกว่า 1,280 หลัก ดังนั้นฉันจึงกราฟจำนวนหลักที่อนุญาตสำหรับแต่ละฐานจาก 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)
แม้ว่า base 8 เป็นค่าต่ำสุดในท้องถิ่น แต่เบส 2 และ 3 และ 4 จะเป็นฐานที่ดีที่สุดที่ 960 หลักที่มีการเปลี่ยนแปลง สำหรับ code golf ฐาน 2 นั้นดีที่สุดเพราะ Perl มีการแปลงสำหรับ base 2
แทนที่ 1280 แปดหลักด้วย 960 หลักเลขบันทึก 320 ตัว
การสลับรหัสจากค่าฐานแปดไปเป็นไบนารี 8 ตัวอักษร:
- เปลี่ยน
oct
เป็นoct'0b'.$_
ค่าใช้จ่าย 7
- เปลี่ยน
/../g
เป็น/.{6}/g
ค่าใช้จ่าย 2
- เปลี่ยน
"%02o"
เป็น "% 06b" `ต้นทุน 0
- เปลี่ยน
160
เป็น480
ค่าใช้จ่าย 0
- เปลี่ยน
0..7
เป็น0,1
บันทึก 1
ฉันเรียนรู้เคล็ดลับกอล์ฟเพิร์ล พวกเขาบันทึก 14 ตัวอักษร:
- เปลี่ยน
'A'..'Z','a'..'z','0'..'9'
เป็นA..Z,a..z,0..9
ใช้ barewords และตัวเลขเปลือยบันทึก 12 ตัว
- เปลี่ยน
"\n"
เป็น$/
บันทึก 2 ตัวอักษร
ฉันบันทึกตัวละคร 3 ตัวโดยการย้าย#$t
ความคิดเห็นไปที่ท้ายไฟล์ สิ่งนี้จะลบบรรทัดใหม่ที่สิ้นสุดความคิดเห็นและตัวอักษร\n
ในควิน
การเปลี่ยนแปลงเหล่านี้บันทึกทั้งหมด 329 ตัวอักษรและลดคะแนนของฉันจาก 1428 เป็น 1,099