Die Idee hier ist, ein sich fast wiederholendes Muster zu erzeugen . Das heißt, die zu konstruierende Sequenz ändert sich im letzten Moment, um eine Wiederholung einer Teilsequenz zu vermeiden. Folgen vom Typ AA und ABA sind zu vermeiden (wobei B nicht länger als A ist).
Beispiele:
Ich werde zunächst alle kleinen Beispiele auflisten, um meine Beschreibung klarer zu machen. Beginnen wir mit 0.
Gültig: 0 Ungültig: 00 (AA-Muster) Gültig: 01 Ungültig: 010 (ABA-Muster) Ungültig: 011 (AA-Muster) Gültig: 012 Gültig: 0120 Ungültig: 0121 (ABA-Muster) Ungültig: 0122 (AA-Muster) Ungültig: 01200 (AA-Muster) Ungültig: 01201 (ABA-Muster; 01-2-01) Ungültig: 01202 (ABA-Muster) Gültig: 01203
Jetzt glaube ich fest daran, dass a 4
niemals benötigt wird, obwohl ich keinen Beweis habe, weil ich leicht Sequenzen mit Hunderten von Zeichen gefunden habe, die nur verwendet werden 0123
. (Es hängt wahrscheinlich eng damit zusammen, wie nur drei Zeichen benötigt werden, um unendliche Zeichenfolgen zu haben, die keine AA-Muster haben. Es gibt eine Wikipedia-Seite dazu.)
Input-Output
Die Eingabe ist eine einzelne positive Ganzzahl ungleich Null n
. Sie können das annehmen n <= 1000
.
Die Ausgabe ist eine n
Zeichenfolge ohne Teilsequenzen, die mit einem der verbotenen Muster (AA oder ABA) übereinstimmen.
Beispiel für Ein- und Ausgänge
>>> 1 0 >>> 2 01 >>> 3 012 >>> 4 0120 >>> 5 01203 >>> 50 01203102130123103201302103120132102301203102132012
Regeln
- Nur die Zeichen
0123
sind erlaubt. - B ist nicht länger als A. Dies dient dazu, die Situation zu vermeiden, in der
012345
gefolgt werden muss,6
weil0123451
dies :1-2345-1
. Mit anderen Worten, die Sequenz wäre trivial und uninteressant. n
kann durch jedes gewünschte Verfahren eingegeben werden, außer durch Hardcodierung.- Die Ausgabe kann entweder eine Liste oder eine Zeichenfolge sein, je nachdem, was einfacher ist.
- Keine rohe Gewalt ; Die Laufzeit sollte in der Größenordnung von Minuten liegen, höchstens eine Stunde auf einer sehr langsamen Maschine, z
n=1000
. (Dies soll Lösungen disqualifizieren, die nur allen
Permutationen von Länge durchlaufen{0,1,2,3}
, so dass Tricks und ähnliche Tricks nicht erlaubt sind.) - Standardschlupflöcher sind wie üblich nicht zulässig.
- Die Bewertung erfolgt in Bytes. Dies ist Code-Golf , also gewinnt der kürzeste Eintrag (wahrscheinlich - siehe Bonus).
- Bonus: Wählen Sie bei jedem Schritt die niedrigste zulässige Ziffer. Wenn
1
und3
für die nächste Ziffer in der Sequenz eine Auswahl möglich ist, wählen Sie1
. Subtrahieren Sie 5 Bytes von Ihrer Punktzahl. Beachten Sie jedoch den folgenden Hinweis.
Hinweis!
Sackgassen sind möglich. Ihr Programm oder Ihre Funktion muss diese vermeiden. Hier ist ein Beispiel:
Stumpf: 0120310213012310320130210312013210230120310213201230210312013023103201230213203102301203210231201302103123013203102130120321023013203123021032012310213012012 Stumpf: 0120310213012310320130210312013210230120310213201230210312013023103201230213203102301203210231201302103123013203102130120321023013203123021032012330212012 Stumpf: 01203102130123103201302103120132102301203102132012302103120130231032012302132031023012032102312013021031230132031021301203210230132031230210320123103303203 Stumpf: 012031021301231032013021031201321023012031021320123021031201302310320123021320310230120321023120130210312301320310213012032102301320312302103201233021203103
Jede dieser Sequenzen kann nicht weiter erweitert werden (ohne Verwendung von a 4
). Beachten Sie aber auch, dass es einen entscheidenden Unterschied zwischen den ersten beiden und den zweiten beiden gibt. Ich werde die gemeinsame anfängliche Teilsequenz durch eine ersetzen X
, um dies klarer zu machen.
Stumpf: X2130120 Stumpf: X2130123 Stumpf: X320 Stumpf: X321301203102130
Die letzten beiden Ziffern von X
sind 10
, daher sind und die einzig mögliche Auswahl für die nächste Ziffer 2
und 3
. Die Auswahl 2
führt zu einer Situation, in der die Sequenz beendet werden muss . Der Greedy - Algorithmus wird nicht hier arbeiten. (Jedenfalls nicht ohne Rückverfolgung.)
quelle
n
? Wenn jemand einen heuristischen semi-gierigen Algorithmus gibt, wie können Sie dann überprüfen, ob er über eine sehr große Länge nicht auf Probleme stößt? Das allgemeine Problem ist interessant, und ich konnte nichts zur Vermeidung von Mustern finden, bei dem wir die Länge eines Teils des Musters einschränken. Wenn jemand ein allgemeines Rezept erstellen kann, erwarte ich, dass dies der beste Ansatz ist.n
, aber da die Stümpfe, die mein Programm findet, jedes Mal um durchschnittlich 10 Stellen länger werden, bin ich mir sehr sicher, dass es eine unendliche Folge gibt. Ich bin mir nicht sicher, wie ein semi-gieriger Algorithmus für beliebig große Sequenzen getestet werden könnte. Ich könnte die Anforderung aufn
= 1000 beschränken und mir keine Sorgen um höhere machenn
.AA
ist wirklich Typ,ABA
woB
leer ist. Dies könnte möglicherweise dazu beitragen, einige Lösungen zu optimieren.Antworten:
Netzhaut , 86 Bytes - 5 = 81
Wobei
<empty>
eine leere nachfolgende Linie steht. Sie können den obigen Code aus einer einzelnen Datei mit dem-s
Flag ausführen .Die Eingabe sollte unär erfolgen , z
111111
. Ich habe es noch nicht auf Ausgabe in der Größenordnung von Tausenden getestet - zwei der regulären Ausdrücke werden nach einer Weile möglicherweise etwas langsam -, aber es kann problemlos ein paar Hundert in wenigen Sekunden verarbeiten.Erläuterung
Dies ist eine einfache Backtracking-Lösung.
0
.3
.Dieses Backtracking wird durch eine Schleife von Regex-Ersetzungen implementiert, die abgebrochen wird, sobald die Zeichenfolge durch eine Iteration unverändert bleibt.
Dies hängt ein
_
an die Eingabe an, mit der die unäre Eingabe von der Sequenz getrennt wird, die wir erstellen.Dies ist die erste Ersetzung in der Schleife (angezeigt durch die führende
(
). Die Regex stimmt überein, wenn a) am Ende der Zeichenfolge ein Wortzeichen (dh eine Ziffer) steht (was bedeutet, dass die Zeichenfolge gültig ist - wir werden unten sehen, dass ungültige Sequenzen mit einem nachgestellten Zeichen gekennzeichnet sind#
) und b) mindestens vorhanden ist so viele Zeichen in der Sequenz wie in der Eingabe (dies wird mithilfe von Ausgleichsgruppen überprüft ). In diesem Fall entfernen wir die Eingabe und fügen a hinzu!
. Dies!
dient dazu, dass alle regulären Ausdrücke in der Schleife fehlschlagen, sodass sie beendet werden.Wenn am Ende ein Wortzeichen steht (dh die Sequenz ist gültig und die Schleife wurde im vorherigen Schritt nicht beendet), fügen Sie a hinzu
0
.Wenn (stattdessen) die Sequenz als ungültig markiert wurde und mit endet
3
, entfernen wir diese3
(lassen die Sequenz jedoch als ungültig, da für das aktuelle Präfix keine Fortsetzung möglich ist ... daher muss auch das nächste Zeichen zurückverfolgt werden).Wenn die Sequenz als ungültig markiert ist und eine andere Ziffer als
3
am Ende steht, erhöhen wir die Ziffer und entfernen die Markierung.Die letzte Ersetzung in der Schleife (wie durch angezeigt
)
). Es wird geprüft, ob die Zeichenfolge endetABA
(wobei sieB
nicht länger als,A
aber möglicherweise leer ist). Die relativen Längen vonA
undB
werden erneut unter Verwendung von Ausgleichsgruppen überprüft, und die Wiederholung vonA
wird mit einer einfachen Rückreferenz überprüft.Wenn dieser reguläre Ausdruck übereinstimmt, markieren wir die Sequenz durch Anhängen als ungültig
#
.Sobald die Schleife beendet ist, müssen wir nur noch die entfernen
!
und dann die gewünschte Ausgabe erhalten.quelle
Python 2, 175 - 5 = 170 Bytes
Dies ist der gierige Algorithmus mit Backtracking. Ich wünschte, es wäre kürzer. Ich hoffe es ist richtig (siehe unten).
Die Zeichenfolge wird ziffernweise erstellt. Bei einer
d
bereits gefundenen Ziffernfolge wird versucht, a0
als(d+1)
erste Ziffer anzuhängen . Wenn das nicht funktioniert, versucht es a1
, dann a2
, dann a3
. Wenn keines davon funktioniert, kehrt es zurd
dritten Ziffer zurück und erhöht sie (wenn kleiner als3
) oder entfernt sie (wenn gleich3
, in diesem Fall erhöht es die vorherige usw.).Die Gültigkeitsprüfung ist die Zeile mit
.find
. Falls sich jemand entscheidet, meinen Code zu lesen, sollte ich sagen, dass dieses Programm die Zeichenfolge tatsächlich rückwärts speichert, was bedeutet, dass es Ziffern nach vorne hinzufügt . Bei der Prüfung wird also nach Stellen gesucht, an denen die erstenc
Ziffern später in der Zeichenfolge erneut angezeigt werden (irgendwo nach den erstenc
Ziffern), und wenn es solche Stellen gibt, ob die dazwischen liegende Länge höchstens istc
.(Natürlich wird die Zeichenfolge vor dem Drucken umgekehrt.)
Es könnte auch leicht schneller sein; Ich hatte ursprünglich verschiedene Schleifen aus Effizienzgründen frühzeitig verlassen, aber das kostete wertvolle Bytes. Im Bereich von
n=1000
ist es jedoch immer noch in Ordnung .Wie auch immer, das Programm scheint eine Präferenz für die kleineren Ziffern aufzuweisen, aber es ist keine sehr starke Präferenz. Wenn
n=2000
ich es zum Beispiel mit laufen ließ, erhielt ich eine Zeichenfolge mit523
Nullen,502
Einsen,497
Zweien und478
Dreien, die mit endete30210312013021
. Wenn also jemand anderes an einem gierigen Algorithmus arbeitet, kann er dieses Ergebnis möglicherweise bestätigen. Oder mit haben=1000
ich[263, 251, 248, 238]
für die Zählungen nach Ziffern.Abschließend möchte ich erwähnen, dass diese Zählungen auf Symmetrie hindeuten, fast (wenn auch nicht genau), als hätten wir mit einer gleichmäßigen Verteilung begonnen und dann einige der
3
's in0
' s und einige der2
's in1
' umgewandelt. s. Aber das könnte natürlich nur Zufall sein. Ich habe keine Ahnung!quelle
Haskell, 115 (120 Bytes - 5 Bonus)
Laufen Sie online bei Ideone
Beispiellauf:
quelle