মডিলার এসএনআইএসপি-র জন্য থামানো সমস্যা সমাধান করুন


10

আত্মা Befinge জন্য স্থগিত সমস্যা সমাধানের , এর অন্য 2D ভাষা বলা সংজ্ঞায়িত করি Modilar SNISP । মডিলার এসএনআইএসপির নিম্নলিখিত ছয়টি নির্দেশনা রয়েছে:

  • \ নির্দেশিকা নির্দেশককে নিম্নলিখিতভাবে নির্দেশ দেয়:
    • যদি উপরে থেকে যোগাযোগ করা হয় তবে ডানদিকে যান;
    • যদি ডান দিক থেকে কাছে পৌঁছে যায় তবে উপরে যান;
    • নীচ থেকে যদি যোগাযোগ করা হয় তবে বাম দিকে যান;
    • যদি বাম দিক থেকে যোগাযোগ করা হয় তবে নীচে যান।
  • / নির্দেশিকা নির্দেশককে নিম্নলিখিতভাবে নির্দেশ দেয়:
    • যদি উপরে থেকে যোগাযোগ করা হয় তবে বাম দিকে যান;
    • যদি বাম দিক থেকে কাছে যায় তবে উপরে যান;
    • নীচ থেকে যদি যোগাযোগ করা হয়, ডানদিকে যান;
    • যদি ডান দিক থেকে যোগাযোগ করা হয় তবে নীচে যান।
  • ! পরবর্তী নির্দেশাবলী এড়িয়ে যান।
  • @ আইপি অবস্থান এবং দিকটি কল স্ট্যাকের দিকে ঠেলে দেয়।
  • #কল স্ট্যাক থেকে একটি আইপি অবস্থান এবং দিক পপ করে এবং সেগুলি পুনরুদ্ধার করে, তারপরে পরবর্তী নির্দেশাবলী এড়িয়ে যায়। যদি কল স্ট্যাকটি খালি থাকে, কার্যকর করা বন্ধ হয়ে যায়।
  • . কিছুই করে না

উপরের বাম কোণে ডানদিকে যাবার নির্দেশ নির্দেশকটি শুরু হয়। যদি এটি কখনও প্লেফিল্ড ছেড়ে যায়, কার্যকর করা বন্ধ হয়ে যায়।

মডিলার এসএনআইএসপি পিডিএর চেয়ে বেশি শক্তিশালী হতে পারে না , কারণ এটি আনবাউন্ডেড স্টোরেজের একমাত্র উত্স একটি সীমাবদ্ধ (কল স্ট্যাক) একটি সীমাবদ্ধ বর্ণমালা (সমস্ত আইপি (অবস্থান, দিকনির্দেশ) জোড়া) এর সেট। থামার সমস্যা পিডিএগুলির জন্য নির্ধারিত , সুতরাং এই চ্যালেঞ্জটি সর্বদা সম্ভব হওয়া উচিত।

চ্যালেঞ্জ

আপনার লক্ষ্য হ'ল এমন একটি প্রোগ্রাম লিখুন যা কোনও মডিলার এসএনআইএসপি প্রোগ্রামের প্রতিনিধিত্ব করে এমন অক্ষরের একটি ম্যাট্রিক্স গ্রহণ করে এবং এটি থামবে কি না তার উপর নির্ভর করে দুটি স্বতন্ত্র আউটপুটগুলির মধ্যে একটি প্রদান করে।

এটি , তাই সংক্ষিপ্ততম বৈধ প্রোগ্রাম ( বাইটে পরিমাপ করা ) জয়ী।

বিশেষ উল্লেখ

  • চরিত্রের ম্যাট্রিক্সটি আপনি যেভাবে নেবেন তা নমনীয়: একটি নতুনলাইন-পৃথক স্ট্রিং, স্ট্রিংগুলির অ্যারে, অক্ষরের অ্যারে, 2 ডি বর্ণের অ্যারে, প্রস্থের উপস্থাপিত পূর্ণসংখ্যার সাথে অক্ষরের সমতল অ্যারে ইত্যাদি সমস্ত গ্রহণযোগ্য। পরীক্ষার কেসগুলি সেই পছন্দগুলির মধ্যে প্রথমটি বেছে নেয়।
  • আপনি ধরে নিতে পারেন যে ইনপুট ম্যাট্রিক্সটি আয়তক্ষেত্রাকার হবে (যাতে আপনাকে ছোট সারি প্যাড করতে হবে না) এবং ননজারো দৈর্ঘ্য এবং প্রস্থের হবে।
  • আপনি যে কোনও দুটি স্বতন্ত্র আউটপুট চয়ন করতে পারেন, কেবল সত্যবাদী / মিথ্যা নয়।
  • আপনি অনুমান করতে পারেন যে ইনপুট ম্যাট্রিক্স শুধুমাত্র বৈধ কমান্ড গঠিত হবে ( \, /, !, @, #, এবং .)।
  • যখন কোনও আদেশ "পরবর্তী নির্দেশাবলী এড়িয়ে চলুন" বলা হয়, আপনি ধরে নিতে পারেন যে পরবর্তী পদক্ষেপ এড়াতে হবে। বিশেষত, এটি এমন পরিস্থিতিতে কখনও মুখোমুখি হবে না যেখানে (১) এটি প্লেফিল্ডের প্রান্তে অবস্থিত এবং (২) আইপিটি সেই প্রান্তে লম্ব প্রান্তরে চলেছে, যেমন "খেলার পরবর্তী ক্ষেত্রের বাইরে" পরবর্তী নির্দেশ "field"

পরীক্ষার কেস

নিম্নলিখিত স্নিপেট ভাষাতে প্রোগ্রামগুলি পরীক্ষা করতে ব্যবহার করা যেতে পারে। মনে রাখবেন যে সামান্য এখানে দেওয়া প্রকৃত স্পেসিফিকেশন চেয়ে বেশি প্রশ্রয়ের (যেমন এটা অক্ষরের চেয়ে অন্যান্য অনুমতি দেয় .নো অপস হিসাবে)।

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 - ল্যাম্বদা-আইফাইড কিছু ফাংশন। রিটার্নের সংখ্যা হ্রাস পেয়েছে। সমাপ্তির জন্য "সত্য" এবং অবিরতকরণের জন্য "মিথ্যা" প্রদান করে। ট্র্যাকিং অবজেক্ট হিসাবে বিদ্যমান ও ক্লাসকে উত্তোলন করে এন ক্লাসের প্রয়োজনীয়তা দূর করে।


প্রতিস্থাপন করা হচ্ছে 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

জাভাস্ক্রিপ্ট (ES6), 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
!/@@.\
.\..#/

এটিও থামে, এবং আইপি অক্ষর 4 টি একটি ধারাবাহিক দিক থেকে চার বার হিট করে, নিম্নোক্ত স্ট্যাকের স্টেটগুলির সাথে (স্ট্যাকের *শীর্ষটি নির্দেশ করে):

  • আকার = ২ [ক, খ] *
  • আকার = 1 [এ] *
  • আকার = 1 [খ] *
  • আকার = 0 [] *

দোভাষী কীভাবে কাজ করে

নির্দেশাবলী ( q) বাইনারি ( c) হিসাবে অনুবাদ করা হয়েছে (অন্যান্য সমস্ত অক্ষর সহ, .বা অন্যথায়, nops হিসাবে পরিবেশন করা):

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
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.