बैच में गोल्फ के लिए युक्तियाँ


14

विंडोज बैच (CMD) कोड गोल्फिंग के लिए शायद सबसे कम उपयुक्त भाषा है।

न्यूलाइन वर्णों से बचें । यदि आप बाइट्स में सबसे छोटे कोड की तलाश कर रहे हैं, जैसा कि वर्णों के विपरीत है, तो आप सभी अनावश्यक कैरिज रिटर्न (newline characters = 2 बाइट्स) से छुटकारा पाना चाहेंगे। आप ऐसा करने के लिए &ऑपरेशन का उपयोग कर सकते हैं , प्रत्येक कमांड के लिए एक बाइट को ट्रिम कर सकते हैं ।

echo Hello&echo World.

चर सेट करना । स्विच का उपयोग करते हुए चर सेट करते समय, setपार्सर रिक्त स्थान की अनदेखी करेगा।

set /a a+=1
set /p b="User Input: "
:: Will be handled the same as..
set/aa+=1
set/pb="User Input: "

ध्यान दें कि समान कमांडर नियम सभी आदेशों पर लागू नहीं होते हैं - उदाहरण के लिए, लूप के लिए रिक्त स्थान की आवश्यकता होती है। set, string, or command(यानी कोष्ठक के अंदर क्या है) और शब्द को छोड़कर do

for /f %%a in (file.txt)do ...

सरल गणितीय अभिव्यक्ति । इसके अलावा, उस अभिव्यक्ति पर ध्यान दें जो मैंने set /aकमांड में वेतन वृद्धि के लिए उपयोग किया था। सरल गणितीय अभिव्यक्तियों के लिए += -= *= /=इसके बजाय (उदाहरण के लिए) का उपयोग करें set /a a=%a%+1

कमांड आउटपुट प्राप्त करना । कमांड का आउटपुट प्राप्त करने के लिए, कभी-कभी फ़ाइल से आउटपुट करना और पढ़ना उपयोगी हो सकता है, जहाँ आपने आउटपुट को इकट्ठा करने के लिए लूप के लिए उपयोग किया होगा:

for /f %%a in ('echo test') do set a=%%a
:: Can be shortened to
echo test>f&set/pa=<f

echo testf, नामक फ़ाइल में स्टडआउट भेजें >f, एक नई कमांड शुरू करें &और एक चर में फ़ाइल की सामग्री प्राप्त करें set/pa=<f। स्पष्ट रूप से यह हमेशा उपयोगी नहीं होता है। लेकिन यह तब हो सकता है जब आप सभी की जरूरत उत्पादन की एक पंक्ति है।

कमांड आउटपुट । कमांड आउटपुट को दबाते समय, कमांड @से पहले का उपयोग करें , जब तक कि आपको 9 से अधिक कमांड को दबाने की आवश्यकता न हो , उस स्थिति में, @echo offअपनी स्क्रिप्ट की शुरुआत में उपयोग करें। @echo off9 बाइट्स लंबी है, और इसलिए आम तौर पर अधिक बाइट्स को लंबी स्क्रिप्ट के साथ सहेजा जाएगा।

कमांड अक्सर अधिक वही करते हैं जो स्पष्ट है - इस बारे में सोचें कि आपके आदेश क्या कर रहे हैं। उदाहरण के लिए; यदि आपको एक चर सेट करने की आवश्यकता है और इसके बजाय एक अन्य चर को प्रतिध्वनित करें:

set a=OUTPUT
echo %a%
echo test>f
set /p b=<f

आप अपने /pलिए आउटपुट पर स्विच के साथ सेट कमांड का उपयोग कर सकते हैं %a%

set a=OUTPUT
echo test>f
set /p b=%a%<f

पूरी तरह से गोल्फ ...

set a=OUTPUT&echo test>f&set/pb=%a%<f

Expamples के एक जोड़े - गणना सभी अंकों का योग - Goldbach का अनुमान

