पोस्टस्क्रिप्ट में गोल्फ के लिए युक्तियाँ?


14

कम लोकप्रिय भाषाओं में से एक के रूप में, पोस्टस्क्रिप्ट हैकरी के एवैंट गार्ड पर साहित्य को खोजना मुश्किल है। तो डाकटिकट की अंतर्निहित क्रियाशीलता को दूर करने के लिए स्टैक मॉडल (या अन्य सुविधाओं) का फायदा उठाने के लिए यहां के गोल्फरों ने क्या खोज की है?


कुछ बाहरी पृष्ठ मिले: sites.google.com/site/codegolfingtips/Postscript
luser droog

जवाबों:


3

एंबेडेड डिकोडर

पोस्टस्क्रिप्ट प्रोग्राम में डेटा के रूप में स्वयं के प्रोग्राम टेक्स्ट को पढ़ने की एक अनूठी (?) क्षमता है। यह आमतौर पर imageऑपरेटर द्वारा उपयोग किया जाता है जो इनपुट के रूप में डेटा-अधिग्रहण-प्रक्रिया प्राप्त करता है , और यह प्रक्रिया अक्सर , या , के currentfileबाद उपयोग करता है । लेकिन एक और तरीका देखा, सिर्फ एक और लूपिंग ऑपरेटर है, इसलिए कोई भी लूप पढ़ सकता है-आगे । एक उदाहरण ग्रीन बुक से लाइन-प्रिंटर एमुलेटर है।readlinereadstringreadhexstringimage

tokenऑपरेटर का उपयोग करके एक फ़ाइल या स्ट्रिंग पर स्कैनर को आमंत्रित किया जाता है, एक नंबर या स्थान को खींचकर- (या अन्यथा-: अन्य उत्तर देखें) -delimited नाम।

PS में एक साधारण PS दुभाषिया:

{currentfile token not {exit} if dup type /arraytype ne {exec} if }loop

बाइनरी ऑपरेटर स्ट्रिंग डिकोडर

चूंकि मुझे मेरे लिए काम करने के लिए कच्चा बाइनरी टोकन नहीं मिल रहा है (अन्य उत्तर देखें), मैंने 8-बिट स्ट्रिंग्स में कोड पैक करने के लिए बाइनरी टोकन तंत्र का फायदा उठाने के लिए "एम्बेडेड डिकोडिंग" विचार का उपयोग किया है, और फिर हेरफेर और मक्खी पर स्ट्रिंग से आदेशों को पार्स ।

/.{
    <920>  % two-byte binary-encoded name template with 0x92 prefix
    dup 1 4 3 roll put  % insert number into string
    cvx exec  % and execute it
}def
/${
    //.   %the /. procedure body defined above
    73 .  %"forall" (by code number)
}def

.प्रक्रिया ढेर और एक दो बाइट स्ट्रिंग में दूसरी बाइट के रूप में यह आवेषण से एक नंबर ले जाता है, पहले बाइट एक द्विआधारी टोकन के लिए उपसर्ग-बाइट, एक निष्पादन प्रणाली का नाम निर्दिष्ट किया जा रहा है। हम स्कैनर के एक नियम का उपयोग करके हेक्सस्ट्रिंग में एक बाइट को बचाते हैं कि हेक्सस्ट्रिंग में विषम संख्या में एक अतिरिक्त 0 निबल के साथ गद्देदार होता है, इसलिए 3 हेक्स निबल्स 2-बाइट स्ट्रिंग पैदा करता है। स्ट्रिंग को तब निष्पादन योग्य चिह्नित किया जाता है और उसे बुलाया जाता है execजो स्कैनर को आमंत्रित करता है, वांछित निष्पादन योग्य सिस्टम नाम का उत्पादन करता है, और फिर नाम को लोड करता है और ऑपरेटर को निष्पादित करता है। $स्टैक पर एक स्ट्रिंग के प्रत्येक बाइट पर ऐसा करता है, दो बार. प्रक्रिया का उपयोग करते हुए , एक बार लूप बॉडी के रूप में, और फिर नंबर द्वारा लूपिंग ऑपरेटर को निष्पादित करने के लिए ।forall

