แก้ไขปัญหาการหยุดชะงักของ Befinge


29

ให้มีกำหนดที่เรียบง่ายภาษา 2D ซึ่งเราจะให้ชื่อเดิมอย่างไม่น่าเชื่อbefinge Befinge มี 5 คำแนะนำ:

  • <>^vเช่นเดียวกับใน esolangs 2D ส่วนใหญ่ให้เปลี่ยนเส้นทางตัวชี้คำสั่งในทิศทางที่เกี่ยวข้อง
  • . เป็น no-op

ตัวชี้คำสั่งเริ่มต้นที่มุมบนซ้ายไปทางขวา หากตัวชี้คำแนะนำเข้าใกล้ขอบโปรแกรมจะหยุด ทุกโปรแกรมของ Befinge จะหยุดหรือเข้าสู่วงวนไม่สิ้นสุดซึ่งไม่ทำอะไรเลย นี่คือสองตัวอย่าง:

ลังเล:

>.v
..<

แบบไม่ลังเล:

>....v
..v..<
..>v..
^..<..

ปัญหาการหยุดชะงักไม่สามารถแก้ไขได้สำหรับภาษาทัวริงที่สมบูรณ์ แต่สำหรับภาษานี้ งานของคุณคือการเขียนโปรแกรม (หรือฟังก์ชั่น) ที่ใช้เป็นอินพุตสตริงที่แทนโปรแกรมbefingeและส่งกลับค่าความจริงหรือความเท็จขึ้นอยู่กับว่ามันจะหยุดหรือไม่

  • คุณสามารถสันนิษฐานได้ว่าการป้อนข้อมูลจะประกอบด้วยตัวละครเหล่านี้เท่านั้นและจะถูกเติมด้วยช่องว่างเพื่อสร้างสี่เหลี่ยมผืนผ้า
  • คุณสามารถใช้ชุดอักขระห้าตัวสำหรับคำแนะนำ (เช่นadws )

กรณีทดสอบ

ลังเล:

.

v>
>^

....v....
....>...v
.^..<....
.......v<
.......v.
....^..<.

v<>v>v^
>v^>^>v
<>>^v<v
v^<>v^<

แบบไม่ลังเล:

>..v
^..<

>v<
v<.
>v.
v<.
>.^

>.>.>.v
.><.<.<

นี่คือดังนั้นโปรแกรมที่สั้นที่สุด (เป็นไบต์) จะชนะ


แล้ว아희 (Aheui)ล่ะ?
JungHwan Min

กรณีทดสอบบางอย่างที่ไม่ใช่ลูกธนูทุกอันจะดี
xnor

ทัวริงพิสูจน์ว่าปัญหา Halting ไม่สามารถแก้ไขได้สำหรับภาษาทัวริงที่สมบูรณ์ดังนั้นฉันจึงต้องสร้างของปลอมที่ไม่ได้ทำทัวริงให้สมบูรณ์ ภาษาที่มักจะหยุดชะงักในที่สุดก็ไม่ได้ทำให้ทัวริงสมบูรณ์
แยกผลไม้

1
นอกจากนี้เรายังไม่ได้มีตัวอย่างใด ๆ ที่เส้นทางทำให้เลี้ยวไม่ใช่ 90 องศาเหมือนหรือ>..>. ><
xnor

2
@PyRulez เพราะฉันต้องการให้การประมวลผลภาพเคลื่อนไหวเป็นส่วนหนึ่งของความท้าทาย
แยกผลไม้

คำตอบ:


4

ES6 (JavaScript) 111, 101 ไบต์

แก้ไข:เปลี่ยนค่าเอาต์พุตเป็นจริงและเท็จแทนที่จะเป็นYและNเพื่อโกนหนวดออก 10 ไบต์ขึ้นไป

แข็งแรงเล่นกอล์ฟ

F=(I,M=[...I],c=0,i)=>(i={j:v=I.search`\n`+1,k:-v,h:-1,l:1,q:i,0:0}[M[c]])?F(I,M,c+i+(M[c]=0),i):i!=0

ทดสอบ

F=(I,M=[...I],c=0,i)=>(i={j:v=I.search`\n`+1,k:-v,h:-1,l:1,q:i,0:0}[M[c]])?F(I,M,c+i+(M[c]=0),i):i!=0  