किसी भी अन्य सुझावों की सराहना की तुलना में अधिक हैं - अगर मैं किसी और चीज के बारे में सोचता हूं तो मैं इसे अपडेट करता रहूंगा।


16
कृपया इस के उत्तर भागों को उत्तर के रूप में पोस्ट करें, प्रश्न के भाग के रूप में नहीं।
नहीं कि चार्ल्स

@Charles मुझे पूरा यकीन है कि मैंने यह कैसे किया है कि यह 'टिप्स प्रश्न' के लिए स्वीकार्य प्रारूप है। अन्य लोग स्वयं की युक्तियों के साथ उत्तर जोड़ सकते हैं।
चाचा

जवाबों:


4

काउंटर

जब भी आपके पास एक चर होगा जो 0आप से शुरू होने वाले काउंटर के रूप में कार्य करेगा जो आप लिखना चाहते हैं

set count=0
set/acount+=1

; हालाँकि, आप पहली पंक्तियों को समाप्त कर सकते हैं क्योंकि जब भी set/aएक अस्थिर चर के साथ प्रयोग किया जाता है तो इसका मान माना जाता है0

set/acounter+=1

कोड ब्लॉक

जब आप कोड के ब्लॉक का उपयोग करना चाहते हैं, तो कुछ तरीके बाइट कर सकते हैं।

जब भी आप एक कोड ब्लॉक खोलते हैं, तो आपको उस ब्लॉक में कोड की पहली पंक्ति से पहले लाइन ब्रेक डालने की आवश्यकता नहीं होती है। समापन कोष्ठक अपनी स्वयं की एक पंक्ति पर होने की आवश्यकता नहीं है।

If %a%==%b% (
     echo true
) else (
    echo false
)

तक पहुंचा जा सकता है

If %a%==%b% (echo true)else (echo false)

नई लाइन के बिना मुद्रण

इसके लिए सामान्य पैटर्न है

echo|set/p=text

लेकिन, आप 2 बाइट्स को बदलने echoसे बचा सकते हैंcd

cd|set/p=text

2
@ akp-morpork अरे, मुझे थोड़ी देर हो गई है। लेकिन मैं आपको सूचित करना चाहता हूं कि ifबयान को और आगे बढ़ाया जा सकता है। सबसे अच्छा एक होना चाहिए:if %a%==%b% (echo true)else echo false
स्टेवफेस्टल

3

ampersands

यद्यपि यह कोड को छोटा लगता है, क्योंकि यह कम लाइनों का उपयोग करता है, यह एक नई पंक्ति के रूप में कई वर्णों का उपयोग करता है। इस का मतलब है कि

echo a&echo b

जब तक है

echo a
echo b

तो आपका कोड पात्रों को बर्बाद किए बिना पठनीय रह सकता है।

कुछ अपवाद हो सकते हैं क्योंकि कुछ टेक्स्ट एडिटर प्रत्येक नई लाइन के लिए लाइन फीड और कार्रिज रिटर्न को मिलाते हैं।


मैंने इसे मूल पोस्ट में शामिल किया क्योंकि मेरे द्वारा उपयोग किए जाने वाले प्रत्येक टेक्स्ट एडिटर में दो बाइट्स के लिए एक नई लाइन मायने रखती है। इस स्पष्टीकरण को जोड़ने के लिए धन्यवाद।
अंकलमेट

2
विंडो का कैरिज रिटर्न लाइनफीड दो अक्षर हैं और कई टेक्स्ट एडिटर इसे दो के रूप में गिनेंगे, लेकिन जब मैंने पहली बार गोल्फ सवालों का जवाब देना शुरू किया तो उनमें से एक टिप्पणी ने कहा कि पीपीसीजी लाइन एंडिंग में हमेशा एक चरित्र के रूप में गिना जाता है।
जेरी यिर्मयाह

2
यूनिक्स स्टाइल लाइनफीड्स सीएमडी लिपियों में ठीक काम करेगा, कम से कम विंडोज के हाल के संस्करणों में।
14:24 पर user2428118

