पर्ल, 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
मेरा पहला डिजाइन
इससे पहले कि मैं डेनिस से बाइनरी में जाने का सुझाव लेता, मेरे कार्यक्रम ने ऑक्टल अंकों की अनुमति दी।
मेरा पहला डिज़ाइन प्रत्येक स्ट्रिंग को 160 अष्टक अंकों में, 2 अंकों के प्रति वर्ण के साथ एन्कोड करता है। इस एन्कोडिंग में 100 8 = 64 विभिन्न वर्ण हैं। अष्टक प्रणाली के 8 अलग-अलग अंक हैं। कार्यक्रम में प्रत्येक अंक की 160 प्रतियां होनी चाहिए, इसलिए यह 8 × 160 = 1280 अंकों की अनुमति देता है।
मैं १६० अंक $sऔर अन्य ११२० अंक रखता हूं $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 मैचों की एक सूची है। मैंने इस सूची को एक घटाव के स्केलर संदर्भ में रखा है, इसलिए पर्ल सूची तत्वों को गिनता है।
एक क्वीन बनाने के लिए, मैं रोजेटा कोड$_=q{print"\$_=q{$_};eval"};eval में पर्ल क्वाइन से फॉर्म लेता हूं । यह एक स्ट्रिंग q{...}को असाइन करता है $_और फिर कॉल करता है eval, इसलिए मैं अपना कोड एक स्ट्रिंग में रख सकता हूं और इसे चला भी सकता हूं। मेरे कार्यक्रम एक Quine जब मैं में पिछले लाइनों के लिए मेरे तीसरे लपेट हो जाता है $_=q{और };eval, और मेरा आखिरी बदलने printके लिए print "\$s = '$s';\n\$t = '$t';\n\$_=q{$_};eval"।
अंत में, मैंने अपने कार्यक्रम को पहली असाइनमेंट $tको एक टिप्पणी में बदलकर , और अतिरिक्त वर्णों को हटाकर गोल्फ किया ।
इसमें 1522 ASCII वर्ण (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 अनुमत द्विआधारी अंक 1280 से कम अष्टाधारी अंक होंगे। इसलिए मैंने 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 अनुमत अंकों पर। कोड गोल्फ के लिए, बेस 2 सबसे अच्छा है क्योंकि पर्ल में बेस 2 के लिए रूपांतरण है।
960 बाइनरी अंकों के साथ 1280 ऑक्टल अंकों की जगह 320 वर्णों को बचाता है।
ऑक्टल से बाइनरी में स्विचिंग कोड की लागत 8 वर्ण है:
- बदले
octके लिए oct'0b'.$_लागत 7।
- बदले
/../gके लिए /.{6}/gलागत 2।
"%02o""% 06b" `0 में बदलें ।
- बदले
160के लिए 480लागत 0।
- 1
0..7को 0,1बचाने के लिए बदलें ।
मैंने कुछ पर्ल गोल्फ टिप्स सीखे । वे 14 पात्रों को बचाते हैं:
- बदलें
'A'..'Z','a'..'z','0'..'9'करने के लिए A..Z,a..z,0..9, barewords और नंगे नंबर, का उपयोग करते हुए 12 अक्षर बचाता है।
- 2 वर्ण सहेजने के
"\n"लिए परिवर्तित करें $/।
मैं #$tटिप्पणी को फ़ाइल के अंत में ले जाकर 3 अक्षर सहेजता हूं । यह टिप्पणी को समाप्त करने \nवाली न्यूलाइन और क्वीन में शाब्दिक रूप से हटा देता है।
ये परिवर्तन कुल 329 वर्णों को बचाते हैं, और मेरे स्कोर को 1428 से घटाकर 1099 कर देते हैं।