अधिक कॉम्पैक्ट रूप से, ये प्रक्रियाएं इस तरह दिखती हैं:

 /.{<920>dup 1 4 3 roll put cvx exec}def/${//. 73 .}def
%123457890123456789012345678901234567890123456789012345
%        1         2         3         4         5

तो, 55 चार्ट बाइनरी टोकन स्ट्रिंग्स खरीदते हैं। या, 6 के लिए (हो सकता है 7, यदि आप इसे एक स्थान के साथ समाप्त करते हैं) वर्ण, आप जी लाइब्रेरी को लोड कर सकते हैं (G)runजिसके साथ परिभाषित किया गया है .और $ऊपर (+ एससी-रीलेबल कोड की सीमा का विस्तार करने के लिए कुछ अन्य)।

इसके अलावा मेरे पहेली पहेली जवाब में सचित्र ।


1
दरअसल, यदि पोस्टस्क्रिप्ट एन्कोडेड रूप में है, तो इसके लिए आपको सामान की तुलना करने में अतिरिक्त सावधानी बरतने की आवश्यकता है। विशेष रूप से, यदि आप ऑपरेटरों को देख रहे हैं, तो आपको इसे टोकन के रूप में पार्स करना चाहिए और फिर टोकन के नाम की तुलना लक्ष्य मूल्य से करनी चाहिए
AJMansfield

2

ग्राफिकल आउटपुट और कंसोल आउटपुट जेनरेट करने से कोई फर्क नहीं पड़ता, =इसके बजाय का उपयोग करें pop


2

ASCII85 के साथ हेक्सस्ट्रिंग्स को बदलें

शायद पुरानी खबर है, लेकिन मैंने इसे सीखा। :)

आप इसे एक कूटबन्धन फ़िल्टर और कट-एंड-पेस्ट के साथ अंतःक्रियात्मक इंटरप्रेटर का उपयोग करके कर सकते हैं। लेकिन मैं यह दिखाने जा रहा हूं dcकि इसे "हाथ से" करने के लिए कैसे उपयोग किया जाए।

तो, यहाँ एक हेक्स स्ट्रिंग है। हमने इसे 4-बाइट विखंडू में विभाजित किया है।

95 20 6e d8   d0 59 49 35   50 74 ba c5   08 2d

डीसी फायरिंग, हम इन्हें 32-बिट (अहस्ताक्षरित) बड़े-एंडियन-बाइट-ऑर्डर संख्याओं के रूप में इनपुट करते हैं। फिर मॉड -ऑफ आधार -85 अंक (जब तक आप 0 तक पहुंचते हैं तब तक 5 होना चाहिए)।

0> डी.सी.
16I
95206ED8
ऐ
D85% N85 /
82
D85% N85 /
83
D85% N85 /
82
D85% N85 /
78
D85% N85 /
47
D85% N85 /
0                    

00 00पैदावार (दशमलव) के साथ अंतिम चंक को पैड करना, उसी संख्या में बाइट्स को छोड़ना जो हमने गद्देदार किया था।

47 78 82 83 82   66 81 72 79 83   25 72 82 25 69  2 53 30 [2 53]

ASCII और पूफ के मुद्रण योग्य रेंज में शिफ्ट होने के लिए 33 जोड़ें! ASCII85।

० १११ ११५ ११६ ११५ ११५ ११५ ११५ ११५ ११५ ५१ १५० १५५ ११५ १०२ ३५ which६ ६३
जो करने के लिए डिकोड करता है: पोस्टस्क्रिप्ट: है: एफ # वी? %%% ऊप्स! कहना चाहिए 'मज़ा'! मैंने कहीं पंगा लिया। :)

इसे लपेटें <~... ~>और स्तर -2 पोस्टस्क्रिप्ट 8-बिट डेटा तक पहुंच सकता है, जो हेक्स से सस्ता है।


2