1
वास्तव में, सीएमडी भी पार्स करने से पहले सीआर के पात्रों को हटा देता है: stackoverflow.com/questions/4094699/…
schnaader

3

संख्यात्मक गणना के परिणाम को सीधे प्रिंट करें

यदि चुनौती के लिए आपको एक संख्या को आउटपुट करने की आवश्यकता होती है जिसे गणना करने की आवश्यकता होती है, तो आप cmd/c set/aगणना को सहेजने और फिर इसे प्रतिध्वनित करने के बजाय सीधे गणना के परिणाम का उपयोग कर सकते हैं । उदाहरण:

@set/a a=%1+%2
@echo %a%

हो जाता है

@cmd/cset/a%1+%2

संपादित करें: स्पष्ट रूप से कोई भी स्थान आवश्यक नहीं है, 2 और बाइट्स की बचत।


2

विलंबित विस्तार

लंबा उपयोग करने के बजाय setLocal enableDelayedExpansionआप cmd /v on(या cmd/von) का उपयोग कर सकते हैं जो विलंबित चर विस्तार सक्षम के साथ एक नया दुभाषिया शुरू करेगा।

मुझे अभी तक इसे लागू करना है इसलिए मेरे पास कोई उदाहरण नहीं है, लेकिन आप इसे /cस्विच के साथ संयोजन में उपयोग कर सकते हैं । उदाहरण:

@cmd/von/cset test=test^&echo !test!

एम्परसेंड से पहले कैरेट के उपयोग पर ध्यान दें। यदि आपको कई एम्परसेंड या किसी अन्य विशेष वर्ण का उपयोग करने की आवश्यकता है, तो आप /cउद्धरण चिह्नों में स्विच के बाद सब कुछ संलग्न करना बेहतर हो सकते हैं :

@cmd/von/c"set test=test&set test1=test1&echo !test! !test1!"

इस पद्धति का भी लाभ है कि सभी इनपुट @को मास्क करने के लिए केवल एक वर्ण का उपयोग किया जा सकता है, और इसलिए, (या कई प्रतीकों) के लिए एक छोटे विकल्प के रूप में , बिना उपयोग किया जा सकता है ।/von@echo off@

9 वर्ण: @echo off
6 वर्ण:@cmd/c

अधिक लंबी लिपियों के लिए, जिसे आप एक पंक्ति में नहीं कर सकते, आप कुछ बाइट्स को बचाने के लिए निम्न कार्य कर सकते हैं:

@!! 2>nul||cmd/q/v/c%0&&exit/b

या, अपुष्ट:

@!! 2>nul || cmd /q /v on /c %0 && exit/b

@echo off&setLocal enableDelayedExpansionउपरोक्त के साथ बदलें ।

जब आप पहली बार चलाते हैं तो आपकी स्क्रिप्ट !!का विस्तार नहीं होगा, इसलिए आप एक त्रुटि प्राप्त करते हैं क्योंकि "!!"एक कमांड नहीं है। त्रुटि आउटपुट तब nul ( 2>nul) में पाइप किया जाता है । जब यह पहला 'कमांड' विफल हो जाता है ( ||), तो यह cmd का एक नया उदाहरण कहता है, जो बैच फ़ाइल को स्वयं कॉल करता है ( /v (on)विलंबित विस्तार को सक्षम करने के लिए और /qइको को बंद करने के लिए)। फिर !!कुछ भी नहीं करने के लिए विस्तार किया जाएगा, क्योंकि कोई चर नहीं है <NULL>। आपकी बाकी स्क्रिप्ट तब चलती है। जिसके बाद यह cmd के मूल उदाहरण पर वापस आ जाएगा, और ( &&) /bखिड़की को खुला रखने के लिए शर्त के साथ बाहर निकलें (निकास तो यह है कि यह पहले स्क्रिप्ट के संदर्भ में आपकी स्क्रिप्ट के माध्यम से चलता नहीं है, प्रतिध्वनि के साथ चालू और विलंबित विस्तार)।


