बीफ़िंग के लिए हल करने की समस्या को हल करने की भावना में , आइए एक और 2 डी भाषा को परिभाषित करें जिसे मोडिलर एसएनआईएसपी कहा जाता है । मॉड्यूलर SNISP में निम्नलिखित छह निर्देश हैं:
\
निर्देश सूचक को निम्नानुसार निर्देशित करता है:- यदि ऊपर से संपर्क किया गया, तो सही जाओ;
- यदि दाईं ओर से संपर्क किया जाए, तो ऊपर जाएं;
- यदि नीचे से संपर्क किया जाए, तो बाएं जाओ;
- यदि बाईं ओर से संपर्क किया जाए, तो नीचे जाएं।
/
निर्देश सूचक को निम्नानुसार निर्देशित करता है:- यदि ऊपर से संपर्क किया जाए, तो बाएं जाएं;
- यदि बाईं ओर से संपर्क किया जाए, तो ऊपर जाएं;
- अगर नीचे से संपर्क किया, सही जाओ;
- यदि दाईं ओर से संपर्क किया जाए, तो नीचे जाएं।
!
अगले निर्देश पर छोड़ देता है।@
कॉल स्टैक पर आईपी स्थान और दिशा धक्का।#
कॉल स्टैक से एक आईपी स्थान और दिशा को पॉप करता है और उन्हें पुनर्स्थापित करता है, फिर अगले निर्देश पर छोड़ देता है। यदि कॉल स्टैक खाली है, तो निष्पादन रुक जाता है।.
कुछ नहीं करता।
निर्देश सूचक ऊपरी बाएं कोने पर शुरू होता है जो दाएं जा रहा है। यदि यह कभी भी खेल का मैदान छोड़ देता है, तो निष्पादन रुक जाता है।
मोडलिअर एसएनआईएसपी पीडीए से अधिक शक्तिशाली नहीं हो सकता है , क्योंकि इसके अनबाउंड स्टोरेज का एकमात्र स्रोत एक परिमित वर्णमाला (सभी आईपी (स्थान, दिशा) जोड़े का सेट) के साथ एक स्टैक (कॉल स्टैक) है। रुकने की समस्या पीडीए के लिए निर्णायक है , इसलिए यह चुनौती हमेशा संभव होनी चाहिए।
चुनौती
आपका लक्ष्य एक ऐसा प्रोग्राम लिखना है जो एक मॉड्यूलर एसएनआईएसपी प्रोग्राम का प्रतिनिधित्व करने वाले पात्रों का एक मैट्रिक्स लेता है और दो अलग-अलग आउटपुटों में से एक को रिटर्न करता है जो इस बात पर निर्भर करता है कि यह रुकता है या नहीं।
यह कोड-गोल्फ है , इसलिए सबसे छोटा वैध कार्यक्रम ( बाइट्स में मापा गया ) जीतता है।
विशेष विवरण
- जिस तरह से आप वर्ण का एक मैट्रिक्स लेते हैं वह लचीला होता है: एक नई लाइन-अलग स्ट्रिंग, स्ट्रिंग की सरणी, वर्णों की सारणी की सरणी, वर्णों की 2d सरणी, पूर्णांक चौड़ाई का प्रतिनिधित्व करने वाले वर्णों के सपाट सरणी, आदि सभी स्वीकार्य हैं। परीक्षण के मामले उन विकल्पों में से पहले के लिए चुनते हैं।
- आप मान सकते हैं कि इनपुट मैट्रिक्स आयताकार होगी (इसलिए आपको छोटी पंक्तियों को पैड करने की ज़रूरत नहीं है) और नॉनज़रो की लंबाई और चौड़ाई की होगी।
- आप किसी भी दो अलग-अलग आउटपुट चुन सकते हैं, न कि केवल सत्य / मिथ्या।
- आप मान सकते हैं कि इनपुट मैट्रिक्स ही मान्य आदेशों से मिलकर बनता है (
\
,/
,!
,@
,#
, और.
)। - जब एक कमांड को "अगले निर्देश को छोड़ें" कहा जाता है, तो आप मान सकते हैं कि छोड़ने के लिए अगला निर्देश होगा। विशेष रूप से, यह उन परिस्थितियों में कभी भी सामना नहीं किया जाएगा जहां (1) यह प्लेफील्ड के किनारे पर स्थित है और (2) आईपी उस किनारे पर लंबवत चल रहा है, जैसे कि "अगला निर्देश" प्लेफील्ड के बाहर झूठ होगा।
परीक्षण के मामलों
निम्नलिखित स्निपेट का उपयोग भाषा में कार्यक्रमों का परीक्षण करने के लिए किया जा सकता है। ध्यान दें कि यह यहां दिए गए वास्तविक विनिर्देश की तुलना में थोड़ा अधिक अनुमेय है (जैसे कि यह पात्रों .
को बिना ऑप्स के अलावा अनुमति देता है )।
function htmlEscape(t){let i=document.createElement("span");return i.innerText=t,i.innerHTML}function tick(){snisp.tick(),snisp.update()}function run(){runButton.style.display="none",stopButton.style.display="",code.style.display="none",executionArea.style.display="",snisp.initialize(),intervalId=setInterval(tick,INTERVAL_MS)}function stop(){runButton.style.display="",stopButton.style.display="none",code.style.display="",executionArea.style.display="none",clearInterval(intervalId)}let TICKS_PER_SECOND=5,INTERVAL_MS=1e3/TICKS_PER_SECOND,runButton=document.getElementById("run-button"),stopButton=document.getElementById("stop-button"),code=document.getElementById("code"),executionArea=document.getElementById("execution-display"),intervalId,snisp={x:null,y:null,direction:null,callStack:null,stopped:null,playfield:null,padRows:function(){let t=Math.max(...this.playfield.map(t=>t.length));for(let i=0;i<this.playfield.length;i++)this.playfield[i]=this.playfield[i].padEnd(t,".")},initialize:function(){this.x=0,this.y=0,this.direction="right",this.callStack=[],this.stopped=!1,this.playfield=code.value.split("\n"),this.padRows(),this.update()},getCurrentChar:function(){let t=this.playfield[this.y];if(void 0!=t)return t[this.x]},backslashMirror:function(){let t={up:"left",right:"down",down:"right",left:"up"};this.direction=t[this.direction]},slashMirror:function(){let t={up:"right",right:"up",down:"left",left:"down"};this.direction=t[this.direction]},forward:function(){switch(this.direction){case"up":this.y-=1;break;case"down":this.y+=1;break;case"left":this.x-=1;break;case"right":this.x+=1;break;default:throw"direction is invalid"}},pushState:function(){this.callStack.push({x:this.x,y:this.y,direction:this.direction})},restoreState:function(){let t=this.callStack.pop();void 0!=t?(this.x=t.x,this.y=t.y,this.direction=t.direction):this.stopped=!0},tick:function(){if(this.stopped)return;let t=this.getCurrentChar();if(void 0!=t){switch(t){case"\\":this.backslashMirror();break;case"/":this.slashMirror();break;case"!":this.forward();break;case"@":this.pushState();break;case"#":this.restoreState(),this.forward()}this.forward()}else this.stopped=!0},generatePlayfieldHTML:function(t,i){let e=[];for(let n=0;n<this.playfield.length;n++){let s=[],l=this.playfield[n];for(let e=0;e<l.length;e++){let a=htmlEscape(l[e]);e==t&&n==i&&(a='<span class="highlight">'+a+"</span>"),s.push(a)}e.push(s.join(""))}return e.join("<br>")},update:function(){let t=[];for(let i=0;i<this.callStack.length;i++){let e=this.callStack[i];t.push(this.generatePlayfieldHTML(e.x,e.y))}t.push(this.generatePlayfieldHTML(this.x,this.y));let i=t.join("<br><br>");executionArea.innerHTML=i}};
#code{font-family:monospace;}#execution-display{font-family:monospace;white-space:pre;}.highlight{background-color:yellow;}
<b>Code:</b><br/><textarea id="code" width="300" height="300"></textarea><br/><button id="run-button" onclick="run()">Run</button><button id="stop-button" onclick="stop()" style="display: none;">Stop</button><br/><div id="execution-display"></div>
यहां बिना ढंके फार्म पाया जा सकता है ।
लंगड़ा
.
सबसे छोटा कार्यक्रम संभव। सही निकलता है।
\\
\/
कार्यक्रम के चारों ओर हवाएँ और शीर्ष बाहर चला जाता है।
.\./.\
.\!/./
एक पाश में चला जाता है। दो अलग-अलग दिशाओं में ट्रैक के हिस्से के माध्यम से हवाएं।
@\!/#
.\@/#
सभी छह आदेशों का उपयोग करता है।
@.@.@.@.@.@.@.@.@.#
इस कार्यक्रम का निष्पादन समय की पुनरावृत्ति की संख्या में घातांक है @.
, लेकिन यह अभी भी रुकता है।
गैर-लंगड़ा
!/\
.\/
मेरा मानना है कि यह सबसे छोटा अनंत लूप है।
@!\\#/@\!\
//@//.#./.
.\#.!\./\.
#.\!@!\@//
/..@.@\/#!
\.@.#.\/@.
यह ट्रैक के चारों ओर हवाओं, कभी-कभी स्टैक फ़्रेमों को फैलाता है, इससे पहले कि अंत में एक चक्र में पकड़े जाने से स्टैक फ्रेम पैदा होते हैं। सभी कमांड वास्तव में उपयोग नहीं किए जाते हैं।
.!/@.@.@.@.@.\
/.@.@.@.@.@.@/
\@.@.@.@.@.@.\
/.@.@.@.@.@.@/
.@\@.@.@.@.@.\
\.@.@.@.@.@.@/
स्टैक फ्रेम बनाते रहते हैं, लेकिन उनमें से कोई भी कभी वापस नहीं आता है।