//Alphabet Map
tr={
'<':'h',
'>':'l',
'^':'k',
'v':'j',
'.':'q',
'\n':'\n'
};

//Test
T=(I,A)=>{
console.log({"Y":"#Halting","N":"#Non-Halting"}[A]);
console.log("I=\n",I,"\nF(I)=",O=F([...I].map(s=>tr[s]).join('')));
console.log('NY'[O*1] == A ? "OK !" : "NOT OK !");
}

//Halting
T(
`>.v
..<`
,'Y');

//Non-Halting
T(
`>....v
..v..<
..>v..
^..<..`
,'N');

//Halting
T(
`.`
,'Y')

//Halting
T(
`v>
>^`
,'Y');

//Halting
T(
`....v....
....>...v
.^..<....
.......v<
.......v.
....^..<.`
,'Y');

//Halting
T(
`v<>v>v^
>v^>^>v
<>>^v<v
v^<>v^<`
,'Y');

//Non-Halting
T(
`>..v
^..<`
,'N');

//Non-Halting
T(
`>v<
v<.
>v.
v<.
>.^`
,'N');

//Non-Halting
T(
`>.>.>.v
.><.<.<`
,'N');

ตัวอย่างผลลัพธ์

#Halting
I=
>.v
..< 
F(I)= true
OK !    

#Non-Halting
I=
>....v
..v..<
..>v..
^..<.. 
F(I)= false
OK !

#Halting
I=
 . 
F(I)= true
OK !

#Halting
I=
v>
>^ 
F(I)= true
OK !

#Halting
I=
....v....
....>...v
.^..<....
.......v<
.......v.
....^..<. 
F(I)= true
OK !

#Halting
I=
v<>v>v^
>v^>^>v
<>>^v<v
v^<>v^< 
F(I)= true
OK !

#Non-Halting
I=
>..v
^..< 
F(I)= false
OK !

#Non-Halting
I=
>v<
v<.
>v.
v<.
>.^ 
F(I)= false
OK !

#Non-Halting
I=
>.>.>.v
.><.<.< 
F(I)= false
OK !

คุณไม่สามารถใช้เพียงแค่YและNเป็นผลลัพธ์เช่นเดียวกับใน JavaScript พวกเขาทั้งสองเป็นความจริง
ბიმო

3

Python 2 , 116 105 ไบต์

x=1
X=Y=y=0
H=[]
G=input()
while(X,Y,x,y)not in H:H+=[(X,Y,x,y)];C=ord(G[Y][X]);x=C%3-1;y=C%5-1;X+=x;Y+=y

ลองออนไลน์!

ความท้าทายนั้นเก่า แต่ฉันคิดว่านี่เป็น Python ที่สั้นที่สุดฉันจะโพสต์มัน อินพุตเป็นรายการของสตริง แต่อักขระที่ใช้ผิดปกติ

> G
< B
v C
^ F
. L

['LLLLCLLLL', 'LLLLGLLLC', 'LFLLBLLLL', 'LLLLLLLCB', 'LLLLLLLCL', 'LLLLFLLBL']ยกตัวอย่างเช่นตัวอย่างลังเลที่สามจะกลายเป็น เอาต์พุตเป็นรหัสทางออก 0 (สำเร็จ) สำหรับการไม่หยุดและ 1 (ข้อผิดพลาด) สำหรับการหยุด เคล็ดลับหรือเทคนิคใด ๆ ที่ชื่นชม


2

Befunge-98 (PyFunge) , 217 209 200 ไบต์

#v10dpf1dp12dp3dpk
 >#v~:a-#v_$10dp1dg1+1dp >
v  >10dp;>0dg1dgp0dg1+0dp^;f1dp
>0dg1dgg:'^-#v_n1-v
^<v01_v#!->':<
  <   >:'<-#v_01-0>   v
