Zielsetzung
Schreiben Sie eine Routine, die eine Zeichenfolge aus druckbaren ASCII-Zeichen ( s) akzeptiert und eine Zeichenfolge mit denselben Zeichen wie ( s) zurückgibt , die neu angeordnet wurde, sodass keine Teilzeichenfolge mit zwei Zeichen mehr als einmal vorkommt. Das Programm muss alle Benchmark-Zeichenfolgen (siehe unten) in jeweils weniger als einer Minute auf einem modernen Computer verarbeiten . Ich werde auch einen besonderen Bonus von 50 Wiederholungen für die Antwort mit der niedrigsten Punktzahl vergeben, die eine gültige 30-Zeichen-Zeichenfolge in weniger als einer Minute verarbeitet.
Bei einer gegebenen Eingabe Mississippi
wäre dies beispielsweise eine gültige Ausgabe issiMspiips
(es werden keine Teilzeichenfolgen mit zwei Zeichen zweimal angezeigt ), während dies eine ungültige Ausgabe wäre ipMsispiiss
(da die Teilzeichenfolge is
zweimal angezeigt wird).
Die Routine kann die Form haben:
- ein vollständiges Programm, das von
stdin
(oder einer gleichwertigen) oder der Befehlszeile gelesen und anstdout
(oder einer gleichwertigen) Stelle ausgegeben wird - Eine Funktion, die ein einzelnes Zeichenfolgenargument akzeptiert und eine Zeichenfolge zurückgibt
Sie können davon ausgehen, dass die Eingabezeichenfolge immer mindestens eine gültige Ausgabe zulässt.
Die Herausforderung
Ihre Routine muss 5 oder mehr Codezeilen enthalten, die durch Zeilenumbrüche voneinander getrennt sind. Leere Zeilen (einschließlich Zeilen, die nur Leerzeichen enthalten) werden in allen Kontexten ignoriert und zählen nicht zur Gesamtanzahl der Zeilen.
Das Vertauschen von zwei beliebigen Zeilen in Ihrem Quellcode muss einen schwerwiegenden Fehler verursachen. Mit "schwerwiegender Fehler" wird auf eine der folgenden Bedingungen verwiesen:
- Der Quellcode kann nicht kompiliert werden, und der Compiler / Interpreter meldet einen schwerwiegenden Fehler
- Die Routine wird mit einem schwerwiegenden Laufzeitfehler oder einer nicht behandelten Laufzeitausnahme abgebrochen
- Die Routine wird zu einem abrupten, abnormalen Programmabbruch gezwungen, der bis auf eine mögliche Fehlermeldung und / oder einen Stapelspeicherauszug keinerlei Ausgabe erzeugt
Alternativ können zusammenhängende Codeblöcke, die keine Zeilenumbrüche enthalten, anstelle von Zeilen verwendet werden. Diese Blöcke sollten in der Quelldatei jeweils in einer eigenen Zeile angezeigt werden, mit der Maßgabe, dass Zeilenumbrüche entfernt werden, bevor der Quellcode kompiliert / interpretiert wird.
Zum Beispiel der Code
aaaa
bbbb
cccc
würde kondensieren
aaaabbbbcccc
bevor sie ausgewertet werden.
In diesem Modus gilt die schwerwiegende Fehlerbedingung für das Austauschen von zwei Codeblöcken (und damit für das Austauschen von Zeilen im Quellcode, bevor Zeilenumbrüche entfernt werden). Daher wird in dem obigen Beispiel die Routinen aaaaccccbbbb
, bbbbaaaacccc
und ccccbbbbaaaa
müssen alle fatalen Fehler produzieren, entweder in compiletime oder Laufzeit.
Bei Einsendungen, die diesen alternativen Modus verwenden, muss die Verwendung deklariert werden.
Wertung
Sei n die Anzahl der nicht leeren Textzeilen in Ihrer Quelldatei, mit n ≥ 5. Sei c die Anzahl der Bytes, die die längste Textzeile (nach Bytelänge) in Ihrer Quelldatei enthält, ohne nachfolgende Zeilenumbrüche.
Die Punktzahl einer Einreichung ergibt sich aus c ( n + 10).
Die Einsendung mit der niedrigsten Punktzahl ist der Gewinner.
Viel Glück. ;)
Benchmark-Strings
Abracadabra Alacazam
Is Miss. Mississauga Missing?
Ask Alaska's Alaskans
GGGGAAAATTTTCCCCgggaaatttccc
A Man A Plan A Canal Panama
CooliO
OutputoOoCli
?Mspiisiipss
gültig, da die einzige Wiederholung die ist, inii
der nicht vorkommtMississippi
?Antworten:
PHP, Score = 289 (17 × (7 + 10))
Die eingebauten Funktionen von PHP machen es ziemlich einfach, dies schlecht zu machen. Der folgende Code mischt die Zeichenfolge nur, bis ein gültiges Ergebnis erhalten wird:
Benchmarks
Durchschnittliche und maximale Ausführungszeit berechnet mit folgendem Code:
Ergebnisse:
* Ich habe zu geändert
ä
,a
um Multibyte-Probleme zu vermeiden. Es sind tatsächlich die ersten 30 Zeichen der De Bruijn-Sequenz für k = 'abcdef' und n = 2, wobei das erste 'b' verschoben wird, um eine sofortige Übereinstimmung zu vermeiden.
quelle
Dyalog APL (11 (5 + 10) = 165)
Beweis:
⍵
, dass eine Funktion außerhalb von a auftrittSYNTAX ERROR
.b
, kann also nicht gegen Zeilen ausgetauscht werden3
oder4
, die davon abhängenb
. Es würde eine gebenVALUE ERROR
. (Und es kann natürlich nicht mit1
oder ausgetauscht5
werden.)c
, kann also nicht gegen Zeile ausgetauscht werden4
, was von abhängtc
. (Und wir haben bereits bewiesen, dass keine andere Leitung mit der Leitung ausgetauscht werden kann3
.)quelle
APL (Dyalog), 6 (5 + 10) = 90
Ich benutze die Alternative, also:
Dies ist derselbe alte Algorithmus.
Durch die Angabe
2,/⍵
eines Arrays von Zeichenpaaren in der Eingabezeichenfolge+/∘.≡⍨
wird ein numerisches Array der Anzahl der Paare generiert, die für jedes Paar gleich sind (einschließlich sich selbst).1∧.=
geprüft, ob jedes Element dieses Arrays gleich 1 ist, und die Ergebnisse werden logisch UND verknüpft:⍵
Wenn das stimmt (1
), geben Sie die Eingabezeichenfolge zurück∇⍵[?⍨⍴⍵]
sonst verschlüsseln Sie die Eingabezeichenfolge und führen Sie einen rekursiven Aufruf durchTauschen
Wenn Zeile 1 gegen Zeile 2 ausgetauscht wird,
+/∘.≡⍨{...}
ist das nur ein Durcheinander von Funktionen und OperatorenSYNTAX ERROR
.Wenn Zeile 1 mit Zeile 3 oder 4 vertauscht wird, haben Sie
⍵
außerhalb einer Funktionsdefinition, und das ist einSYNTAX ERROR
.Wenn Zeile 1 gegen Zeile 5 ausgetauscht wird, führt dies allein zu unsymmetrischen Klammern. Machen Sie sich
SYNTAX ERROR
also keine Gedanken über die anderen 4 Syntaxfehler.Wenn Zeile 5 mit Zeile 2/3/4 getauscht wird, haben Sie wieder
⍵
außerhalb einer Funktionsdefinition. (SYNTAX ERROR
)Wenn Zeile 2 gegen Zeile 3 ausgetauscht wird, erhalten Sie
1∧.=2,/⍵:⍵
. Diese Syntax wird als Guard bezeichnet (man denke an eine Bedingung). Die Guard-Bedingung muss als0
oder1
oder als 1-Element-Array von0
oder ausgewertet werden1
. Hier ergibt sich eine komplexere Bewertung (ein Skalar mit einem Array aus zwei Elementen). Das ist also einDOMAIN ERROR
.Wenn Zeile 2 gegen Zeile 4 ausgetauscht wird, erhalten Sie die Anweisung
1∧.=
, die versucht, die Funktion anzuwenden∧.=
ohne das erforderliche linke Argument . (SYNTAX ERROR
).Wenn Zeile 3 gegen Zeile 4 ausgetauscht wird, erhalten Sie wieder eine Unordnung von Funktionen und Operatoren (
1∧.=+/∘.≡⍨
)SYNTAX ERROR
.Benchmarks
(Zahlen in Millisekunden)
Ich denke immer noch über verschiedene Spaltungen nach. Ich habe auch eine deterministische, systematische Art, die Aufgabe zu erledigen. Ich kann es einfach nicht in einen Algorithmus verwandeln (den kreativen Teil von "Zahlen richtig machen" entfernen) und kann nicht sicherstellen, dass es jedes Mal funktioniert.
quelle
Haskell, 129 = 3x (33 + 10)
Dies verwendet den alternativen Modus.
oder in lesbarer Form:
Haskell ist eine sehr strenge Sprache. Zum Beispiel
import
muss das zuerst kommen. die Definitionen vons
müssen zusammenkommen; Alle Typen müssen übereinstimmen, und es gibt keine Möglichkeit, zwischen ihnen zu wechseln, und so weiter. Dies führt dazu, dass ein nicht schwerwiegender Fehler fast unmöglich ist. Tatsächlich ist es fast unmöglich, einen schwerwiegenden Laufzeitfehler zu haben.Beachten Sie, dass if
g
eine gültige Funktion ist, aber einen falschen Typ hat (jeder andere Typ[a]->[a]
oderString -> String
ähnliches), als dies ein schwerwiegender Fehler ist, da es unmöglich ist, ihn anzuwendeng
auf die Eingänge.Ausgänge:
quelle