의 정신 Befinge에 대한 중단 문제를 해결 ,의라는 또 다른 차원의 언어로 정의 할 수 Modilar SNISP을 . Modilar SNISP에는 다음 6 가지 지침이 있습니다.
\
다음과 같이 명령 포인터를 지시합니다.- 맨 위에서 접근하면 오른쪽으로 이동하십시오.
- 오른쪽에서 접근하면 위로 올라가십시오.
- 바닥에서 접근하면 왼쪽으로 이동하십시오.
- 왼쪽에서 접근하면 내려갑니다.
/
다음과 같이 명령 포인터를 지시합니다.- 맨 위에서 접근하면 왼쪽으로 이동하십시오.
- 왼쪽에서 접근하면 위로 올라갑니다.
- 바닥에서 접근하면 오른쪽으로 이동하십시오.
- 오른쪽에서 접근하면 내려갑니다.
!
다음 명령을 건너 뜁니다.@
IP 위치 및 방향을 호출 스택으로 푸시합니다.#
호출 스택에서 IP 위치와 방향을 표시하고 복원 한 후 다음 명령을 건너 뜁니다. 호출 스택이 비어 있으면 실행이 중지됩니다..
아무것도하지 않습니다.
명령 포인터는 오른쪽 상단에서 시작합니다. 그것이 운동장을 떠나면 실행이 중단됩니다.
제한되지 않은 스토리지의 유일한 소스는 유한 알파벳 (모든 IP (위치, 방향) 쌍의 세트)이있는 스택 (호출 스택)이기 때문에 Modilar SNISP는 PDA 보다 강력 할 수 없습니다 . PDA의 경우 정지 문제를 결정할 수 있으므로이 문제는 항상 가능합니다.
도전
귀하의 목표는 Modilar SNISP 프로그램을 나타내는 문자 매트릭스를 사용하고 정지 여부에 따라 두 가지 고유 한 출력 중 하나를 리턴하는 프로그램을 작성하는 것입니다.
이것은 code-golf 이므로 가장 짧은 유효한 프로그램 ( 바이트 단위로 측정 )이 이깁니다.
명세서
- 문자 행렬을 취하는 방식은 유연합니다. 줄 바꿈으로 구분 된 문자열, 문자열 배열, 문자 배열 배열, 2d 문자 배열, 너비를 나타내는 정수를 가진 평면 문자 배열 등이 모두 허용됩니다. 테스트 사례는 이러한 선택 중 첫 번째를 선택합니다.
- 입력 행렬이 직사각형이고 짧은 행을 채울 필요가 없으며 길이와 너비가 0이 아니라고 가정 할 수 있습니다.
- 진실 / 거짓뿐만 아니라 두 가지 뚜렷한 결과를 선택할 수 있습니다.
- 당신은 입력 행렬은 유효한 명령으로 구성된다고 가정 할 수 있습니다 (
\
,/
,!
,@
,#
, 및.
). - 명령이 "다음 명령 건너 뛰기"라고 말하면 건너 뛸 다음 명령이 있다고 가정 할 수 있습니다. 특히, (1) 운동장 가장자리에 있고 (2) IP가 그 가장자리에 직각으로 이동하여 "다음 명령"이 운동장 밖에 놓이는 상황에서는 발생하지 않습니다.
테스트 사례
다음 코드는 언어로 프로그램을 테스트하는 데 사용할 수 있습니다. 여기에 제공된 실제 사양보다 약간 더 허용됩니다 (예 : .
no-ops 이외의 문자 허용 ).
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 양식은 여기 에서 찾을 수 있습니다 .
정지
.
가능한 가장 작은 프로그램. 오른쪽으로 나갑니다.
\\
\/
프로그램을 둘러보고 맨 위로 나갑니다.
.\./.\
.\!/./
루프로 들어갑니다. 트랙의 일부를 서로 다른 두 방향으로 감습니다.
@\!/#
.\@/#
6 가지 명령을 모두 사용합니다.
@.@.@.@.@.@.@.@.@.#
이 프로그램의 실행 시간은의 반복 횟수에 기하 급수적 @.
이지만 여전히 정지합니다.
비 보정
!/\
.\/
나는 이것이 가장 짧은 무한 루프라고 생각합니다.
@!\\#/@\!\
//@//.#./.
.\#.!\./\.
#.\!@!\@//
/..@.@\/#!
\.@.#.\/@.
이것은 트랙 주위를 감아 스택 프레임을 때때로 생성하여 결국 스택 프레임을 무한대로 생성하는 사이클에 걸리게됩니다. 모든 명령이 실제로 사용되는 것은 아닙니다.
.!/@.@.@.@.@.\
/.@.@.@.@.@.@/
\@.@.@.@.@.@.\
/.@.@.@.@.@.@/
.@\@.@.@.@.@.\
\.@.@.@.@.@.@/
스택 프레임을 계속 생성하지만 반환 프레임은 없습니다.