Ein Brainfuck-Derivat
Definieren wir eine einfache Brainfuck- ähnliche Programmiersprache. Es verfügt über ein bidirektionales Zellenband, und jede Zelle enthält ein Bit. Alle Bits sind anfänglich 0. Auf dem Band befindet sich ein sich bewegender Kopf, der sich anfänglich an Position 0 befindet. Ein Programm ist eine Zeichenfolge über den Zeichen <>01!
, die von links nach rechts mit der folgenden Semantik ausgeführt wird:
<
bewegt den Kopf einen Schritt nach links.>
bewegt den Kopf einen Schritt nach rechts.0
setzt 0 in die aktuelle Zelle.1
setzt 1 in die aktuelle Zelle.!
Kippt die aktuelle Zelle.
Da es keine Schleifen gibt, endet ein Programm mit n Zeichen nach genau n Schritten. Ein Programm ist langweilig, wenn alle Zellen am Ende der Ausführung 0 enthalten, und aufregend, wenn mindestens eine 1 vorhanden ist. Beachten Sie, dass die Größe des Bandes nicht angegeben ist. Je nach Implementierung kann sie also in beide Richtungen unendlich oder unendlich sein kreisförmig.
Ein Beispielprogramm
Betrachten Sie das Programm 1>>>!<<<<0>!>>>!
. Auf einem unendlichen Band läuft die Ausführung wie folgt ab:
v
00000000000000 Put 1
v
00000100000000 Move by >>>
v
00000100000000 Flip
v
00000100100000 Move by <<<<
v
00000100100000 Put 0
v
00000100100000 Move by >
v
00000100100000 Flip
v
00000000100000 Move by >>>
v
00000000100000 Flip
v
00000000000000
Am Ende sind alle Zellen 0, daher ist dieses Programm langweilig. Lassen Sie uns nun dasselbe Programm auf einem kreisförmigen Band der Länge 4 ausführen.
v
0000 Put 1
v
1000 Move by >>>
v
1000 Flip
v
1001 Move by <<<< (wrapping around at the edge)
v
1001 Put 0
v
1000 Move by > (wrapping back)
v
1000 Flip
v
0000 Move by >>>
v
0000 Flip
v
0001
Dieses Mal gibt es eine Zelle mit dem Wert 1, das Programm ist also aufregend! Wir sehen, ob ein Programm langweilig oder aufregend ist, hängt von der Größe des Bandes ab.
Die Aufgabe
Ihre Eingabe ist eine nicht leere Zeichenfolge <>01!
, die ein Programm in der obigen Programmiersprache darstellt. Ein Array von Zeichen ist auch ein akzeptables Eingabeformat. Das Programm ist garantiert langweilig, wenn es auf einem endlosen Band abgespielt wird. Ihre Ausgabe soll die Liste der Bandlängen sein, auf denen das Programm spannend ist. Beachten Sie, dass Sie das Programm nur auf Bändern testen müssen, die kürzer als die Programmlänge sind.
Die Lösung mit der niedrigsten Byteanzahl in jeder Sprache ist der Gewinner. Es gelten die Standardregeln für Code-Golf .
Testfälle
> : []
110 : []
1>0<! : [1]
0>>1>0<<>! : [1]
1>>>!<<<<0>!>>>! : [2, 4]
!<!<><<0>!>!<><1!>>0 : [2]
>>!>><>001>0<1!<<!>< : [1, 2, 3]
1!><<!<<<!!100><>>>! : [1, 3]
!!1>!>11!1>>0<1!0<!<1><!0<!<0> : [3, 4]
<><<>>!<!!<<<!0!!!><<>0>>>>!>> : [1, 2, 4]
0>>><!<1><<<0>!>>!<<!!00>!<>!0 : [3]
0000!!!!><1<><>>0<1><<><<>>!<< : []
!>!>!>!>!>1>!>0<!<!<!<0<!<0<!<!<!<1>!>0<<! : [1, 2, 5, 7]
<!!>!!><<1<>>>!0>>>0!<!>1!<1!!><<>><0<<!>><<!<<!>< : [1, 2, 4, 5]
!>1<<11<1>!>!1!>>>0!!>!><!!00<><<<0<<>0<<!<<<>>!!> : [1, 2, 3, 5, 6]
<>01!
?Antworten:
Haskell, 119 Bytes
Probieren Sie es online!
Function
#
ist der Interpreter für einen einzelnen Befehlc
. Das gesamte Programmp
wird durch laufenfold
ing#
mit dem Startband inp
.f
wirdp
für jedes Band ausgeführt und behält diejenigen bei, bei denen die Summe der Zellen mindestens 1 beträgt.quelle
n<-[1..length p] ... 0<$[1..n]
scheint ziemlich lang zu sein, es muss einen kürzeren Weg geben.n
als Ergebnis benötigen. Wenn Sie also0<$[1..n]
einen anderen Weg konstruieren (sagen wir mitscanr(:)
), müssen Sie denlength
davon nehmen. (Ich habe auch versucht,1
(zu ersetzenlength
durchsum
) oderFalse
(or
für den Test zu verwenden)0
, aber es kam nicht kürzer heraus.)n<-init$scanr(:)[]$0<$p ... n
die 2 Bytes kürzer ist, aber es gibt eine Liste der Startbänder anstelle ihrer Länge zurück, z[[0],[0,0,0]]
. Mit ein bisschen Regelbiegen könnten die Bänder also als unäre Zahlen angesehen werden, also ist es vielleicht ok.init$
kann durch eine[0]
erste Liste ersetzt werden, wurde aber immer noch nicht kurz genug. Ich denke, Unary ist nur für Sprachen ohne eine natürlichere Zahlendarstellung zulässig .Stax ,
5654433835 Bytes CP43742 Bytes beim Auspacken,
Online ausführen und debuggen!
-2 Bytes pro Kommentar von @recursive
Erläuterung
Ich werde die Version mit einem Präfix
i
(dhi%fz(y{{|(}{|)}{B!s+}{0_]e&}4ls"><! "I@!F|a
) verwenden, um zu erklären, warum dasi
entfernt werden kannCode zum Ausführen des Programms:
quelle
i
Scheck zu validieren .0]*
kann durch ersetzt werdenz(
. Auch, wenn Sie die Zeichenfolge ändern „<>“, dann0
und1
geben Index -1, so dass Art und Weise Ihre Sperrliste nur 4 Blöcke benötigt, statt 5. dies funktionieren wird , da die0
und1
Handler identisch ohnehin sind.CJam ,
57564946 Bytes-7 danke an @MartinEnder
Probieren Sie es online!
quelle
Perl 5 ,
83827977 BytesEnthält
+3
für-F
Geben Sie Anweisungen als eine Zeile auf STDIN
Probieren Sie es online!
quelle
Perl 5 (
-F
), 101 BytesProbieren Sie es online!
quelle
Rot , 243 Bytes
Probieren Sie es online!
Sehr ausführlich und unkompliziert. Mit der 1-Indizierung von Red kann ich die Byteanzahl nicht reduzieren, indem ich eine modulare Arithmetik zum Durchlaufen der kreisförmigen Bänder verwende.
Ungolfed
quelle
Python 2 ,
139135133132131 Bytes-3 Bytes dank Herrn Xcoder
Probieren Sie es online!
quelle
Retina , 121 Bytes
Probieren Sie es online! Erläuterung:
Erstellen Sie ein Array von Bändern jeder Länge bis zur Länge des Eingabeprogramms.
Schleife, bis das Programm verbraucht ist.
Wenn das nächste Zeichen im Programm eine 0 oder 1 ist, ändern Sie das erste Zeichen in jeder Zeile in dieses Zeichen.
Wenn es sich um ein handelt,
!
schalten Sie das erste Zeichen in jeder Zeile um.Wenn es ein
>
oder<
ist, drehen Sie die Linie. (Einfacher als den Kopf zu bewegen.)Löschen Sie die Anweisung und beenden Sie die Schleife.
Behalte nur die aufregenden Linien.
Zählen Sie die Länge jeder Zeile.
quelle
JavaScript (ES6),
126118 Byte3 Bytes gespart dank @ user71546
Nimmt die Eingabe als Array von 1-Zeichen-Zeichenfolgen.
Probieren Sie es online!
quelle
t.some(x=>x)?
durch,+t.join``?
überprüfen Sie das Array stattdessen als Ziffern (und 0 zeigt ein Band mit Nullen an), aber 3 Bytes weniger.APL (Dyalog Unicode) ,
796454 Byte ( Adáms SBCS )Probieren Sie es online!
-15 Dank an Adám (vergessen über Monade
⍸
).-10 danke an ngn .
quelle
↓
). Ich werde es überprüfen und aktualisieren. :)↓
entfernst, brauchst du ein;
, nein?MATL ,
4639 BytesProbieren Sie es online! Oder überprüfen Sie alle Testfälle .
Wie es funktioniert
quelle
APL (Dyalog Unicode) ,
19278 BytesProbieren Sie es online! (nicht abgeflachtes Ergebnis)
Probieren Sie es online! (abgeflacht)
Nachdem ich einige Zeit damit verbracht hatte, meinen Kopf gegen die Wand zu schlagen, entschloss ich mich, einen Tradfn anstelle eines Dfn zu machen. Das ist das Ergebnis. Klügere Leute als ich sind vielleicht in der Lage, daraus Golf zu spielen.Überraschung, Überraschung, jemand, der schlauer als ich war, hat das zum Teufel gemacht. Vielen Dank, dass Sie Adám für 114 Bytes.
Er sagte:
Die Funktion übernimmt
⎕IO←0
.Wie?
(Diese Erklärung verwendet eine "ungolfed" Version, um das Lesen zu erleichtern)
quelle
t←l⍴0
be erstellent←l⍴i←0
und die darüber stehende Zeile entfernen. Sie können andere auch sparen , indem Siet[i|⍨≢t]←1-t[i|⍨≢t]
auft[i|⍨≢t]←~t[i|⍨≢t]
.∇
?∇
? Es ist eine stillschweigende Funktion.Jelly , 41 Bytes
Probieren Sie es online!
quelle
C (clang) 171 Bytes
Probieren Sie es online!
Musste clang verwenden, da die Verwendung
char*p,t[l=strlen(S)]
als Initialisierungsausdruck aus irgendeinem Grund GCC denken lässt, dass ich deklarieren möchte,strlen
anstatt es aufzurufen.Ganz einfach: Führt das Programm auf kreisförmigen Bändern mit abnehmender Länge aus und gibt eine beliebige Länge aus, die irgendwo auf dem Band zu einer 1 führte.
Versuchte, das Gewirr der ternären Operatoren zu verkürzen, benötigte jedoch mehr Klammern als gesund.
quelle
i=0,bzero(t,l)
anstelle vonmemset(t,i=0,l)
und*p-62?t[i]=*p^33?*p-48:t[i]^1:(i=~i+l?i+1:0)
anstelle von*p==62?i=i^l-1?i+1:0:*p^33?t[i]=*p-48:(t[i]^=1)