ในจิตวิญญาณของการแก้ปัญหาลังเลสำหรับ Befingeให้มีกำหนดภาษาอื่นที่เรียกว่า 2D Modilar SNISP Modilar SNISP มีหกคำแนะนำต่อไปนี้:
\
ชี้นำตัวชี้คำสั่งดังนี้:- หากเข้าหาจากด้านบนไปทางขวา;
- ถ้าเดินจากทางขวาขึ้นไป;
- หากเข้าหาจากด้านล่างไปซ้าย;
- หากเข้าหาจากด้านซ้ายให้ลงไป
/
ชี้นำตัวชี้คำสั่งดังนี้:- ถ้าเข้าหาจากด้านบนไปซ้าย;
- หากเข้าหาจากด้านซ้ายขึ้นไป;
- หากเข้าหาจากด้านล่างไปทางขวา;
- หากเข้าหาจากด้านขวาให้ลงไป
!
ข้ามคำแนะนำถัดไป@
ผลักตำแหน่ง IP และทิศทางไปยังสแตกการโทร#
ดึงตำแหน่ง IP และทิศทางจาก call stack และเรียกคืนจากนั้นข้ามคำสั่งถัดไป หาก call stack ว่างเปล่าการดำเนินการจะหยุดลง.
ไม่ทำอะไรเลย
ตัวชี้คำสั่งเริ่มต้นที่มุมซ้ายบนไปทางขวา หากเคยออกจากสนามแข่งขันการประหารชีวิตจะหยุดลง
Modilar SNISP ไม่สามารถมีประสิทธิภาพมากกว่าPDAได้เพราะแหล่งเดียวของที่เก็บข้อมูลที่ไม่ได้ จำกัด คือสแต็ก (call call) ที่มีตัวอักษรที่ จำกัด (คู่ของ IP ทั้งหมด (ตำแหน่งทิศทาง) ปัญหาการหยุดชะงักสามารถตัดสินใจได้สำหรับพีดีเอดังนั้นความท้าทายนี้ควรเป็นไปได้
ความท้าทาย
เป้าหมายของคุณคือการเขียนโปรแกรมที่ใช้เมทริกซ์ของตัวละครที่เป็นตัวแทนของโปรแกรม Modilar SNISP และส่งกลับผลลัพธ์ที่แตกต่างกันหนึ่งในสองขึ้นอยู่กับว่ามันหยุดหรือไม่
นี่คือรหัสกอล์ฟดังนั้นโปรแกรมที่ถูกต้องสั้นที่สุด (วัดเป็นไบต์ ) ชนะ
ข้อมูลจำเพาะ
- วิธีที่คุณใช้เมทริกซ์ของอักขระนั้นมีความยืดหยุ่น: สตริงที่คั่นด้วยบรรทัดใหม่, อาร์เรย์ของสตริง, อาร์เรย์ของอักขระ, อาร์เรย์ 2d ของอักขระ, อาร์เรย์แบบแบนของอักขระที่มีจำนวนเต็มที่เป็นตัวแทนของความกว้าง ฯลฯ ล้วนเป็นที่ยอมรับ กรณีทดสอบเลือกใช้ตัวเลือกแรกเหล่านั้น
- คุณสามารถสมมติว่าเมทริกซ์การป้อนข้อมูลจะเป็นรูปสี่เหลี่ยมผืนผ้า (ดังนั้นคุณไม่จำเป็นต้องวางแถวสั้น ๆ ) และจะมีความยาวและความกว้างที่ไม่ใช่ศูนย์
- คุณสามารถเลือกเอาท์พุทที่แตกต่างกันสองแบบไม่เพียง แต่ความจริง / เท็จ
- คุณสามารถคิดว่าเมทริกซ์การป้อนข้อมูลจะมีเพียงคำสั่งที่ถูกต้อง (
\
,/
,!
,@
,#
และ.
) - เมื่อคำสั่งถูกพูดว่า "ข้ามคำสั่งถัดไป" คุณสามารถสันนิษฐานได้ว่าจะมีคำสั่งถัดไปที่จะข้าม โดยเฉพาะอย่างยิ่งมันจะไม่ถูกพบในสถานการณ์ที่ (1) มันอยู่บนขอบสนามเด็กเล่นและ (2) IP กำลังเคลื่อนที่ในแนวตั้งฉากกับขอบนั้นเช่น "คำสั่งต่อไป" หลังจากที่มันจะอยู่นอกสนามแข่งขัน
กรณีทดสอบ
ตัวอย่างต่อไปนี้สามารถใช้ในการทดสอบโปรแกรมในภาษา โปรดทราบว่าอนุญาตเล็กน้อยกว่าข้อกำหนดจริงที่ให้ไว้ที่นี่เล็กน้อย (เช่นอนุญาตให้ใช้อักขระอื่นนอกเหนือจาก.
ที่ไม่มีตัวเลือก)
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>
รูปแบบ ungolfed สามารถพบได้ที่นี่
ที่ลังเล
.
โปรแกรมที่เล็กที่สุดเท่าที่จะเป็นไปได้ ออกไปทางขวา
\\
\/
ลมไปรอบ ๆ โปรแกรมและออกไปด้านบน
.\./.\
.\!/./
ไปในวง ลมผ่านส่วนหนึ่งของแทร็กในสองทิศทางที่แตกต่างกัน
@\!/#
.\@/#
ใช้ทั้งหกคำสั่ง
@.@.@.@.@.@.@.@.@.#
เวลาดำเนินการของโปรแกรมนี้เป็นเลขชี้กำลังในจำนวนการทำซ้ำของ@.
แต่มันก็ยังคงหยุดทำงาน
แบบไม่ลังเล
!/\
.\/
ฉันเชื่อว่านี่เป็นวงที่สั้นที่สุด
@!\\#/@\!\
//@//.#./.
.\#.!\./\.
#.\!@!\@//
/..@.@\/#!
\.@.#.\/@.
สิ่งนี้หมุนรอบแทร็กวางไข่เฟรมสแต็กเป็นครั้งคราวก่อนที่ในที่สุดจะติดอยู่ในวงจรที่สร้างเฟรมสแต็คอย่างไม่สิ้นสุด ไม่ใช่คำสั่งทั้งหมดที่ใช้จริง
.!/@.@.@.@.@.\
/.@.@.@.@.@.@/
\@.@.@.@.@.@.\
/.@.@.@.@.@.@/
.@\@.@.@.@.@.\
\.@.@.@.@.@.@/
คงการสร้างเฟรมสแต็ก แต่ไม่มีใครกลับมาเลย