v^pd1+gd3gd1[:'v-#v_01>3dp2dpndg1dgp
>0dg2dg+0dp ^ @.!;>:'.-#;_

ลองออนไลน์!

ปัญหาการหยุดชะงักของ befinge ต้องการวิธีแก้ปัญหาของ befunge ผลตอบแทนที่ 0 สำหรับความจริงและ 1 สำหรับความเท็จ วางอินพุตบนกริดเริ่มจาก 1,15 แล้วย้ายที่ด้านบนแทนที่ลูกศรด้วยเลขศูนย์ ทันทีที่เราถึงศูนย์เราก็รู้ว่ามันเป็นลูป อะไรนอกจาก> <^ v และจะพิจารณาเป็นศูนย์เพื่อหยุดโปรแกรมซึ่งรวมถึงเส้นขอบของช่องว่างที่เราได้รับรอบโปรแกรมโดยการวางลงบนกริดเล็กน้อย

วิธีง่ายๆในการโกนหนวดกัดสองสามอันคือการใช้ตัวเลขแทน> <^ v แต่ฉันไม่รู้สึกว่ามันคุ้มค่า


A befinge halting problem needs a befunge solution.แม่นยำ. +1
Draco18s

1

ตุรกี , 146 ไบต์

!u[*.[ r+.]l[ l]dr_+]#*#[ u]d[ (.r)(>.r{.r}@>)(v.d{.d}@v)(<.l{.l}@<)(^.u{.u}@^)(*@0' )],@1(0@0)(v' d)(<' r)(>' l)(^' d)[ u]d[ l]r[ [ r]l[ ' l]dr],

โปรแกรมนี้ใช้ I / O แตกต่างกัน: โปรดยุติแต่ละบรรทัดด้วยช่องว่างรวมถึงบรรทัดสุดท้าย Turtlèdไม่ชอบการขึ้นบรรทัดใหม่เนื่องจากใช้กริดสำหรับมิติที่สองของตัวละคร

ลองออนไลน์!

0 สำหรับวนซ้ำตลอดไป 1 สำหรับหยุดพัก

คำอธิบายทั่วไป:

มันเขียนอินพุตบนกริดจากนั้นก็ตามเส้นทางที่ลูกศรทำรอบกริดแทนที่ลูกศรแต่ละตัวด้วย * ตามที่มันไปนอกจากนี้ยังบันทึกทิศทางใน char var ด้วย หากพบ * ลูกศรที่กดก่อนหน้าโปรแกรมจะไม่หยุดดังนั้นจึงตั้งค่า char var เป็น0ออกจากลูป มิฉะนั้นจะเข้าสู่จุดสิ้นสุดของกริดและออกจากลูป มันจะเขียนตัวอักษร หากมันกดที่ส่วนท้ายของตารางมันจะใช้ทิศทางที่เก็บไว้ใน char var เพื่อกลับไปที่ตารางและตั้งค่า var var เป็น1สำหรับหยุดพัก หาก var ถ่านเป็นจริง 0 0ไม่ทิศทางที่มันไม่จำเป็นต้องได้รับกลับมาในขณะที่มันยังคงมีและมันทำให้มันกลับไป มันล้างออกตารางแล้วเขียน var ถ่านที่สำหรับหยุดพักอื่น10



1

JavaScript (ES6), 158 127 ไบต์

f=(a,x=0,y=0,d=1,e=0,c=a[y]&&a[y][x])=>c<'~'?(c>'.'&&(a[y][x]='~',d=(c=='>')-(c=='<'),e=(c=='v')-(c=='^')),f(a,x+d,y+e,d,e)):!c

รับอินพุตเป็นอาร์เรย์อักขระสองมิติและส่งคืนtrueเพื่อหยุดและfalseสำหรับการวนซ้ำไม่สิ้นสุด ทำงานโดยการตั้งค่าอักขระทิศทางที่เยี่ยมชม~เป็น s ขณะที่มันวนซ้ำแบบสำรวจซ้ำ แก้ไข: บันทึก 31 ไบต์โดยอัปเดตเวกเตอร์ทิศทางของฉันก่อนเรียกซ้ำ

การใช้อักขระคำสั่งที่ไม่เหมาะสม ( 1=^ 4=< 5=. 6=> 9=v) ทำให้ฉันมีขนาดไม่เกิน 101 ไบต์:

f=(a,x=0,y=0,d=1,e=0,c=a[y]&&a[y][x])=>+c?(c-5&&(a[y][x]='0',d=~-c%4,e=~-(c>>2)),f(a,x+d,y+e,d,e)):!c

> รับอินพุตเป็นอาร์เรย์อักขระสองมิติอนุญาตอินพุตที่จัดรูปแบบแตกต่างกันหรือไม่? (ไปจากสตริงแบนไปยังอาร์เรย์จะใช้ไบต์ด้วย)
เรือเหาะ

@zeppelin ความเชื่อของฉันคือสิ่งนี้ได้รับอนุญาต ดูmeta.codegolf.stackexchange.com/q/2214/17602เช่น
Neil

ReferenceError: f ไม่ได้ถูกกำหนด
l4m2

@ l4m2 Bah ฉันทำอีกครั้งฉันได้รวมf=จำนวนไบต์ แต่ไม่ใช่รหัส ...
357 Neil

1

SmileBASIC, 158 145 ไบต์

หากพบลูกศรเดียวกันมากกว่าหนึ่งครั้งโปรแกรมจะไม่หยุด เมื่อตัวชี้คำแนะนำส่งลูกศรมันจะถูกแทนที่ด้วยสัญลักษณ์ที่แตกต่างกันซึ่งจะทำให้ฟังก์ชันส่งกลับค่า 0 หากถึงอีกครั้ง ถ้า IP ไม่มีขอบเขตมันจะคืนค่า 1

DEF H P@L
C=VAL(P[Y][X])IF C>8THEN?0RETURN
IF C THEN D=C-1P[Y][X]="9
X=X+!D-(D==1)Y=Y+(D==2)-(D>2)IF X+1&&Y+1&&Y-LEN(P)&&X-LEN(P[0])GOTO@L
?1
END

รับอินพุตเป็นอาร์เรย์ของสตริง <any non-digit chracter>, 1, 2, 3, 4= ., >, <, v,^


0

Python 2, 182 ไบต์

m,v,d,x,y=input(),[],'>',0,0
try:
 while 1:
  if[x,y]in v:print 0;break
  c=m[y][x]
  if c!='.':d=c;v+=[[x,y]]
  if d in'><':x+=[-1,1][d=='>']
  else:y+=[-1,1][d=='v']
except:print 1

รับอาร์เรย์สตริงเป็นอินพุต ฉันต้องตีกอล์ฟให้มากกว่านี้ แต่ตอนนี้ถึงเวลาแล้วที่จะต้องเครียดกับการเลือกตั้ง

Ungolfed:

input = input()

visited = [  ] 

dir = ">"
x=0
y=0

try:
    while True:
        if[x,y]in visited:print False;break
        char=input[y][x]
        if char!=".":
            dir=char
            visited+=[[x,y]]

        if dir==">":
            x+=1
        if dir=="<":
            x-=1
        if dir=="v":
            y+=1
        if dir=="^":
            x-=1
except:
    print True

เดี๋ยวก่อนถ้าคุณเอาส่วนหลักออกจากการลองและใส่เฉพาะ c = m [y] [x] ในการลองและยกเว้น? สิ่งนี้จะช่วยให้คุณสามารถแทนที่การหยุดพักด้วย 1/0 เช่นเดียวกับการลดการเยื้อง
เลมอนที่ทำลายได้

1
[-1,1][d=='v'] -> 2*(d>'>')-1และ[-1,1][d=='>'] -> 2*(d>'<')-1บันทึกทั้งหมด 6 ไบต์
Kade

คำตอบที่ผิดสำหรับ["<>"]
feersum

0

Clojure 143 ไบต์

#((fn[p v i s](if-let[v({\> 1\< -1\^(- s)\. v\v s}(get % p))](if(neg? i)1(recur(+ p v)v(dec i)s))))0 1 1e9(+(count(take-while(set"<>v^.")%))1))

ฟังก์ชั่นที่มีการขัดแย้ง 4 รัฐ: ตำแหน่งpความเร็วvดัชนีขั้นตอนและขนาดของเส้นหนึ่งi sส่งคืน1ถ้าเราไม่ออกนอกขอบเขตใน 10 ^ 9 ขั้นตอนและnilอย่างอื่น ที่จริงวิธีการหลายขั้นตอนที่เราจะต้องตรวจสอบเพื่อให้แน่ใจว่า(count %)? ฉันคิดว่ามันเป็นมากกว่านั้นเช่นเดียวกับ NOP เดียวกันที่สามารถเคลื่อนที่ในแนวนอนและแนวตั้ง

สามารถถูกเรียกเช่นนี้ (รับสายปกติเป็นอาร์กิวเมนต์getส่งกลับnilเมื่ออยู่นอกขอบเขต):

(def f #( ... ))
(f ">....v\n..v..<\n..>v..\n^..<..")
(f "v>\n>^")
(f "....v....\n....>...v\n.^..<....\n.......v<\n.......v.\n....^..<.")

รัฐเปลี่ยน (+1, -1, + S, -s) {\> 1\< -1\^(- s)\. v\v s}มีการเข้ารหัสในพจนานุกรม


4 เท่าของจำนวนอักขระกริดควรเพียงพอ: หากตัวชี้กลับมาที่อักขระเดียวกันโดยมีทิศทางเข้ามาเหมือนกันแสดงว่าอยู่ในวงวนไม่สิ้นสุด
Greg Martin

0

Python 2/3, 201 192 ไบต์

def f(x):
 X=Y=b=0;a=1;D={}
 while len(x)>Y>-1<X<len(x[Y]):
  try:
   a,b={'>':(1,0),'^':(0,-1),'<':(-1,0),'v':(0,1)}[x[Y][X]]
   if(X,Y)in D:return 0
  except:0
  D[X,Y]=0;X+=a;Y+=b
 return 1

ลองออนไลน์!

ให้คำตอบที่ถูกต้องสำหรับ ["<>"]


ฉันเชื่อว่าคุณสามารถบันทึกได้หลายไบต์โดยเปลี่ยนจากฟังก์ชั่นเป็นโปรแกรมเต็มรูปแบบ คุณสามารถแทนที่def f(x):ด้วยx=input()ความแตกต่าง 0 ไบต์จากนั้นลบการเยื้องพิเศษ (-8 ไบต์) จากนั้นแทนที่return xด้วยexit(x)(ได้รับอนุญาตต่อฉันทามติเมตา ) อีก 2 ไบต์ อย่างไรก็ตามทางออกที่ดี!
สะเทินน้ำสะเทินบก

0

Java, 477

ฉันรู้ว่านี่ไม่ชนะ n = และอาจจะเล่นกอล์ฟได้มากกว่านี้ แต่มันเกี่ยวข้องกับวิธีการที่คล้ายคลึงกับคำตอบอื่น ๆ ที่ใช้ แต่อันนี้ใช้ hashmap เพื่อทำการค้นหา อินพุตกำลังใช้สัญลักษณ์> <^ v และสิ่งอื่นนอกเหนือจากนั้นสำหรับ op อินพุตมาจาก args

แข็งแรงเล่นกอล์ฟ

import java.util.*;interface B{static void main(String[]a){HashMap<String,Byte>h=new HashMap<>();int x,y=0;for(String s:a){x=0;for(char c:s.toCharArray()){if("><^v".indexOf(c)>-1)h.put(x+","+y,(byte)c);x++;}y++;}x=0;y=0;int d=0;int D=0;while(x>-1&&x<a[0].length()&&y<a.length&&y>-1){Byte v=h.get(x+","+y);if(v!=null){if(v==0){System.out.print(0);return;}d=(v<85)?"<>".indexOf(v)*2-1:0;D=(v>84)?"^v".indexOf(v)*2-1:0;}h.replace(x+","+y,(byte)0);x+=d;y+=D;}System.out.print(1);}}

UNGOLFED

นำเข้า java.util. *;

interface B{
    static void main(String a[]) {
        HashMap<String, Byte> h = new HashMap<>();
        int x, y = 0;
        for(String s : a) {
            x = 0;
            for(char c : s.toCharArray()) {
                if ("><^v".indexOf(c) > -1) h.put(x + "," + y, (byte) c);
                x++;
            }
            y++;
        }
        x = 0;
        y = 0;
        int d = 0;
        int D = 0;
        while(x > -1 && x < a[0].length() && y < a.length && y > -1) {
            Byte v = h.get(x + "," + y);
            if(v != null) {
                if(v == 0) {System.out.print(0); return;}
                d = (v < 85) ? "<>".indexOf(v)*2-1 : 0;
                D = (v > 84) ? "^v".indexOf(v)*2-1 : 0;
            }
            h.replace(x + "," + y, (byte) 0);
            x += d;
            y += D;
        }
        System.out.print(1);
    }
}

คำอธิบายจะมาเร็ว ๆ นี้!


สิ่งหนึ่งที่มีขนาดเล็ก: คุณสามารถเปลี่ยนString a[]ไปString[]aและงดพื้นที่
แยกผลไม้

นอกจากนี้คุณยังสามารถใช้varในหลาย ๆ สถานที่หากคุณใช้ Java 10
แยกผลไม้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.