Angenommen, Sie binden einen Strang Froot Loops für eine Halskette, ein Armband, einen Schnürsenkel oder was auch immer. Es gibt 6 Schleife Farben: r ed, O - Bereich, y ellow, g reen, b lue und p urple. Sie möchten, dass Ihr Faden ganz links mit Rot beginnt und in der Reihenfolge des Regenbogens nach rechts läuft und mit Lila endet. Das heißt, Sie möchten es so machen, dass Ihr Strang durch die Zeichenfolge dargestellt wird, die roygbp
einige Male wiederholt wird (möglicherweise 0).
Das Problem ist, dass Sie Ihre Loops bereits aufgereiht haben und nicht in einer bestimmten Reihenfolge. Welche Schleifen sollten Sie essen und nicht essen, damit Sie die Anzahl der richtigen Regenbogenzyklen von links nach rechts maximieren können, mit der allerersten Schleife in Rot und der allerletzten Schleife in Lila?
Schreiben Sie ein Programm oder eine Funktion, die eine beliebige Zeichenfolge einliest roygbp
und eine Zeichenfolge mit der gleichen Länge ausgibt oder zurückgibt, e
anstelle der zu essenden und n
anstelle der nicht zu essenden Schleifen.
Zum Beispiel, wenn Ihr Froot Loop-Strang so aussah
die Eingabe wäre
gorboypbgbopyroybbbogppbporyoygbpr
und von links nach rechts finden wir 3 komplette roygbp
Regenbogensequenzen, aber einige der Schleifen müssen weg gegessen werden. Damit wäre die Ausgabe
eenenneennenennneeeeneennenennnnne
Das Ergebnis ist ein perfekter Strang mit 3 Zyklen:
Wenn der Eingang keine vollständigen Regenbogenzyklen enthält, ist der Ausgang alles e
und der Strang endet schleifenlos. zB der Eingang proygb
hat Ausgang eeeeee
. Umgekehrt proygbp
hat ausgegeben ennnnnn
.
Sie können davon ausgehen, dass alle Eingangsstränge mindestens eine Schleife haben.
Der kürzeste Code in Bytes gewinnt.
r
oder könnteoygbproygbpr
er sich auch qualifizieren?Antworten:
Pyth, 31 Bytes
Unglaublich ineffizient, Erklärung folgt in Kürze.
yUlz
generiert alle möglichen Teilmengen aller möglichen Indizes vonz
(der Eingabe) in der angegebenen Reihenfolge. ZB wenn die Eingabe istabc
:Dann
hf!
findet man das ersteT
in der obigen Liste so, dass:jk.DzT"roygbp"k
es falsch ist..D
Nimmt einen String und eine Liste von Indizes und löscht die Elemente an diesen Indizes. So.D"abcd",1 3
ist es auch"ac"
. Da.D
eine Liste zurückgegeben wird (was in zukünftigen Versionen von Pyth nicht der Fall sein sollte), verwende ichjk
(k
is""
), um sie wieder zu einem String zusammenzufügen. Der:_"roygbp"k
Teil ersetzt jede Instanz eines Zyklus durch die leere Zeichenfolge.Da die leere Zeichenkette falsch ist, erklären die obigen Absätze, wie ich die kleinste Menge von Indizes finde, die zum Essen benötigt werden, um eine Zeichenkette zu erhalten, die nur aus Zyklen besteht.
:*lz\n_\e
verwandelt dann diese Liste von Indizes in einennnneeennene
Zeichenfolge.quelle
Hexagony ,
920722271 BytesSechs verschiedene Arten von Fruchtschleifen, sagst du? Dafür wurde Hexagony gemacht .
Okay, das war es nicht. Oh Gott, was habe ich mir angetan ...
Dieser Code ist jetzt ein Sechseck mit der Seitenlänge 10 (es begann bei 19). Es könnte wahrscheinlich noch ein bisschen mehr Golf gespielt werden, vielleicht sogar bis zur Größe 9, aber ich denke, dass meine Arbeit hier erledigt ist einen Befehl von einem Kreuzungspfad aus ausführen).
Trotz der offensichtlichen Linearität ist der Code tatsächlich zweidimensional: Hexagony ordnet ihn in ein reguläres Sechseck um (dies ist auch gültiger Code, in Hexagony sind jedoch alle Leerzeichen optional). Hier ist der entfaltete Code in all seinen ... nun, ich möchte nicht "Schönheit" sagen:
Erläuterung
Ich werde nicht einmal versuchen, alle verworrenen Ausführungspfade in dieser Golf-Version zu erklären, aber der Algorithmus und der gesamte Kontrollfluss sind identisch mit dieser nicht Golf-Version.
Ehrlich gesagt, im ersten Absatz habe ich nur einen halben Scherz gemacht. Die Tatsache, dass es sich um einen Zyklus von sechs Elementen handelt, war tatsächlich eine große Hilfe. Das Speichermodell von Hexagony ist ein unendliches hexagonales Gitter, bei dem jede Kante des Gitters eine vorzeichenbehaftete Ganzzahl mit willkürlicher Genauigkeit enthält, die auf Null initialisiert ist.
Hier ist ein Diagramm des Layouts des Speichers, den ich in diesem Programm verwendet habe:
Das lange gerade Bit auf der linken Seite wird als 0-terminierte Zeichenfolge
a
beliebiger Größe verwendet, die dem Buchstaben r zugeordnet ist . Die gestrichelten Linien der anderen Buchstaben repräsentieren die gleiche Art von Struktur, jede um 60 Grad gedreht. Zu Beginn zeigt der Speicherzeiger auf die mit 1 bezeichnete Kante in Richtung Norden.Das erste, lineare Bit des Codes setzt den inneren "Stern" der Kanten auf die Buchstaben
roygbp
sowie die Anfangskante auf1
, sodass wir wissen, wo der Zyklus endet / beginnt (zwischenp
undr
):Danach sind wir wieder am Rande mit der Bezeichnung 1 .
Nun lautet die allgemeine Idee des Algorithmus wie folgt:
e
in der Ecke mit der Aufschrift ? , denn solange der Zyklus nicht abgeschlossen ist, müssen wir davon ausgehen, dass wir auch diesen Charakter essen müssen. Danach bewegen wir uns im Ring zum nächsten Zeichen im Zyklus.e
s im ? Kanten mitn
s, weil wir jetzt wollen, dass dieser Zyklus an der Kette bleibt. Dann fahren wir mit dem Drucken von Code fort.e
und unterscheiden könnenn
). Dann suchen wir nach der 1 Kante (um den Rest eines möglicherweise unvollständigen Zyklus zu überspringen), bevor wir ebenfalls zum Drucken von Code übergehen.e
für jedes Zeichen eine gedruckt wird . Dann bewegt es sich zum ? Kante, die dem Zeichen zugeordnet ist. Wenn es negativ ist, beenden wir einfach das Programm. Wenn es positiv ist, drucken wir es einfach aus und fahren mit dem nächsten Zeichen fort. Sobald wir den Zyklus abgeschlossen haben, kehren wir zu Schritt 2 zurück.Interessant ist auch, wie ich Strings mit beliebiger Größe implementiert habe (da ich zum ersten Mal unbegrenzten Speicher in Hexagony verwendet habe).
Stellen Sie sich vor, wir lesen irgendwann noch Zeichen für r (also können wir das Diagramm so verwenden, wie es ist) und eine [0] und eine 1 wurden bereits mit Zeichen gefüllt (alles nordwestlich von ihnen ist immer noch Null) ). Vielleicht haben wir gerade die ersten beiden Zeichen
og
der Eingabe in diese Kanten eingelesen und lesen jetzt ay
.Das neue Zeichen wird in die Lese in Kante. Wir benutzen die ? edge, um zu überprüfen, ob dieses Zeichen gleich ist
r
. (Hier gibt es einen raffinierten Trick: Hexagony kann nur leicht zwischen positiv und nicht positiv unterscheiden. Daher ist die Überprüfung der Gleichheit durch Subtraktion ärgerlich und erfordert mindestens zwei Zweige. Aber alle Buchstaben sind weniger als einen Faktor von 2 voneinander entfernt.) Wir können die Werte vergleichen, indem wir das Modulo nehmen, das nur dann Null ergibt, wenn sie gleich sind.)Aufgrund
y
von verschieden istr
, bewegen wir den (unmarkiert) Rand links in und kopieren diey
dort. Wir bewegen uns nun weiter um das Sechseck herum und kopieren das Zeichen jedes Mal um eine Kante weiter, bis wiry
die Kante gegenüber von in haben . Aber jetzt gibt es bereits ein Zeichen in einer [0], das wir nicht überschreiben möchten. Stattdessen "ziehen" wir dasy
um das nächste Sechseck und überprüfen eine 1 . Aber es gibt auch eine Figur, also gehen wir ein weiteres Sechseck weiter hinaus. Nun ist a [2] immer noch Null, also kopieren wir dasy
hinein. Der Speicherzeiger bewegt sich nun entlang der Zeichenkette zurück zum inneren Ring. Wir wissen, wann wir den Anfang der Zeichenkette erreicht haben, weil die (unbeschrifteten) Kanten zwischen dem a [i] alle Null sind, wohingegen ? ist positiv.Dies wird wahrscheinlich eine nützliche Technik zum Schreiben von nicht-trivialem Code in Hexagony im Allgemeinen sein.
quelle
Hexagony , 169 Bytes
Ich war von Martin Büttners Antwort inspiriert (es ist auch sein Esolang) und entschied, dass ich es in Größe 8 schaffen kann (ich bin überzeugt, dass es auch in Größe 7 möglich ist, aber es ist sehr schwierig. Ich habe schon vier Tage ohne sie verbracht - Hör auf damit.)
Sechseckig angeordnet:
Das Programm verwendet die
#
Anweisung nicht wirklich , daher habe ich dieses Zeichen verwendet, um zu zeigen, welche Zellen tatsächlich nicht verwendet werden. Darüber hinaus ist jede No-Op-Zelle, die nur in eine Richtung durchlaufen wird, ein Spiegel (z. B._
wenn sie horizontal durchlaufen wird), sodass Sie wissen, dass alle.
Zeichen in mehr als einer Richtung durchlaufen werden.Erläuterung
Zu Beginn führen wir die Befehlsfolge aus
r''o{{y''g{{b''p"")"
. Diese sind etwas zufällig im Code verstreut, weil ich sie eingedrückt habe, nachdem ich alles andere geschrieben habe. Ich]
wechsle einige Male zum nächsten Befehlszeiger. Auf diese Weise kann ich mich im Wesentlichen zu einer anderen Ecke des Sechsecks teleportieren. Der gesamte Rest des Programms wird durch den Befehlszeiger # 3 ausgeführt.Der Speicher sieht nun wie folgt aus, wobei die wichtigen Kanten mit Namen beschriftet sind, die ich in dieser Erklärung verwenden werde:
Die beschrifteten Kanten bedeuten Folgendes:
in
: Wir verwenden diese Kante, um ein Zeichen zu speichern, das wir aus STDIN gelesen haben.%
: Wir verwenden diese Kante eine Modulo - Operation auf den Charakter von STDIN (lesen Sie ausführenin
) und die aktuelle „gültig“ Zeichen (r
,o
usw.), die sein wird ,0
wenn sie gleich sind. Ich habe diesen Trick aus Martin Büttners Antwort gestohlen, aber der Rest des Programms ist anders.#
: Solange wir "ungültige" Zeichen lesen (dh Farben, die wir essen müssen), erhöhen wir diese Kante. Somit merkt sich diese Kante, wie vielee
s wir später ausgeben müssen.r?
: Immer0
außer wo derr
(rote) Teil ist. Dies sagt uns, wann wir einen Zyklus abgeschlossen haben.Das Programm läuft folgendermaßen ab:
#
. Andernfalls gehen Sie im Uhrzeigersinn zum nächsten Segment des Speichers.r?
positiv ist, haben wir eine ganze Revolution gemacht. Machen Sie eine vollständige Runde und geben Sie#
e
s und 1n
pro Segment aus. Dies setzt jeweils#
wieder auf0
. (Dase
wird auf eine unbeschriftete Kante gelegt, aber für denn
Fall#
, dass wir die Kante, die wir0
mit einem*
(Multiplikations) setzen, falsch einsetzen, funktioniert dies, weil wir wissen, dass alle%
Kanten zu diesem Zeitpunkt Null sind.)#
+1e
s aus, bis Sie zu dem Punkt zurückkehren, an demr?
es positiv ist. Beenden Sie dann.Nach einem vollständigen Durchlauf sieht der Speicher am Ende ungefähr wie folgt aus. Sie werden die Kanten bemerken, die
101
(den ASCII-Code vone
) enthalten; eine derin
Kanten ist-1
(EOF); alle#
Kanten sind bei 0; und der Speicherzeiger endet an der positivenr?
Flanke.quelle
Retina ,
1488579 BytesSie können dies aus einer einzelnen Quelldatei mit dem
-s
Interpreter-Flag ausführen .Erläuterung
Lassen Sie uns zunächst die einfachen Dinge aus dem Weg räumen:
Hängt
#roygbp
an das Ende der Zeichenfolge an, mit der der Buchstabenzyklus dynamisch berechnet wird.Der nächste (lange) Schritt ermittelt, welche Loops beibehalten und durch diese ersetzt werden sollen
n
. Wir werden uns in Kürze ansehen, wie das funktioniert.Dadurch wird unser Such-Assistent am Ende der Zeichenfolge entfernt.
Dadurch werden alle Zeichen, die im zweiten Schritt nicht ersetzt wurden, durch ersetzt
e
, wodurch die Umwandlung abgeschlossen wird.Gehen wir nun zum zweiten Schritt zurück.
Die Grundstruktur verwendet einen Trick, den ich vor einigen Monaten entdeckt habe , um ausgewählte Zeichen in einer globalen Übereinstimmung zu ersetzen:
wo
...
entspricht einer beliebig komplexen Muster. Dies entspricht dem zu ersetzenden Zeichen.
und startet dann einen Lookbehind (den Sie von rechts nach links lesen sollten). Der Lookbehind fängt alles bis zum übereinstimmenden Charakter in einer Gruppe zusammenprefix
. Dann wechselt es zu einem Look Ahead , der nun am Anfang der Zeichenkette beginnt und ein komplexes Muster enthalten kann. Nach dem Zeichen, das wir in diesem Muster ersetzen möchten, setzen wir einen optionalen Blick nach hinten , der prüft, ob dieprefix
Gruppe hier übereinstimmt. Wenn dies der Fall ist, wird eine leere Zeichenfolge in das Feld aufgenommenflag
Gruppe. Wenn dies nicht der Fall ist, hat dies keine Auswirkung auf den Status der Regex-Engine und wird ignoriert.\k<flag>
Wenn der Lookahead erfolgreich abgeglichen wurde, bleibt nur das Ende übrig, das nur übereinstimmt, wenn das Flag zu einem bestimmten Zeitpunkt während der Berechnung gesetzt wurde.Lassen Sie uns nun die lange Regex ein wenig entgolfen, indem Sie benannte Gruppen und den Freespacing-Modus verwenden:
Ich hoffe, Sie erkennen den allgemeinen Umriss von oben. Wir müssen uns also nur ansehen, wofür ich ausgefüllt habe
...
.Wir möchten das nächste Zeichen im Zyklus in der Gruppe erfassen
char
. Wir tun dies, indem wir uns auch die Zeichenfolge von#
bis zum aktuellen Zeichen in merkencycle
. Um das nächste Zeichen zu erhalten, verwenden wir einen Lookahead, um nach dem zu suchen#
. Jetzt versuchen wir,cycle
das nächste Zeichen in zu finden und dann zu findenchar
. Dies ist normalerweise möglich, sofernchar
es sich nicht um das letzte Zeichen handeltp
. In diesem Fall\k<cycle>
wird der gesamte Rest der Zeichenfolge abgeglichen, und es ist kein Zeichen mehr zum Erfassen vorhandenchar
. Der Suchmaschinen-Backtrack überspringt also den Backverweis aufcycle
und stimmtr
stattdessen nur mit dem ersten Zeichen überein .Jetzt haben wir das nächste Zeichen im Zyklus in
char
, wir suchen nach dem nächsten möglichen Auftreten dieses Zeichens mit.*?\k<char>
. Dies sind die Zeichen, die wir ersetzen möchten, also setzen wir denprefix
Haken dahinter. Diese Schritte (Finden des nächstenchar
im Zyklus, Suchen des nächsten Vorkommens, Setzen eines Flags, falls zutreffend) werden jetzt einfach mit einem wiederholt+
.Das ist eigentlich alles, um die zyklische Teilfolge zu finden, aber wir müssen auch sicherstellen, dass wir mit a enden
p
. Dies ist ziemlich einfach: Überprüfen Sie einfach, ob der aktuell in gespeicherte Wertchar
mit demp
am Ende der Zeichenfolge übereinstimmt.*\k<char>$
. Dies stellt auch sicher, dass unsere Nachschlagezeichenfolge nicht zum Beenden eines unvollständigen Zyklus verwendet wird, da wirp
für diese Prüfung das Trailing benötigen .quelle
Python 2,
133 130 126121 BytesDie erste Schleife erhält Zyklen und die zweite entfernt einen unvollständigen Zyklus
3 Bytes dank JF und 5 von DLosc gespeichert
quelle
r
undn
so:r=n=''
?R=r.count
funktioniert nicht, da Zeichenfolgen unveränderlichR
sind,''.count
auch wenn sier
geändert wurden.Perl 5,
7665 BytesEine Prise unverdünnter regulärer Ausdrücke.
Erst findet was nicht gegessen werden soll. Was bleibt, ist essbar.
Prüfung
quelle
[^o]*
Sie anstelle von etc..*?
(non-greedy quantifier) verwenden?\s
anstelle\n
der negativen Zeichenklasse der ersten Version verwenden.r(.*?)o(.*?)y(.*?)g(.*?)b(.*?)p
n$1n$2n$3n$4n$5n
[^n\s]
e
(4 Dateien, 57 Bytes).Lua, 101 Bytes
Verwendet Lua-Muster kreativ; Ich denke, das ist ein interessanter Ansatz.
Es ersetzt alle nicht gegessenen Zeichen durch "*", ersetzt alle alphanumerischen Zeichen durch "e" und ersetzt dann alle "*" durch "n".
quelle
Javascript (ES6), 118
Geige in Firefox getestet. Ich habe gehört, dass Chrome jetzt Pfeilfunktionen unterstützt, habe dies jedoch noch nicht in Chrome getestet.
Ungolfed:
quelle
...
Notation.Gawk, 96
Konstruiert das Suchmuster
"([^r]*)r([^o]*)o([^y]*)y([^g]*)g([^b]*)b([^p]*)p"
und die Ersetzung"\\1n\\2n\\3n\\4n\\5n\\6n"
. Nach diesem Austausch deklariert es alles, was Nahrung ("e") ist, und ist nicht Teil eines vollständigen Regenbogens.Diese Kombination stellt automatisch sicher, dass bei diesem Vorgang keine Regenbögen beschädigt werden und am Ende keine durchtrennten Regenbögen auftauchen.
quelle
Pyth, 42 Bytes
Probieren Sie es online aus: Demonstration
quelle
CJam, 41 Bytes
Brute-Force-Ansatz, der alle Ess- / Nicht-Ess-Variationen ausprobiert und diejenige auswählt, die zur längsten, gültigen Kette führt.
Probieren Sie es online im CJam-Interpreter aus .
quelle
CJam, 50 Bytes
Probieren Sie es online aus
Dies ist etwas länger als bei einigen anderen Einsendungen, aber bei linearer Komplexität sehr effizient. Es durchsucht die Eingabezeichenfolge und vergleicht die Zeichen nacheinander.
Der Kern des Algorithmus ist eigentlich ziemlich kompakt. Etwa die Hälfte des Codes dient zum Entfernen des unvollständigen Zyklus am Ende.
quelle
C90, 142-146 Byte (abhängig von bis zu 119 Byte)
Arbeitet in linearer Zeit, um die Fruchtschleifen, die nicht Teil eines hübschen Regenbogens sein können, effizient zu verzehren. Dann beendet ein Nachbearbeitungsvorgang jede Teilschleife am Ende.
Hier sind vier Versionen:
Version 1 (146 Bytes), Aufruf mit
[name] [string]
:main(int a,char**b){char*v=b[1],*s="roygbp",i=0,k=0;for(;v[i];++i)if(s[k]==v[i]){++k;k%=6;v[i]='n';}else v[i]='e';while(k-->0)v[--i]='e';puts(v);}
Version 2 (142 Bytes), aufrufen mit
[name] [string] [rainbow order]
:main(int a,char**b){char*v=b[1],*s=b[2],i=0,k=0;for(;v[i];++i)if(s[k]==v[i]){++k;k%=6;v[i]='n';}else v[i]='e';while(k-->0)v[--i]='e';puts(v);}
Damit können Sie Ihre eigene Regenbogenreihenfolge mit beliebigen Farben definieren, sofern diese nicht vorhanden sind
n
oder nichte
. Das macht den Code tatsächlich kürzer!Version 3 (123 Bytes), wie Version 1 aufrufen:
main(int a,char**b){char*v=b[1],*s="roygbp",i=0,k=0;for(;v[i];++i)if(s[k]==v[i]){++k;k%=6;v[i]='n';}else v[i]='e';puts(v);}
Diese gibt Ihnen so viel wie möglich von Ihrem Regenbogen! Die unvollständigen nachlaufenden Regenbogen sind vielversprechend! Wir sollten sie nicht essen!
Version 4 (119 Bytes), Aufruf wie Version 2:
main(int a,char**b){char*v=b[1],*s=b[2],i=0,k=0;for(;v[i];++i)if(s[k]==v[i]){++k;k%=6;v[i]='n';}else v[i]='e';puts(v);}
Wie Version 3, jedoch MOAR RAINBOW-TYPEN!
Kleinere Einschränkung: Der Computer muss Zeichen mit Vorzeichen haben (der allgemeine Fall), und die Zeichenfolge muss ziemlich kurz sein. Gibt
\n
zur Verdeutlichung ein Trailing aus.Version 1 ist die einzige, die die Anforderungen eindeutig erfüllt, obwohl Version 2 fraglich ist. Die Versionen 3 und 4 sind eine weniger korrekte (aber dennoch unterhaltsame) Interpretation der Frage.
quelle
Pyth, 38 Bytes
Ich weiß, das ist deutlich länger als die Antwort von Orlp, aber diese läuft in linearer Zeit: o)
Probieren Sie es hier aus .
Kurz gesagt, dieses Programm ersetzt alle Zeichen nach dem letzten 'p' durch Leerzeichen und durchläuft dann jedes Zeichen in der resultierenden Zeichenfolge. Wenn das Zeichen das nächste in der "Roygbp" -Sequenz ist, drucken Sie "n", andernfalls "e".
Ich habe mich bemüht, einen kürzeren Weg zu finden, um die Eingabezeichenfolge zu verarbeiten.
_>_zJ
fühlt sich besonders umständlich an, gibt aber<Jz
nicht den erforderlichen String an, wennJ == 0
, dh wenn die Eingabe mit einem 'p' endet.quelle
Haskell, 138 Bytes
g
macht es.quelle
f
undz
als Infix definieren:'n'%'n'='n'
usw. Außerdem können einige Klammern in der Definition vong
mit entfernt werden$
.Javascript (ES6),
8582 BytesDie Regel "Halskette muss in Lila enden" war ursprünglich eine große Hürde und erhöhte meine Punktzahl von 66 auf 125, aber ich fand einen kürzeren Weg darüber (zum Glück!).
Erläuterung:
Dieser Code durchläuft jedes Zeichen in der Eingabe und ersetzt jedes mit
r
odere
mit dieser Logik:p
, UND das Zeichen das nächste im Regenbogen ist, behalten Sie es bei (ersetzen Sie es durchn
).e
).Ungolfed:
Vorschläge willkommen!
quelle
Python 2, 254 Bytes
Schleifen!
Entschuldigen Sie das Wortspiel. : P
quelle