इसके लिए, बैच फ़ाइलों को चलाने के लिए cmd /q /v on /c <filename>केवल 2 बाइट्स के रूप में गिना जाना चाहिए क्योंकि वे पर्ल झंडे के समान दो "झंडे" हैं, -pIजो केवल 2 अतिरिक्त बाइट्स के रूप में गिना जाएगा।

1

दोहराए जाने वाले तार

चर में दोहराए जाने वाले कोड ब्लॉक सेट करें, जहां चर को सेट करने के लिए उपयोग किए जाने वाले बाइट की संख्या + चर को आउटपुट करने के लिए बाइट की संख्या सीधे कोड को कॉल करने के लिए बाइट की संख्या से कम होती है।

एक उदाहरण के लिए, देखें: उन संयोजनों को खींचें जो 100 तक जोड़ते हैं

आप सेट कमांड के उपयोग के अनुसार 1 बाइट बचाते हैं, यदि आप एक चर बनाते हैं (एक वर्ण के साथ नाम, जैसे "s") set<space>। यह केवल मान उत्पन्न करता है यदि आप सेट कमांड का उपयोग 12 से अधिक बार करते हैं। (नोट स्ट्रिंग के अंत में एक वर्ण है set s=set)।

set s=set 
%s%a=1
%s%b=2
%s%c=3
%s%d=4
%s%e=5
%s%f=6
%s%g=7
%s%h=8
%s%i=9
%s%j=10
%s%k=11
%s%l=12
%s%m=13

ऊपर 1 बाइट से छोटा है ..

set a=1
set b=2
set c=3
set d=4
set e=5
set f=6
set g=7
set h=8
set i=9
set j=10
set k=11
set l=12
set m=13

यह शायद एक बहुत खराब उदाहरण है - लेकिन यह बिंदु पार हो जाता है।


1

एक स्ट्रिंग की शुरुआत

संकेतन %var:~start,end%चर का एक विकल्प निकालता है var। लेकिन अगर startहै 0तो आप इसे पूरी तरह छोड़ सकते हैं। हम पहले से ही जानते हैं कि ,endयदि आप बाकी स्ट्रिंग चाहते हैं, तो आप इसे छोड़ सकते हैं , जो %var:~%लगभग बेकार का पर्याय बन जाता है %var%, सिवाय इसके कि यह खाली ~होने पर लौटता %var%है। (शायद आप इसे एक परीक्षण में उपयोग कर सकते हैं if %var:~%==~:?)


मुझे आपका अंतिम वाक्य हमें याद दिलाता है कि यह कुछ उद्धरणों को बचाएगा :) इसके लिए +1।
स्टेवफेस्टल

1

संक्षिप्त IF EQUबयान

if %a% equ %b% do_something
if %a%==%b% do_something

3 बाइट्स सहेजने के ==बजाय का उपयोग करना । equ


IFकथनों में लघुकरण

यह एक पारंपरिक तथाकथित "सुरक्षित" ifमजबूरी है।

if "%a%"=="%b%" do_something

इस कथन को छोटा करने के लिए, निम्नलिखित करें जब इनपुट केवल अल्फ़ान्यूमेरिकल / खाली हो सकता है :

if %a%.==%b%. do_something

कुल 2 बाइट्स की बचत ।


चुनौतियां जिनके लिए आउटपुट की आवश्यकता होती है

अगर सवाल कुछ ऐसा कहे:

कम से कम 1 दृश्यमान चरित्र आउटपुट।

तो आप बस ऐसा कर सकते हैं:

cd

cdकरने के लिए वर्तमान निर्देशिका चलता STDOUT


GOTOएक लेबल आईएनजी

यहां gotoएक लेबल की कुछ विधियां हैं, जो बाइट्स के अवरोही क्रम में क्रमबद्ध हैं।

