मॉड्यूलर SNISP के लिए समस्या हल करना


10

बीफ़िंग के लिए हल करने की समस्या को हल करने की भावना में , आइए एक और 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>

यहां बिना ढंके फार्म पाया जा सकता है

लंगड़ा

.

सबसे छोटा कार्यक्रम संभव। सही निकलता है।


\\
\/

कार्यक्रम के चारों ओर हवाएँ और शीर्ष बाहर चला जाता है।


.\./.\
.\!/./

एक पाश में चला जाता है। दो अलग-अलग दिशाओं में ट्रैक के हिस्से के माध्यम से हवाएं।


@\!/#
.\@/#

सभी छह आदेशों का उपयोग करता है।


@.@.@.@.@.@.@.@.@.#

इस कार्यक्रम का निष्पादन समय की पुनरावृत्ति की संख्या में घातांक है @., लेकिन यह अभी भी रुकता है।


गैर-लंगड़ा

!/\
.\/

मेरा मानना ​​है कि यह सबसे छोटा अनंत लूप है।


@!\\#/@\!\
//@//.#./.
.\#.!\./\.
#.\!@!\@//
/..@.@\/#!
\.@.#.\/@.

यह ट्रैक के चारों ओर हवाओं, कभी-कभी स्टैक फ़्रेमों को फैलाता है, इससे पहले कि अंत में एक चक्र में पकड़े जाने से स्टैक फ्रेम पैदा होते हैं। सभी कमांड वास्तव में उपयोग नहीं किए जाते हैं।

.!/@.@.@.@.@.\
/.@.@.@.@.@.@/
\@.@.@.@.@.@.\
/.@.@.@.@.@.@/
.@\@.@.@.@.@.\
\.@.@.@.@.@.@/

स्टैक फ्रेम बनाते रहते हैं, लेकिन उनमें से कोई भी कभी वापस नहीं आता है।


सैंडबॉक्स (अब नष्ट कर दिया गया)
फलों के जूल

भाषा मुझे बहुत सरल विखंडन की याद दिलाती है ।
सूंदर -

1
@sundar यह मॉड्यूलर SNUSP का उपसमूह है , उसी तरह Befinge (प्रकार का) Befunge का सबसेट है।
फल

जवाबों:


4

पायथन 3 , 639 बाइट्स 630 बाइट्स 593 बाइट्स

def e(I):
 m=[(0,-1),(0,1),(1,1),(1,-1)];a=lambda i:(tuple(i[0]),i[1]);b=lambda s,q:s.s==q.s and s.S&q.S==q.S
 class O():i=[[0,0],2];S=[];A={}
 def z():d=m[O.i[1]];O.i[0][d[0]]+=d[1]
 def y():O.i=O.S.pop();z()
 def x():O.i[1]=[3,2,1,0][O.i[1]]
 def w():O.i[1]=[2,3,0,1][O.i[1]]
 def v():O.S+=[[O.i[0][:],O.i[1]]]
 while 1:
  p=O();p.s=a(O.i);p.S={a(i)for i in O.S};l=O.A.setdefault(p.s,[]);c=any((b(p,s)for s in l));l+=[p];e=O.i[0];d=not((0<=e[0]<len(I))and(0<=e[1]<len(I[0])))or((x,w,z,v,lambda:len(O.S)==0 or y(),lambda:0)["\\/!@#.".find(I[e[0]][e[1]])]()==1);z()
  if d!=c:return not c or d

इसे ऑनलाइन आज़माएं!

मुझे ऐसा लगता है कि यह गोल्फ से अधिक छोटा स्रोत है ... मुझे यकीन है कि वहां पहुंचने का एक बेहतर तरीका है।

कार्यक्रम भाषा के लिए पूर्ण दुभाषिया के रूप में काम करता है। यह या तो तब रुक जाता है जब:

  1. हम प्रोग्राम से बाहर निकलते हैं
  2. हम पाते हैं कि हम एक पाश में हैं।

लूप का पता लगाना कुछ अनुभवहीन (और भारी) होता है। प्रत्येक चाल का मूल्यांकन करने से पहले, हम अपनी वर्तमान दिशा, स्थिति और स्टैक को कैश करते हैं। यदि हम देखते हैं कि हम एक ऐसी स्थिति में आ गए हैं, जिससे हम एक ही दिशा में आगे बढ़ रहे हैं, और हमारा वर्तमान स्टैक इस स्थिति + दिशा में पिछले स्टैक का एक सुपर सेट है, तो हम जानते हैं कि हम एक लूप में हैं और स्टैक या तो बढ़ रहा है (या स्थिर रहना)।

संपादित 1 - "पास" काटने के लिए हरमन एल को धन्यवाद । "ट्रू" को भी काटो।

2 संपादित करें - लैम्ब्डा- ified कुछ फ़ंक्शन। रिटर्न की संख्या कम समाप्त करने के लिए "सही" और गैर-समाप्ति के लिए "गलत" लौटाता है। ट्रैकिंग क्लास के रूप में मौजूदा ओ क्लास को लीवरेज किया गया, जिससे एन क्लास की जरूरत खत्म हो गई।


के class N():passसाथ class N():0और def t():passसाथ def t():0काम करने लगता है
हरमन एल

आप को बदल कर एक पूर्ण कार्यक्रम के लिए एक समारोह से बदल सकता है def e(I)के साथ I=input()। यह आपको सभी इंडेंट को हटाने की अनुमति देता है। return xबयान के साथ बदला जा सकता है exit(x)
उभयचर जूल

