Risolvi il problema dell'arresto per Befinge


29

Definiamo un semplice linguaggio 2D, che daremo il nome incredibilmente originale befinge . Befinge ha 5 istruzioni:

  • <>^v, come nella maggior parte degli esolang 2D, reindirizzare il puntatore dell'istruzione nelle rispettive direzioni.
  • . è una no-op.

Il puntatore dell'istruzione inizia nell'angolo in alto a sinistra andando a destra. Se il puntatore dell'istruzione raggiunge un limite, il programma si arresta. Ovviamente ogni programma Befinge si fermerà o entrerà in un ciclo infinito che non fa nulla. Ecco due esempi:

arrestare:

>.v
..<

Non-Halting:

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

Il problema dell'arresto non è risolvibile per un linguaggio completo di Turing, ma è per questo. Il tuo compito è scrivere un programma (o una funzione) che accetta come input una stringa che rappresenta il programma befinge e restituisce un valore di verità o falsità a seconda che si interrompa o meno.

  • Si può presumere che l'input consisterà solo di questi caratteri e sarà riempito con spazi per formare un rettangolo.
  • È possibile utilizzare qualsiasi set di cinque caratteri per le istruzioni (ad es adws .).

Casi test

arrestare:

.

v>
>^

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

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

Non-Halting:

>..v
^..<

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

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

Questo è , quindi vince il programma più breve (in byte).


Che dire di 아희 (Aheui) ?
JungHwan Min

Alcuni casi di test in cui non viene colpita ogni freccia sarebbero buoni.
xnor

Turing ha dimostrato che il problema di Halting non è risolvibile per nessun linguaggio Turing-Complete, quindi ho dovuto inventarne uno falso che non fosse completo. Un linguaggio che alla fine si fermerà sempre non è Turing completo.
Esolanging Fruit

1
Inoltre non abbiamo esempi in cui il percorso comporti una virata di non-90 gradi come >..>.o ><.
xnor

2
@PyRulez Perché volevo che l'elaborazione del movimento direzionale facesse parte della sfida.
Esolanging Fruit

Risposte:


4

ES6 (JavaScript), 111, 101 byte

EDIT: ha cambiato i valori di output in true e false , anziché in Y e N , per radere di 10 byte in più

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

Test

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

Uscita campione

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

Non puoi semplicemente usare Ye Ncome output come in JavaScript sono entrambi veri .
ბიმო

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

Provalo online!

La sfida è vecchia, ma ho pensato che dato che questo è il Python più corto, lo posterò. L'input è un elenco di stringhe, ma i caratteri utilizzati sono insoliti.

> G
< B
v C
^ F
. L

Ad esempio, il terzo esempio di arresto si trasforma in ['LLLLCLLLL', 'LLLLGLLLC', 'LFLLBLLLL', 'LLLLLLLCB', 'LLLLLLLCL', 'LLLLFLLBL']. L'uscita avviene tramite il codice di uscita, 0 (successo) per non-stop e 1 (errore) per-stop. Eventuali suggerimenti o trucchi apprezzati.


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

Provalo online!

Un problema di arresto befinge richiede una soluzione befunge. Restituisce 0 per verità e 1 per falsità. Mette l'input sulla griglia a partire da 1,15 e quindi si sposta in alto, sostituendo le frecce con zeri. Non appena raggiungiamo uno zero, sappiamo che si verificano dei loop. Qualsiasi cosa oltre> <^ v. e si considera zero per arrestare il programma, che include il bordo degli spazi che aggiriamo il programma posizionandolo sulla griglia leggermente sfalsato.

Un modo semplice per eliminare alcuni morsi sarebbe usare i numeri invece di> <^ v. ma non credo che ne valga la pena.


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

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

Questo programma prende l'I / O in modo diverso: terminare ogni riga con uno spazio, incluso l'ultimo. A Turtlèd non piacciono le newline, poiché usa una griglia per la sua seconda dimensione di personaggi.

Provalo online!

0 per i loop per sempre, 1 per gli arresti.

Spiegazione generale:

Scrive l'input sulla griglia, quindi in realtà segue il percorso che le frecce fanno intorno alla griglia, sostituendo ciascuna freccia con un * mentre procede, salvando anche la direzione nel carattere var. Se incontra un *, una freccia che ha colpito prima, il programma non si fermerebbe, quindi imposta il carattere var su 0, esce dal ciclo. Altrimenti, colpirà la fine della griglia e uscirà dal circuito. Scriverà il carattere var. Se ha colpito la fine della griglia, utilizza la direzione memorizzata nel carattere var per tornare alla griglia e imposta il carattere var su 1, per gli arresti. Se il char var era effettivamente 0, non una direzione, non è necessario tornare indietro, poiché è ancora lì e lo reimposta su 0. Cancella la griglia, quindi scrive il carattere var, 1per fermarsi, altro 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

Prende input come una matrice di caratteri bidimensionali e ritorna trueper l'arresto e falseper un ciclo infinito. Funziona impostando i caratteri di direzione visitati su ~s mentre li attraversa in modo ricorsivo. Modifica: salvato 31 byte aggiornando il mio vettore di direzione prima di ricorrere.

Abusare dei caratteri di istruzione ( 1=^ 4=< 5=. 6=> 9=v) mi porta a 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

> Accetta input come array di caratteri bidimensionali È consentito un input formattato diversamente? (passare da una stringa piatta a un array richiede anche byte).
Zeppelin,

@zeppelin La mia convinzione è che questo sia permesso. Vedi ad esempio meta.codegolf.stackexchange.com/q/2214/17602 .
Neil,


@ l4m2 Bah, l'ho fatto di nuovo, ho incluso il f=conteggio dei byte ma non il codice ...
Neil

1

SmileBASIC, 158 145 byte

Se la stessa freccia viene rilevata più di una volta, il programma non si arresterà mai. Quando il puntatore dell'istruzione passa una freccia, viene sostituito con un simbolo diverso, che restituirà la funzione 0 se viene raggiunta di nuovo. Se l'IP supera i limiti, restituisce 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

Accetta input come una matrice di stringhe. <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

Accetta un array di stringhe come input. Devo giocare a golf di più, ma per ora è il momento di stressarmi per le elezioni.

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

ehi, cosa succederebbe se togliessi la parte principale dal tentativo e metti solo c = m [y] [x] in un tentativo e tranne? ciò consentirebbe anche di sostituire l'interruzione con 1/0, oltre a ridurre i rientri.
Limone distruttibile

1
[-1,1][d=='v'] -> 2*(d>'>')-1e [-1,1][d=='>'] -> 2*(d>'<')-1salva un totale di 6 byte.
Kade,

Risposta errata per["<>"]
feersum

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

Una funzione con 4 argomenti di stato: posizione p, velocità v, indice di passo ie dimensione di una riga s. Restituisce 1se non siamo andati oltre i limiti in 10 ^ 9 passaggi e nilaltrimenti. In realtà quanti passaggi dobbiamo controllare per essere sicuri (count %)? Penso che sia più di questo dato che lo stesso NOP può essere attraversato in senso orizzontale e verticale.

Può essere chiamato in questo modo (accetta stringhe normali come argomenti, getrestituisce nilquando è fuori limite):

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

Le transizioni di stato (+1, -1, + s, -s) sono codificate nel dizionario {\> 1\< -1\^(- s)\. v\v s}.


4 volte il numero di caratteri della griglia dovrebbe essere sufficiente: se il puntatore ritorna allo stesso carattere con la stessa direzione in entrata, si trova in un ciclo infinito.
Greg Martin,

0

Python 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

Provalo online!

Fornisce una risposta corretta per ["<>"]


Credo che puoi salvare diversi byte passando da una funzione a un programma completo. È possibile sostituire def f(x):con una x=input()differenza di 0 byte, quindi rimuovere il rientro aggiuntivo (-8 byte), quindi sostituire return xcon exit(x)(consentito per meta consenso ), per altri 2 byte. Comunque, bella soluzione!
Anfibologico,

0

Java, 477

So che questo non sta vincendo, n = e probabilmente può essere giocato di più, ma impianta un metodo simile a quello che usano le altre risposte, ma questo usa l'hashmap per eseguire le ricerche. L'input utilizza i simboli> <^ v e qualsiasi cosa diversa da quella per il no op. L'input arriva attraverso 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);}}

UNGOLFED

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

Spiegazione in arrivo!


Una piccola cosa: si può cambiare String a[]per String[]ae omettere lo spazio.
Esolanging Fruit

Puoi anche usarlo varin molti posti se usi Java 10.
Esolanging Fruit

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.