Giải quyết vấn đề dừng cho Befinge


29

Hãy định nghĩa một cách đơn giản bằng ngôn ngữ 2D, mà chúng tôi sẽ cung cấp cho các tên vô cùng gốc befinge . Befinge có 5 hướng dẫn:

  • <>^v, như trong hầu hết các esolang 2D, chuyển hướng con trỏ lệnh theo hướng tương ứng.
  • . là một không-op.

Con trỏ lệnh bắt đầu ở góc trên bên trái đi bên phải. Nếu con trỏ lệnh tới một cạnh, chương trình sẽ dừng lại. Mỗi chương trình Befinge rõ ràng sẽ dừng lại hoặc đi vào một vòng lặp vô tận mà không làm gì cả. Đây là hai ví dụ:

Dừng lại:

>.v
..<

Không dừng lại:

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

Vấn đề tạm dừng không thể giải quyết được đối với ngôn ngữ Turing-Complete, nhưng nó là dành cho ngôn ngữ này. Nhiệm vụ của bạn là viết một chương trình (hoặc hàm) lấy đầu vào là một chuỗi đại diện cho chương trình befinge và trả về giá trị trung thực hoặc falsey tùy thuộc vào việc nó có dừng hay không.

  • Bạn có thể giả định rằng đầu vào sẽ chỉ bao gồm các ký tự này và sẽ được đệm bằng khoảng trắng để tạo thành một hình chữ nhật.
  • Bạn có thể sử dụng bất kỳ bộ năm ký tự cho hướng dẫn (ví dụ adws ).

Các trường hợp thử nghiệm

Dừng lại:

.

v>
>^

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

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

Không dừng lại:

>..v
^..<

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

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

Đây là , vì vậy chương trình ngắn nhất (tính bằng byte) sẽ thắng.


Thế còn (Aheui) ?
JungHwan Min

Một số trường hợp thử nghiệm mà không phải mũi tên nào cũng trúng sẽ tốt.
xnor

Turing đã chứng minh rằng vấn đề Ngừng không thể giải quyết được đối với bất kỳ ngôn ngữ Turing-Complete nào, vì vậy tôi đã phải tạo ra một ngôn ngữ giả không hoàn thành Turing. Một ngôn ngữ cuối cùng sẽ luôn dừng lại không phải là Turing hoàn chỉnh.
Esolanging Fruit 9/11/2016

1
Chúng tôi cũng không có bất kỳ ví dụ nào trong đó đường dẫn biến không 90 độ như >..>.hoặc ><.
xnor

2
@PyRulez Vì tôi muốn xử lý chuyển động định hướng là một phần của thử thách.
Esolanging Fruit

Câu trả lời:


4

ES6 (JavaScript), 111, 101 byte

EDIT: thay đổi giá trị đầu ra thành truefalse , thay vì YN , để loại bỏ thêm 10 byte

Chơi gôn

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

Kiểm tra

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');

Đầu ra mẫu

#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 !

Bạn không thể chỉ sử dụng YNlàm đầu ra như trong JavaScript , cả hai đều là sự thật .
ბიმო

3

Python 2 , 116 105 byte

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

Hãy thử trực tuyến!

Thử thách đã cũ, nhưng tôi đoán vì đây là Python ngắn nhất, tôi sẽ đăng nó. Đầu vào là một danh sách các chuỗi, nhưng các ký tự được sử dụng là không bình thường.

> G
< B
v C
^ F
. L

Ví dụ, ví dụ tạm dừng thứ ba biến thành ['LLLLCLLLL', 'LLLLGLLLC', 'LFLLBLLLL', 'LLLLLLLCB', 'LLLLLLLCL', 'LLLLFLLBL']. Đầu ra là thông qua mã thoát, 0 (thành công) để không tạm dừng và 1 (lỗi) để tạm dừng. Bất kỳ lời khuyên hoặc thủ thuật đánh giá cao.


2

Befunge-98 (PyFunge) , 217 209 200 byte

#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 ^ @.!;>:'.-#;_

Hãy thử trực tuyến!

Một vấn đề tạm dừng befinge cần một giải pháp befunge. Trả về 0 cho sự thật và 1 cho falsey. Đặt đầu vào trên lưới bắt đầu từ 1,15 và sau đó di chuyển lên trên, thay thế các mũi tên bằng số không. Ngay khi chúng tôi đạt đến số 0, chúng tôi biết rằng đó là các vòng lặp. Bất cứ điều gì ngoài> <^ v. và zero được coi là tạm dừng chương trình, bao gồm đường viền của không gian chúng ta có xung quanh chương trình bằng cách đặt nó trên lưới một chút bù.

Một cách dễ dàng để loại bỏ một vài vết cắn là sử dụng số thay vì> <^ v. nhưng tôi không cảm thấy như thế


A befinge halting problem needs a befunge solution.Đúng. +1
Draco18

1

Turtlèd , 146 byte

!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],

Chương trình này có I / O khác nhau: vui lòng chấm dứt mỗi dòng bằng một khoảng trắng, bao gồm cả dòng cuối cùng. Turtlèd không thích dòng mới, vì nó sử dụng lưới cho chiều thứ hai của các ký tự.

Hãy thử trực tuyến!

0 cho các vòng lặp mãi mãi, 1 cho các vòng.

Giải thích chung:

Nó viết đầu vào trên lưới, sau đó nó thực sự đi theo đường dẫn mà mũi tên tạo ra xung quanh lưới, thay thế mỗi mũi tên bằng dấu *, đồng thời lưu hướng trong char var. Nếu nó gặp *, một mũi tên mà nó bắn trúng trước đó, chương trình sẽ không dừng lại, vì vậy nó đặt char var thành0 , thoát khỏi vòng lặp. Nếu không, nó sẽ chạm vào cuối lưới và thoát khỏi vòng lặp. Nó sẽ viết var var. Nếu nó chạm vào cuối lưới, nó sử dụng hướng được lưu trữ trong char var để quay lại lưới và đặt var var thành 1, để tạm dừng. Nếu var var thực sự là 0, không phải là một hướng, thì nó không cần phải quay lại, vì nó vẫn ở đó và nó đặt nó trở lại 0. Nó xóa lưới, sau đó viết var var, 1cho tạm dừng, khác 0.



1

JavaScript (ES6), 158 127 byte

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

Lấy đầu vào dưới dạng mảng ký tự hai chiều và trả về trueđể tạm dừng vàfalse cho một vòng lặp vô hạn. Hoạt động bằng cách đặt các ký tự hướng truy cập vào~ s khi nó đệ quy ngang qua chúng. Chỉnh sửa: Đã lưu 31 byte bằng cách cập nhật vectơ chỉ đường của tôi trước khi đệ quy.

Việc lạm dụng các ký tự lệnh ( 1=^ 4=< 5=. 6=> 9=v) sẽ đưa tôi xuống còn 101 byte:

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

> Đưa đầu vào dưới dạng mảng ký tự hai chiều Có được phép nhập định dạng khác không? (đi từ một chuỗi phẳng sang một mảng cũng mất byte).
zeppelin

@zeppelin Niềm tin của tôi là điều này được cho phép. Xem meta.codegolf.stackexchange.com/q/2214/17602 chẳng hạn.
Neil

Tham
khảoError

@ l4m2 Bah, tôi đã thực hiện lại, tôi đã bao gồm f=số byte nhưng không bao gồm mã ...
Neil

1

SmileBASIC, 158 145 byte

Nếu cùng một mũi tên gặp nhiều lần, chương trình sẽ không bao giờ dừng lại. Khi con trỏ lệnh vượt qua một mũi tên, nó được thay thế bằng một ký hiệu khác, điều này sẽ khiến hàm trả về 0 nếu đạt được một lần nữa. Nếu IP vượt quá giới hạn, nó sẽ trả về 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

Đưa đầu vào như một mảng của chuỗi. <any non-digit chracter>, 1, 2, 3, 4= ., >, <, v,^


0

Python 2, 182 byte

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

Lấy một chuỗi chuỗi làm đầu vào. Tôi phải chơi golf nhiều hơn nhưng bây giờ đã đến lúc phải căng thẳng về cuộc bầu cử.

Ung dung:

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

này, điều gì sẽ xảy ra nếu bạn lấy phần chính ra khỏi thử và chỉ đặt c = m [y] [x] trong một lần thử và ngoại trừ? điều này cũng sẽ cho phép bạn thay thế ngắt bằng 1/0, cũng như giảm thụt lề.
Lemon phá hủy

1
[-1,1][d=='v'] -> 2*(d>'>')-1[-1,1][d=='>'] -> 2*(d>'<')-1lưu tổng cộng 6 byte.
Kade

Câu trả lời sai cho["<>"]
frageum

0

Clojure, 143 byte

#((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))

Hàm có 4 đối số trạng thái: vị trí p , vận tốc v, chỉ số bước ivà kích thước của một dòng s. Trả về 1nếu chúng tôi không đi ra khỏi giới hạn trong 10 ^ 9 bước và nilnếu không. Trên thực tế có bao nhiêu bước chúng ta cần kiểm tra để chắc chắn , (count %)? Tôi nghĩ rằng nó còn hơn thế nữa vì cùng một NOP có thể được duyệt theo chiều ngang và chiều dọc.

Có thể được gọi như thế này (lấy các chuỗi bình thường làm đối số, gettrả về nilkhi nằm ngoài giới hạn):

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

Chuyển trạng thái (+1, -1, + s, -s) được mã hóa trong từ điển {\> 1\< -1\^(- s)\. v\v s}.


Số lượng ký tự lưới gấp 4 lần là đủ: nếu con trỏ trở về cùng một ký tự có cùng hướng đến, thì đó là một vòng lặp vô hạn.
Greg Martin

0

Trăn 2/3, 201 192 byte

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

Hãy thử trực tuyến!

Đưa ra câu trả lời đúng cho ["<>"]


Tôi tin rằng bạn có thể lưu một vài byte bằng cách thay đổi từ một chức năng thành một chương trình đầy đủ. Bạn có thể thay thế def f(x):bằng x=input()chênh lệch 0 byte, sau đó loại bỏ thụt lề bổ sung (-8 byte), sau đó thay thế return xbằng exit(x)(được phép cho mỗi đồng thuận meta ), cho 2 byte khác. Dù sao, giải pháp tốt đẹp!
Lưỡng cư

0

Java, 477

Tôi biết rằng đây không phải là chiến thắng, n = và có thể được đánh gôn nhiều hơn, nhưng nó áp dụng một phương pháp tương tự như những gì các câu trả lời khác sử dụng, nhưng cách này sử dụng hàm băm để thực hiện tra cứu. Đầu vào đang sử dụng các ký hiệu> <^ v và bất cứ thứ gì khác ngoài ký hiệu không có op. Đầu vào đến thông qua args.

GOLFED

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);}}

NÂNG CẤP

nhập 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);
    }
}

Giải thích đến sớm!


Một điều nhỏ: bạn có thể thay đổi String a[]để String[]avà bỏ qua không gian.
Esolanging Fruit

Bạn cũng có thể sử dụng varở nhiều nơi nếu bạn sử dụng Java 10.
Esolanging Fruit

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.