भी def u():return len(O.S)==0 or y()बन सकता था u=lambda:len(O.S)==0or y()। पुनश्च अच्छा समाधान!
उभयचर जूल

1

जावास्क्रिप्ट (ईएस 6), 258 254 बाइट्स

p=>(d=>{for(x=y=r=k=1,s=[],v={};w=[--x,--y,d],c=1<<"\\!@/#".indexOf(q=(p[y]||0)[x]),q&&r&&(e=v[w]?v[w].some(u=>!s.some(t=>u+0==t+0)):1);x+=d>>2,y+=d&3)v[w]=[...s],k=k?c&9?d=c&1?d/4|4*d&12:(d+5)%10:c&4?s.push(w):c&16?(r=s.pop())&&!([x,y,d]=r):c-2:1})(9)|e

गैर-खाली प्रोग्राम को स्ट्रिंग की एक सरणी के रूप में अपेक्षा करता है, जहां प्रत्येक तत्व मोडिलर एसएनआईएसपी की एक पंक्ति का प्रतिनिधित्व करता है। आउटपुट 1यदि दिए गए प्रोग्राम को रोकता है, और 0अन्यथा।

@ Machina.widmo के उत्तर के समान तर्क । वैकल्पिक तरीकों पर कुछ असफल प्रयासों ने मुझे यह निष्कर्ष निकाला कि वे अब और अधिक कोड का उत्पादन करेंगे!

इसे ऑनलाइन आज़माएं!

व्याख्या

अन्य उत्तर के समान, यह फ़ंक्शन इसके साथ बाहर निकलता है:

  • 1 यदि प्रोग्राम रुकता है (जैसे आईपी ग्रिड से दूर जाता है या खाली स्टैक पॉप होता है)
  • 0यदि आईपी उस स्थिति में पहुंच जाता है जो पहले ही दौरा कर चुका होता है, उसी दिशा में आगे बढ़ रहा है , और पिछली यात्रा में मौजूद स्टैक का एक सुपरसेट के साथ ।

वही दिशा क्यों?

 1
!\/

उपरोक्त कार्यक्रम रुकता है, लेकिन एक समान स्टैक के साथ एक ही स्थिति (चरित्र 1) को हिट करता है, लेकिन एक अलग दिशा से।

क्यों एक सुपरसेट और न केवल स्टैक आकार?

  ab4
!/@@.\
.\..#/

यह भी रुक जाता है, और IP चार वर्णों को एक सुसंगत दिशा से चार बार हिट करता है, निम्नलिखित स्टैक अवस्थाओं के साथ (स्टैक *के शीर्ष को इंगित करता है):

  • आकार = 2 [ए, बी] *
  • आकार = 1 [a] *
  • आकार = 1 [बी] *
  • आकार = 0 [] *

दुभाषिया कैसे काम करता है

निर्देश ( q) बाइनरी में अनुवादित हैं ( c) निम्नानुसार (अन्य सभी वर्णों के साथ, .या अन्यथा, नोड्स के रूप में सेवारत हैं):

1 2 4 8 16
\ ! @ / #

दिशा ( d) को एक छोटे क्षेत्र के रूप में दर्शाया गया है:

9 -> right : 1001
1 -> left  : 0001
6 -> down  : 0110
4 -> up    : 0100

दर्पण ( \/) दिशा बदल रहा है:

\: 6-> 9 9-> 6 4-> 1 1-> 4

d/4 | 4*d&12

/: 1-> 6 6-> 1 4-> 9 9-> 4

(d+5) % 10

नई दिशाएं स्थिति को बदल देती हैं:

x += d>>2 - 1

y += d&3 - 1

अन्य वैश्विक चर

  • x, y: आईपी स्थिति
  • r: स्टैक से पॉप अप किया गया मान रखता है
  • k: मिथ्या यदि अगला निर्देश लंघन (जैसे !#)
  • s: ढेर
  • v: कैश ने पदों, दिशा, स्टैक के स्नैपशॉट का दौरा किया
  • w: [x, y, d], स्टैक पर संग्रहीत मूल्य और के लिए मुख्य मूल्य के रूप में उपयोग किया जाता हैv
  • e: अगर कैची मैच के कारण प्रोग्राम रुकता नहीं है तो गलत है

Ungolfed

p => (d => {                                                  // set initial direction and avoid a verbose `return` statement
    for (
        x = y = r = k = 1,
        s = [],
        v = {};
        w = [--x, --y, d],                                    // decrement positions early so that x,y 
                                                              // do not require a separate assignment to 0
        c = 1 << "\\!@/#".indexOf(q = (p[y]||0)[x]),          // taking an index of undefined produces an error; using 0 does not
        q && r && (
            e = v[w]
                ? v[w].some(u => !s.some(t => u+0 == t+0))    // in order to compare two arrays, must coerce to strings
                : 1
        );
        x += d>>2,
        y += d&3
    )
        v[w] = [...s],                         // clone stack
        k = k
            ?
                c&9                            // if \ or /
                    ? d = c&1
                        ? d/4 | 4*d&12
                        : (d+5) % 10
                : c&4                          // if @
                    ? s.push(w)
                : c&16                         // if #
                    ? (r = s.pop())
                        && !([x, y, d] = r)    // destructure value in stack if any exists
                : c-2                          // 0 if !
            : 1
})(9) | e
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.