Befinge için Durma Problemini Çözme


29

İnanılmaz derecede orijinal ismini befinge verecek olan basit bir 2D dili tanımlayalım . Befinge'da 5 talimat var:

  • <>^v, çoğu 2B izolanjında ​​olduğu gibi, talimat işaretçisini ilgili yönlerine yönlendirin.
  • . bir ameliyat değildir.

Talimat işaretçisi, sol üst köşede sağa doğru ilerleyerek başlar. Kumanda göstergesi bir kenara gelirse, program durur. Her Befinge programı açıkça durur ya da hiçbir şey yapmadan sonsuz bir döngüye girer. İşte iki örnek:

durduruluyor:

>.v
..<

Sigara durduruluyor:

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

Durma problemi Turing-tamamlanmış bir dil için çözülemez, fakat bunun için. Göreviniz, ateşleme programını temsil eden bir dize girdi olarak alan ve durup durmamasına bağlı olarak bir truthy veya falsey değeri döndüren bir program (veya işlev) yazmaktır .

  • Girişin yalnızca bu karakterlerden oluşacağını ve bir dikdörtgen oluşturmak için boşluklarla doldurulacağını varsayabilirsiniz.
  • Talimatlar için herhangi bir beş karakter setini kullanabilirsiniz (örn. adws ).

Test Kılıfları

durduruluyor:

.

v>
>^

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

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

Sigara durduruluyor:

>..v
^..<

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

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

Bu , yani en kısa program (bayt cinsinden) kazanır.



Her okun vurulmadığı bazı test durumları iyi olacaktır.
Xnor

Turing, Halting sorununun herhangi bir Turing-Complete dili için çözülemediğini kanıtladı, bu yüzden Turing'in tamamlanmadığı sahte bir tane yapmak zorunda kaldım. Her zaman sonunda duracak bir dil Turing tam değil.
Esolanging Fruit

1
Ayrıca, yolun 90 derecelik olmayan bir dönüş >..>.ya da gibi yaptığı hiçbir örneğimiz yok ><.
xnor

2
@PyRulez Çünkü yönlü hareketi işleme zorluğun bir parçası olmak istedim.
Esolanging Fruit

Yanıtlar:


4

ES6 (JavaScript), 111, 101 bayt

EDIT: çıktı değerlerini 10 bayt daha fazla tıraş etmek için Y ve N yerine doğru ve yanlış olarak değiştirdi

golfed

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

Ölçek

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

Örnek çıktı

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

Sadece kullanamazsınız Yve Nçıktıları JavaScript'te olduğu gibi ikisi de hakikatsizdir .
ბიმო

3

Python 2 , 116 105 bayt

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

Çevrimiçi deneyin!

Zorluk eski, ama en kısa Python olduğu için bunu göndereceğimi düşündüm. Giriş, dizelerin bir listesidir, ancak kullanılan karakterler olağandışıdır.

> G
< B
v C
^ F
. L

Örneğin, üçüncü durma örneği dönüşür ['LLLLCLLLL', 'LLLLGLLLC', 'LFLLBLLLL', 'LLLLLLLCB', 'LLLLLLLCL', 'LLLLFLLBL']. Çıkış, çıkış kodu, durmayanlar için 0 (başarılı) ve durma için 1'dir (hata). Herhangi bir ipucu veya püf noktaları takdir etti.


2

Befunge-98 (PyFunge) , 217 209 200 bayt

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

Çevrimiçi deneyin!

Bir yangın durdurma durdurma problemi, bir befunge çözümüne ihtiyaç duyar. Truthy için 0, falsey için 1 döndürür. Girdiyi 1,15'den başlayarak ızgaraya yerleştirir ve sonra okları sıfırlarla değiştirerek üste doğru hareket eder. Bir sıfıra çarptığımızda, döngüler olduğunu biliyoruz. > <^ V dışında herhangi bir şey. ve sıfır, programın etrafına yerleştirdiğimiz alanların sınırlarını da içeren programın, ızgara üzerine hafifçe kaydırılarak yerleştirilmesidir.

Birkaç ısırıktan kurtulmanın kolay bir yolu> <^ v yerine sayı kullanmaktır. ama buna değdiğini sanmıyorum.


A befinge halting problem needs a befunge solution.Tam. +1
Draco18s

1

Turtlèd , 146 bayt

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

Bu program G / Ç'yi farklı şekilde alır: lütfen her satırı son satır da dahil olmak üzere bir boşlukla sonlandırın. Turtlèd, yeni karakterlerden hoşlanmaz, çünkü karakterlerin ikinci boyutu için bir ızgara kullanır.

Çevrimiçi deneyin!

Sonsuza kadar döngüler için 0, durdurmalar için 1.

Genel açıklama:

Girdiyi ızgaraya yazar, sonra gerçekte okların ızgara etrafında yaptığı yolu izler, her oku olduğu gibi bir * ile değiştirir, ayrıca char var de yönünü korur. Eğer daha önce * çarptığında bir okla karşılaşırsa, program durmaz, bu yüzden char değişkenini ayarlar 0, döngüden çıkar. Aksi takdirde, kılavuzun sonuna vuracak ve döngüden çıkacaktır. Char var yazacak. Izgara sonuna düştüğünde, ızgaraya geri dönmek için char var'da depolanan yönü kullanır ve 1durmalarda char var değerini ayarlar . Char var aslında 0 ise, bir yön değil, hala orada olduğu için geri dönmesi gerekmez ve onu tekrar ayarlar 0. Daha sonra karakter var dizininde, yazar, ızgara kapalı temizler 1başka, duraklamalara için 0.



1

JavaScript (ES6), 158 127 bayt

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

Girdiyi iki boyutlu bir karakter dizisi olarak alır ve truedurma ve falsesonsuz döngü için döndürür . Ziyaret edilen yön karakterlerini ~yinelenen şekilde geçtiğinde s olarak ayarlayarak çalışır . Düzenleme: özyinmeden önce yön vektörümü güncelleyerek kaydedilen 31 bayt.

Yönerge karakterlerini ( 1=^ 4=< 5=. 6=> 9=v) kötüye kullanmak beni 101 bayta indiriyor:

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

> Girişi iki boyutlu bir karakter dizisi olarak alır Farklı formatlanmış girişlere izin verilir mi? (düz bir diziden bir diziye gitmek de bayt alır).
zeplin

@zeppelin Benim inancım buna izin verildiğidir. Bkz meta.codegolf.stackexchange.com/q/2214/17602 mesela.
Neil

ReferenceError: f tanımlanmadı
l4m2

@ l4m2 Bah, yine yaptım f=, byte sayımına dahil ettim ancak kodu girmedim ...
Neil

1

SmileBASIC, 158 145 bayt

Aynı ok birden fazla kez karşılaşırsa, program hiç durmaz. Komut işaretçisi bir oku geçtiğinde, farklı bir sembolle değiştirilir, bu fonksiyona tekrar ulaşıldığında fonksiyonun 0 döndürmesini sağlar. IP sınırların dışına çıkarsa, 1 değerini döndürür.

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

Dizeleri bir dizi olarak girdi alır. <any non-digit chracter>, 1, 2, 3, 4= ., >, <, v,^


0

Python 2,182 bayt

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

Girdi olarak bir dize dizisi alır. Bunu daha çok golf oynamalıyım ama şimdilik seçim üzerinde baskı yapmanın zamanı geldi.

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

hey, ya ana bölümü denemenin dışına çıkardıysanız ve yalnızca c = m [y] [x] denemesine koyup koymuyorsanız? bu aynı zamanda, arayı 1/0 ile değiştirmenin yanı sıra girintileri azaltmanıza da izin verir.
Yıkılabilir Limon

1
[-1,1][d=='v'] -> 2*(d>'>')-1ve [-1,1][d=='>'] -> 2*(d>'<')-1toplam 6 bayt kaydedin.
Kade

Yanlış cevap["<>"]
feersum

0

Clojure, 143 bayt

#((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 durumlu argümanlara sahip bir fonksiyon: pozisyon p, hız v, adım indeksi ive bir çizginin büyüklüğü s. İade 1biz 10 ^ 9 adımlar ve de sınırların dışında gitmedi eğer nilaksi. Aslında emin olmak için kaç adım kontrol etmemiz gerekiyor (count %)? Sanırım aynı NOP yatay ve dikey olarak geçilebileceğinden daha fazlası.

Bu şekilde çağrılabilir (normal dizeleri argüman olarak alır , sınırların dışına çıktığında getdöner nil):

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

Durum geçişleri (+1, -1, + s, -s) sözlükte kodlanmıştır {\> 1\< -1\^(- s)\. v\v s}.


Izgara karakterlerinin sayısının 4 katı yeterli olmalıdır: imleç aynı gelen yöne sahip aynı karaktere geri dönerse, sonsuz bir döngüye girer.
Greg Martin

0

Python 2/3, 201 192 bayt

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

Çevrimiçi deneyin!

İçin doğru cevabı verir ["<>"]


Bir işlevden tam programa geçerek birkaç bayttan tasarruf edebileceğinizi düşünüyorum. Sen yerini alabilir def f(x):ile x=input()daha sonra yerini daha sonra, ekstra girinti (-8 bayt) kaldırmak, 0 bayt fark ile return xbirlikte exit(x)(başına izin meta konsensüs başka 2 byte için). Her neyse, güzel çözüm!
Amphibological

0

Java, 477

Bunun kazanmadığını biliyorum, n = ve muhtemelen daha fazla golf oynayabilir, ancak diğer cevapların kullandıklarına benzer bir yöntem uygular, ancak bu arama yapmak için hashpa kullanır. Giriş,> <^ v sembollerini ve no op için olandan başka bir şey kullanıyor. Girdi argümanlardan geliyor.

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

UNGOLFED

java.util dosyasını içe aktarın. *;

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

Açıklama çok yakında!


Bir küçük şey: değiştirebileceğiniz String a[]için String[]ave uzay ihmal.
Esolanging Fruit

Ayrıca kullanabilirsiniz varJava 10 kullanıyorsanız birçok yerde .
Esolanging Fruit

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.