goto :l
goto l
goto:l

उपरोक्त विधि 1 बाइट बचाता है ।


1
वैकल्पिक रूप से आप ऐसा कर सकते हैं goto:lजो समान 1 बाइट बचाता है और आपके बृहदान्त्र को अक्षुण्ण रखने का अतिरिक्त बोनस है
Matheus Avellar

@ मैथ्यू एवलर: मैंने आपकी टिप्पणी के अनुसार सामग्री जोड़ दी है
स्टीववेस्टल

1

स्लैश के साथ कमांड और मापदंडों के बीच की जगह को छोड़ना

गैर-शीर्षक शीर्षक के बारे में क्षमा करें। मैं जो पाने की कोशिश कर रहा हूं, वह यह है कि कुछ (सभी नहीं) विंडोज कमांड के लिए, आप कमांड / प्रोग्राम के नाम और पैरामीटर के बीच की जगह को छोड़ सकते हैं, जब तक कि पैरामीटर स्लैश से शुरू नहीं होता है। उदाहरण के लिए:

for /f %%G in ...

हो जाता है

for/f %%G in ...

-1 बाइट!

ERRORLEVEL का उपयोग करने के बजाय पाइपिंग आउटपुट

यह निर्धारित करने के लिए ERRORLEVEL का उपयोग करना कि क्या सही ढंग से चली गई कमांड कम से कम या सबसे सुरुचिपूर्ण विधि नहीं है। इसके बजाय, आप आउटपुट को पाइप कर सकते हैं। यह निम्नानुसार काम करता है (याद रखें कि &&ऑपरेटर के बाद कोई भी कमांड केवल तभी निष्पादित होता है यदि कमांड &&बिना त्रुटियों के भाग गया हो। ||ऑपरेटर के बाद कोई भी कमांड , दूसरी ओर, केवल तभी चलेगा जब कमांड ठीक से नहीं चला था। मेरा उदाहरण। :

net session>nul
if %errorlevel%==0 (echo 1) else (echo 0)

इसके साथ प्रतिस्थापित किया जा सकता है:

net session>nul&&echo 1||echo 0

-26 बाइट्स, वाह! ध्यान दें कि यह आदेशों के साथ काम नहीं करता है choice, जहां कुछ इनपुट के अनुसार ERRORLEVEL का एक विशेष मूल्य है।

सादर,
गेबे


1

प्रभावी ढंग से कोष्ठक का उपयोग करना

फिर से नमस्कार,

दूसरा उत्तर पोस्ट करने के लिए क्षमा करें, लेकिन मुझे लगा कि यह इसके योग्य है। मैंने देखा है कि लोग C:\Windows\System32>echo fooप्रत्येक कमांड से पहले उस pesky लाइन को प्रदर्शित किए बिना कमांड आउटपुट प्रदर्शित करने के लिए अक्सर निम्न विधियों में से एक का उपयोग करते हैं।
पहली विधि (उपयोग करके echo off):

@echo off
echo foo
echo bar
echo foobar
echo barfoo

दूसरी विधि:

@echo foo
@echo bar
@echo foobar
@echo barfoo

हालाँकि, इनमें से कोई भी तरीका निम्न के रूप में छोटा नहीं है:

@(echo foo
echo bar
echo foobar
echo barfoo)

बहुत आसान है, है ना? एक अन्य नोट पर, इसका उपयोग आउटपुट की कई लाइनों को एक फ़ाइल या डिवाइस में आसानी से पाइप करने के लिए किया जा सकता है। उदाहरण के लिए, यह लंबा कोड:

echo foo>file.txt
echo bar>file.txt
echo foobar>file.txt
echo barfoo>file.txt

काफी छोटा हो जाता है:

(echo foo
echo bar
echo foobar
echo barfoo)>file.txt

इस लंबे जवाब को पढ़ने के लिए धन्यवाद, और मुझे आशा है कि यह आपकी मदद करता है। सादर,
गेबे


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