यहाँ एक क्विक है: [...>>beginकीवर्ड को खत्म करने के लिए कई परिभाषाएँ लपेटें def(nb। [समान है <<)।

 def def
[>>begin

इसलिए याद रखें: से अधिकतीनदो ... एक साथ झुंड ! ;)


क्या नियम "दो से अधिक" नहीं होना चाहिए? तुलना /a 1 def/b 2 def/c 3 defके साथ <</a 1/b 2/c 3>>begin। हमें डिफ के लिए अधिक स्थान चाहिए।
थॉमस डब्ल्यू।

वाह। मैं उस के बावजूद नहीं था। हां, गणना में सुधार की आवश्यकता है।
लूसर ने

वास्तव में, यह होना चाहिए[/a 1/b 2/c 3>>begin
थॉमस डब्ल्यू।

आमने हथेली। । । ।
लूसर

1
यह लागू नहीं हो सकता है यदि आप कुछ ऐसा नामकरण कर रहे हैं जो एक आत्म-परिशोधन टोकन पर समाप्त होता है। में /a{pop 2 mul}defया \b[2 3]def, defकेवल 3 अक्षरों, नहीं 4. लागत
AJMansfield

2

जबकि सबसे उपसंहार ऑपरेटरों वाक्य रचना पहचानकर्ता (और इसलिए अंतरिक्ष (या otherwise- होना चाहिए) सीमांकित), नाम हैं [, ], <<, और >>आत्म परिसीमन कर रहे हैं और स्कैनर अंतरिक्ष हस्तक्षेप के बिना उन्हें पहचान करेगा। उसी कारण से, आप इन नामों को सामान्य /literalवाक्यविन्यास (उदाहरण के /[लिए दो टोकन: एक खाली शाब्दिक नाम ()cvn cvlitऔर उसके [बराबर निष्पादन योग्य नाम ([)cvn cvx exec) के साथ संदर्भित नहीं कर सकते ।

इन नामों को फिर से परिभाषित करने के लिए, जिन्हें नाम से नहीं जाना जा सकता है, हम ऐसे तार का उपयोग कर सकते हैं जो कि शब्दकोष (सुविधाजनक!) में कुंजियों के रूप में उपयोग किए जाने पर नाम में परिवर्तित हो जाते हैं।

यह उदाहरण इन ऑपरेटरों को गालियां देने के लिए गाली देता है।

%!
([)0 def
(])1 def
(<<){add}def
(>>){mul}def
 ]]<<]]]<<<<>> =
%1 1 add 1 1 1 add add mul = %prints 6

इसके अलावा <<और [(और mark) सब एक ही बात मतलब है।


मेरी अपनी पोस्टस्क्रिप्ट दुभाषिया, एक्सपोस्ट , कुछ प्रतिबंधों के साथ सही-कर्ली ब्रेस भी उपलब्ध कराती हैविचार-विमर्श


2
इसके अलावा, /पिछले टोकन को समाप्त करता है ताकि आपको इससे पहले एक स्थान की आवश्यकता न हो।
ज्योफ रेमी

1

फैक्टर-आउट दोहराया ऑपरेटर लंबे नामों का उपयोग करता है

यदि आप पहले से ही एक <<>>beginशब्दकोश का उपयोग कर रहे हैं , तो /?{}प्रति पुनर्वित्त 4 वर्णों का एक निरंतर ओवरहेड है । तो लंबाई n दोहराया N बार के एक ऑपरेटर
(4 + n ) - ( N * ( n - 1)) के चरित्र-गणना परिवर्तन का उत्पादन करेगा ।

इस सूत्र को 0 के बराबर सेट करना ब्रेक-सम पॉइंट का समीकरण देता है । इससे हम प्रत्येक चर को दूसरे के संदर्भ में हल कर सकते हैं,
n = - ( N - 4) / (1 - N ) और
N = (4 + n ) / ( n - 1)।

नहीं, हम इस तरह के सवालों का जवाब नहीं दे सकते हैं, "संक्षिप्त रूप में 'प्रिंट' के कितने उपयोग हैं?" n = 5, इसलिए N = 9/4। छत को लें, क्योंकि आप प्रभावी रूप से प्रिंट 1/4 बार कॉल नहीं कर सकते हैं। तो, 3. 3 का उपयोग करता है। और सचमुच में,

print print print
/P{print}p p p

(यह मानते हुए कि आपने <<>>beginपरिभाषा को सक्रिय करने के लिए पहले ही ओवरहेड का भुगतान कर दिया है )।

बेशक, बाइनरी टोकन इस तरह की लूट बनाता है, आपको सिस्टम नाम तालिका से पहला 255 नाम 2-बाइट्स के रूप में देता है: 0x92, 0x ?? और बाइनरी टोकन भी स्वयं-परिसीमन कर रहे हैं, इससे पहले या बाद में कोई व्हाट्सएप की आवश्यकता नहीं है, क्योंकि पहले बाइट का उच्च-बिट आसिकी सीमा के बाहर है।


1

बाइनरी टोकन

पोस्टस्क्रिप्ट प्रोग्राम के अंतिम ज़िप-अप के लिए जो कि अंतिम सीमा द्विआधारी टोकन है जो आपको लंबे समय तक ऑपरेटर के नामों को पूरी तरह से हटाने की अनुमति देता है, अब एएससीआईआई-स्वच्छ कार्यक्रम नहीं है।

इसलिए पोस्टस्क्रिप्ट कोड के एक संकुचित ब्लॉक के साथ शुरू करना

[/T[70{R 0 rlineto}48{}49{}43{A rotate}45{A neg rotate}91{currentdict
end[/.[currentpoint matrix currentmatrix]cvx>>begin begin}93{. setmatrix
moveto currentdict end end begin}>>/S{dup B eq{T begin exch{load exec}forall
end}{exch{load exch 1 add S}forall}ifelse 1 sub }>>begin moveto 0 S stroke

हम PLRM (परिशिष्ट F, पीपी। 795-797) के पीछे सभी नामों को देखते हैं

appearance
in
vim    dec  meaning

<92>   146  'executable system name' binary token prefix
^A     1    add
^M     13   begin
^^     30   currentdict
'      39   currentmatrix
(      40   currentpoint
2      50   cvx
8      56   dup
9      57   end
=      61   eq  !)
>      62   exch
?      63   exec
I      73   forall
U      85   ifelse
d      100  load
h      104  matrix
k      107  moveto
n      110  neg
<85>   133  rlineto
<88>   136  rotate
§      167 stroke
©      169 sub

और फिर उन्हें 146(दशमलव) बाइट द्वारा उपसर्ग में टाइप करें । मनमाने बाइट्स में प्रवेश के लिए मदद

फिर विम में, संघनित फ़ाइल को सीधे टाइप किया जा सकता है, इसलिए:

[/ टी [70 {R 0 ^V146 ^V133} 48 {} 49 {} 43 {एक ^V146 ^V136} 45 {एक ^V146 ^V110 ^V146 ^V136} 91 { ^V146 ^V30 ^V146 ^V57 [/। [ ^V146 ^V40 ^V146 ^V104 ^V146 ^V39] ^V146 ^V50 >> ^V146 ^V13 ^V146 ^V13} 93 {। ^V146 ^V156 ^V146 ^V107 ^V146 ^V30 ^V146 ^V57 ^V146 ^V57 ^V146 ^V13} >> / एस { ^V146 ^V56 बी ^V146 ^V61 {टी ^V146 ^V13 ^V146 ^V62 { ^V146 ^V100 ^V146 ^V63}^V146 ^V73 ^V146 ^V57} { ^V146 ^V62 { ^V146 ^V100 ^V146 ^V62

... ^V-62 को समाप्त करने और 1 को शुरू करने के लिए आपको यहां एक स्थान दर्ज करना होगा, लेकिन बाद में आप इसे हटा सकते हैं और हटा सकते हैं ...

1 ^V146 ^V1S} ^V146 ^V73} ^V146 ^V85

... ^V-85 को समाप्त करने और 1 को शुरू करने के लिए यहां एक स्थान दर्ज करना होगा, लेकिन आप बाद में इसे हटा सकते हैं और हटा सकते हैं ...

1 ^V146 ^V169} >> ^V146 ^V13 ^V146 ^V107

... 3-अंकीय कोड का तीसरा अंक बाइट-एंट्री को समाप्त करता है, इसलिए 0यहां निम्नलिखित सामान्य है, आसानी से ...

0 एस ^V146 ^V167

जो स्क्रीन पर इस तरह दिखेगा (vim में):

[/T[70{R 0<92><85>}48{}49{}43{A<92><88>}45{A<92>n<92><88>}
91{<92>^^<92>9[/.[<92>(<92>h<92>']<92>2>>
<92>^M<92>^M}93{.<92><9c><92>k<92>^^<92>9<92>9<92>^M}
>>/S{<92>8B<92>={T<92>^M<92>>{<92>d<92>?}<92>I<92>9}{<92>>
{<92>d<92>>1<92>^AS}<92>I}<92>U1<92>©}>><92>^M
<92>k0 S<92>§

यह अक्सर पूरी तरह से छोड़ा जा सकता है अगर उद्देश्य सिर्फ एक तस्वीर दिखाने के लिए है। घोस्टस्क्रिप्ट बिना जरूरत के अधिकांश चीजों को स्क्रीन पर पेंट करता है showpage

¡    161   showpage

[ यह वास्तव में काम नहीं कर रहा है। घोस्टस्क्रिप्ट मुझे undefinedऔर syntaxerrorइन टोकन के लिए दे रहा है । हो सकता है कि मुझे सक्षम करने के लिए कुछ मोड हो]


शायद यह इस कार्यक्रम के बारे में कुछ है । ऑनलाइन कॉम्पैक्टर यह पसंद नहीं करता है, या तो।
लूज़र ने

1

नकारात्मक रोल को सकारात्मक में बदलें

नकारात्मक रोल को हमेशा सकारात्मक रोल में बदला जा सकता है

3 -1 roll
3 2 roll

5 -2 roll
5 3 roll

कौन सा अधिक कुशल है 3 -1 rollया 3 2 roll? मेरे मानसिक मॉडल में, पूर्व को अधिक कुशल होना चाहिए क्योंकि यह सिर्फ एक कदम लेता है। क्या मेरा मानसिक मॉडल सही है?
मेरी बगल चुंबन

ईमानदारी से, मुझे यकीन नहीं है। यहां मेरा कार्यान्वयन है , जहां पहले चरण के रूप में सभी नकारात्मक रोल को सकारात्मक में बदल दिया जाता है। मुझे लगता है कि स्टैक के एक फ्लैट-सरणी कार्यान्वयन के साथ इसे अभी भी कम से कम 2 चालें (3 मान ऊपर ले जाएँ, 3 मान नीचे जाएँ ) की आवश्यकता होगी। लेकिन मेरा स्टैक खंडित है, इसलिए सेगमेंट को प्रबंधित करने के लिए फ़ंक्शन कॉल के माध्यम से पहुंच प्राप्त होती है; इसलिए निश्चित रूप से मेरे द्वारा किए गए कार्यान्वयन के लिए अधिक कुशल तरीके हैं। ... एक बात जो अब मैं देख रहा हूं: मुझे लूप के बाहर स्टैकंडरफ्लो के लिए जांच करनी चाहिए ।
लूजर ने

1
मेरी अंतिम टिप्पणी के बाद से स्रोत फ़ाइल चली गई है। यहाँroll ऑपरेटर का मेरा कार्यान्वयन है ।
लूज़र ने

0

मेरी जी लाइब्रेरी का उपयोग करें

https://github.com/luser-dr00g/G

यह एक पाठ फ़ाइल है। इसे लोड करने के लिए कम से कम सिंटैक्स के लिए कोई एक्सटेंशन नहीं।

यह इस 203-चार Sierpinksi त्रिकोण कार्यक्रम की अनुमति देता है

[48(0-1+0+1-0)49(11)43(+)45(-)/s{dup
0 eq{exch{[48{1 0 rlineto}49 1 index
43{240 rotate}45{120 rotate}>>exch
get exec}forall}{exch{load
exch 1 sub s}forall}ifelse 1 add}>>begin
9 9 moveto(0-1-1)9 s fill

के रूप में 151 बाइट्स में फिर से लिखना है

3(G)run $
{A - B + A + B - A}
{B B}

{A - B - B}7{[ex{du w{(>K?\2u)$}if}fora]}rep
cvx[/A{3 0 rl}/B 1 in/-{120 rot}/+{-120 rot}>>b
100 200(k?B9)$ showp

टिप्पणियों के साथ workfile

संक्षिप्त प्रणाली नाम सुविधा का उपयोग करना, 1(G)runलंबे ऑपरेटर नामों के बोझ को पूरी तरह से हटा देता है। एक ऑपरेटर नाम की आवश्यकता है कि उसे दूसरों से अलग करने के लिए केवल लंबा समय हो।

इसलिए

  • add हो जाता है ad
  • mul हो जाता है mu
  • index हो जाता है i
  • आदि आदि।

ऑपरेटर नामों के मानक तालिका के लिए PLRM परिशिष्ट F का उपयोग करें ।

और ऑपरेटर स्ट्रिंग्स की सुविधा उपलब्ध है भले ही संक्षिप्त नाम का चयन न किया गया हो। नंगे पुस्तकालय में एक "आधार-स्तर" है जिसे केवल (G)runआगे की सजावट के साथ जोड़कर चुना गया है ।

आधार स्तर में एक नया फ़ंक्शन शामिल होता है .जो एक ऑपरेटर के लिए पूर्णांक कोड को स्वीकार करता है (ऊपर उल्लेखित एक ही परिशिष्ट एफ) और इसे निष्पादित करता है।

नया फ़ंक्शन $एक स्ट्रिंग के माध्यम से पुनरावृत्त करता है और .प्रत्येक पर कॉल करता है। तो एससीआई कोड सीधे संचालक का चयन करता है।

एक नया फ़ंक्शन @आपको अंतरिक्ष चरित्र (Ascii 0x20) को 0 के रूप में मानकर परिशिष्ट F में तालिका के नीचे तक पहुंचने देता है।

एक नया फ़ंक्शन #आपको पहले 95 (0x5F) जोड़कर तालिका में आगे तक पहुंचने देता है, इसलिए अंतरिक्ष वर्ण 0x20 को 127 (0x7F) के रूप में माना जाता है, अंतिम प्रिंट करने योग्य एससीआई चरित्र ~126 (0x5E) के बाद अगला कोड ।

दो नए फ़ंक्शन !आपको कई (और ) ऑपरेटरों के थकाऊ अभिव्यक्तियों के बजाय, सूचकांकों / कुंजियों के एक सूचकांक सरणी के साथ सरणियों और / या dicts की एक गहरी नेस्टेड संरचना का उपयोग करने की सुविधा देते हैं ।getput

(G)run 7 वर्ण बेस-स्तर खरीदता है।

1(G)run 8 वर्ण खरीदता है कि और संक्षिप्त रूप सिस्टम नाम।

3(G)run $9 वर्ण तुरंत अगली रिक्त रेखा तक एक अंतर्निहित-प्रक्रिया ब्लॉक स्कैनिंग स्रोत लाइनें शुरू करते हैं , और पहली पंक्ति को एक प्रक्रिया के रूप में परिभाषित करते हैं A, अगली पंक्ति को एक प्रक्रिया के रूप में परिभाषित किया जाता है B, आदि। इसे defपरिभाषित करने के लिए आवश्यक अधिकांश एस को हटा देना चाहिए। बहुत सारे सामान, उन्हें एक शब्दकोश में लपेटने की आवश्यकता के बिना, और न ही उन्हें स्पष्ट रूप से नाम देने के लिए।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.