Viele Sprachen verfügen über integrierte Methoden zum Entfernen von Duplikaten oder zum "Deduplizieren" oder "Eindeutigen" einer Liste oder Zeichenfolge. Eine seltenere Aufgabe ist es, eine Zeichenfolge zu "zerlegen". Das heißt, für jedes erscheinende Zeichen werden die ersten beiden Vorkommen beibehalten.
Hier ist ein Beispiel, in dem die Zeichen, die gelöscht werden sollen, mit gekennzeichnet sind ^
:
aaabcbccdbabdcd
^ ^ ^^^ ^^
aabcbcdd
Ihre Aufgabe ist es, genau diese Operation zu implementieren.
Regeln
Die Eingabe ist eine einzelne, möglicherweise leere Zeichenfolge. Sie können davon ausgehen, dass es nur Kleinbuchstaben im ASCII-Bereich enthält.
Die Ausgabe sollte eine einzelne Zeichenfolge sein, wobei alle Zeichen entfernt werden, die bereits mindestens zweimal in der Zeichenfolge vorkommen (sodass die beiden am weitesten links stehenden Vorkommen beibehalten werden).
Anstelle von Strings können Sie auch mit Listen von Zeichen (oder Singleton-Strings) arbeiten, das Format muss jedoch zwischen Eingabe und Ausgabe konsistent sein.
Sie können ein Programm oder eine Funktion schreiben und eine unserer Standardmethoden zum Empfangen und Bereitstellen von Eingaben verwenden.
Sie können jede Programmiersprache verwenden , beachten Sie jedoch, dass diese Lücken standardmäßig verboten sind.
Das ist Code-Golf , also gewinnt die kürzeste gültige Antwort - gemessen in Bytes .
Testfälle
Jedes Zeilenpaar ist ein Testfall, Eingabe gefolgt von Ausgabe.
xxxxx
xx
abcabc
abcabc
abcdabcaba
abcdabc
abacbadcba
abacbdc
aaabcbccdbabdcd
aabcbcdd
Bestenliste
Das Stapel-Snippet am Ende dieses Beitrags generiert eine Rangliste aus den Antworten a) als Liste der kürzesten Lösungen pro Sprache und b) als Gesamtrangliste.
Um sicherzustellen, dass Ihre Antwort angezeigt wird, beginnen Sie Ihre Antwort mit einer Überschrift. Verwenden Sie dazu die folgende Markdown-Vorlage:
## Language Name, N bytes
Wo N
ist die Größe Ihres Beitrags? Wenn Sie Ihren Score zu verbessern, Sie können alte Rechnungen in der Überschrift halten, indem man sich durch das Anschlagen. Zum Beispiel:
## Ruby, <s>104</s> <s>101</s> 96 bytes
Wenn Sie mehrere Zahlen in Ihre Kopfzeile aufnehmen möchten (z. B. weil Ihre Punktzahl die Summe von zwei Dateien ist oder wenn Sie die Strafen für Interpreter-Flags separat auflisten möchten), stellen Sie sicher, dass die tatsächliche Punktzahl die letzte Zahl in der Kopfzeile ist:
## Perl, 43 + 3 (-p flag) = 45 bytes
Sie können den Namen der Sprache auch als Link festlegen, der dann im Snippet angezeigt wird:
## [><>](http://esolangs.org/wiki/Fish), 121 bytes
<style>body { text-align: left !important} #answer-list { padding: 10px; width: 290px; float: left; } #language-list { padding: 10px; width: 290px; float: left; } table thead { font-weight: bold; } table td { padding: 5px; }</style><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="language-list"> <h2>Shortest Solution by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr> </thead> <tbody id="languages"> </tbody> </table> </div> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr> </thead> <tbody id="answers"> </tbody> </table> </div> <table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr> </tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr> </tbody> </table><script>var QUESTION_ID = 86503; var ANSWER_FILTER = "!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe"; var COMMENT_FILTER = "!)Q2B_A2kjfAiU78X(md6BoYk"; var OVERRIDE_USER = 8478; var answers = [], answers_hash, answer_ids, answer_page = 1, more_answers = true, comment_page; function answersUrl(index) { return "https://api.stackexchange.com/2.2/questions/" + QUESTION_ID + "/answers?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + ANSWER_FILTER; } function commentUrl(index, answers) { return "https://api.stackexchange.com/2.2/answers/" + answers.join(';') + "/comments?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + COMMENT_FILTER; } function getAnswers() { jQuery.ajax({ url: answersUrl(answer_page++), method: "get", dataType: "jsonp", crossDomain: true, success: function (data) { answers.push.apply(answers, data.items); answers_hash = []; answer_ids = []; data.items.forEach(function(a) { a.comments = []; var id = +a.share_link.match(/\d+/); answer_ids.push(id); answers_hash[id] = a; }); if (!data.has_more) more_answers = false; comment_page = 1; getComments(); } }); } function getComments() { jQuery.ajax({ url: commentUrl(comment_page++, answer_ids), method: "get", dataType: "jsonp", crossDomain: true, success: function (data) { data.items.forEach(function(c) { if (c.owner.user_id === OVERRIDE_USER) answers_hash[c.post_id].comments.push(c); }); if (data.has_more) getComments(); else if (more_answers) getAnswers(); else process(); } }); } getAnswers(); var SCORE_REG = /<h\d>\s*([^\n,<]*(?:<(?:[^\n>]*>[^\n<]*<\/[^\n>]*>)[^\n,<]*)*),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/; var OVERRIDE_REG = /^Override\s*header:\s*/i; function getAuthorName(a) { return a.owner.display_name; } function process() { var valid = []; answers.forEach(function(a) { var body = a.body; a.comments.forEach(function(c) { if(OVERRIDE_REG.test(c.body)) body = '<h1>' + c.body.replace(OVERRIDE_REG, '') + '</h1>'; }); var match = body.match(SCORE_REG); if (match) valid.push({ user: getAuthorName(a), size: +match[2], language: match[1], link: a.share_link, }); else console.log(body); }); valid.sort(function (a, b) { var aB = a.size, bB = b.size; return aB - bB }); var languages = {}; var place = 1; var lastSize = null; var lastPlace = 1; valid.forEach(function (a) { if (a.size != lastSize) lastPlace = place; lastSize = a.size; ++place; var answer = jQuery("#answer-template").html(); answer = answer.replace("{{PLACE}}", lastPlace + ".") .replace("{{NAME}}", a.user) .replace("{{LANGUAGE}}", a.language) .replace("{{SIZE}}", a.size) .replace("{{LINK}}", a.link); answer = jQuery(answer); jQuery("#answers").append(answer); var lang = a.language; lang = jQuery('<a>'+lang+'</a>').text(); languages[lang] = languages[lang] || {lang: a.language, lang_raw: lang.toLowerCase(), user: a.user, size: a.size, link: a.link}; }); var langs = []; for (var lang in languages) if (languages.hasOwnProperty(lang)) langs.push(languages[lang]); langs.sort(function (a, b) { if (a.lang_raw > b.lang_raw) return 1; if (a.lang_raw < b.lang_raw) return -1; return 0; }); for (var i = 0; i < langs.length; ++i) { var language = jQuery("#language-template").html(); var lang = langs[i]; language = language.replace("{{LANGUAGE}}", lang.lang) .replace("{{NAME}}", lang.user) .replace("{{SIZE}}", lang.size) .replace("{{LINK}}", lang.link); language = jQuery(language); jQuery("#languages").append(language); } }</script>
Antworten:
Gelee , 6 Bytes
Probieren Sie es online! oder überprüfen Sie alle Testfälle .
Wie es funktioniert
quelle
JavaScript (ES6), 42
48Bearbeite ganze 6 Bytes, die dank @Neil gespeichert wurden
Erläuterung: Ich verwende die Eigenschaften 'a' ... 'z' von object
k
, um Informationen für jedes Zeichen zu speichern (object k ist in diesem Fall ein regulärer Ausdruck, um nur Bytes zu speichern). Diese Eigenschaften sind zunächstundefined
. In Javascriptundefined
ergibt das Hinzufügen einer Zahl zu " gives"NaN
(durchaus sinnvoll), das Hinzufügen einer Zeichenfolge "X" jedoch"undefinedX"
- eine Zeichenfolge mit der Länge 10 (albern). Wenn Sie mehr Zeichen hinzufügen, erhalten Sie längere Zeichenfolgen. Wenn die erhaltene Zeichenfolge für ein bestimmtes Zeichen länger als 11 ist, wird dieses Zeichen nicht in die Ausgabe kopiert.Prüfung
quelle
v=>v.filter(x=>!(v[x]+=x)[11])
. Ein dickes Lob auf den "undefinierten" Hack.Python 2, 48 Bytes
c[r.count(c)/2:]
ist eine gleichlange Alternative zuc*(r.count(c)<2)
.49 Bytes:
quelle
Retina , 17 Bytes
Probieren Sie es online!
Einfaches Ersetzen von Regex - Ordnen Sie ein Zeichen zu, wenn es bereits zweimal vorkommt, und entfernen Sie es.
quelle
{2}
, beide mit 18 Bytes.:P
. Vielen Dank!Brachylog , 25 Bytes
Probieren Sie es online! oder überprüfen Sie alle Testfälle .
Erläuterung
Das funktioniert, weil erst
s - Subset
mit größeren Teilmengen vereinheitlicht wird, also zB dafür vorher probiert"aaa"
wird ."aa"
"a"
Hauptprädikat:
Prädikat 1: Stellen Sie sicher, dass alle Zeichen höchstens zweimal vorkommen. Eingabe =
[String:Char]
Prädikat 2: Holen Sie sich ein Vorkommen eines Charakters. Eingabe =
[String:Char]
quelle
> <> , 22 Bytes
Probieren Sie es online! Verwendet die Codebox, um die bisherigen Zählungen zu verfolgen.
quelle
J,
2015 BytesDies definiert eine monadische Funktion, die einen String akzeptiert und zurückgibt. Probieren Sie es hier aus . Verwendungszweck:
Erläuterung
Ich habe auf denselben Algorithmus gewechselt, den einige andere Lösungen verwenden, da er sich als kürzer herausstellte ...
quelle
Haskell,
4039 BytesAnwendungsbeispiel:
foldl(\s c->s++[c|filter(==c)s<=[c]])"" "aaabcbccdbabdcd"
->"aabcbcdd"
.Behalten Sie das nächste Zeichen bei,
c
wenn die Zeichenfolge allerc
bisherigen s weniger oder gleich der Singleton-Zeichenfolge ist[c]
.Edit: @xnor hat ein Byte gespeichert, indem von Listenverständnis zu umgeschaltet wurde
filter
. Vielen Dank!quelle
filter(==c)s<=[c]
ein Byte speichern.Perl, 22 Bytes
21 Byte Code + 1 für
-p
.Verwendungszweck
quelle
C 57 Bytes
Rufen Sie
f()
mit der Zeichenfolge detriplicate. Die Funktion ändert ihren Parameter. Erfordert C99 wegen derfor
-loop-Deklaration.quelle
s
in die erste Aussage von setzenfor
?JavaScript (ES6), 35 Byte
Nimmt ein Array von Zeichen als Eingabe und gibt das detriplizierte Array zurück.
quelle
c=>(s[c]=-~s[c])<3
ein paar Bytes sparen.map
. Golfen sah es im Wesentlichen aus wie bei Ihnen. Der Hauptunterschied war die Zuweisung, die beim Umschalten einige Bytes einspart. Versuchen Sie ess.filter(c=>(s[c]=s[c]+1|0)<3)
mit 33 Bytes. EDIT: Whoops, Kommentar über mir verpasst haben , die sogar besser :)PowerShell v2 +, 31 Byte
Verwendet den gleichen regulären Ausdruck wie in Kobis Retina-Antwort , der nur im PowerShell-
-replace
Operator enthalten ist. Funktioniert, da beide .NET-Regex im Hintergrund verwenden.Alternativ, ohne Regex, 56 Bytes
Erstellt ein Helfer-Array, das
$b
mit0
s gefüllt ist. Wandelt die Eingabezeichenfolge$args[0]
in einchar
-array um und leitet sie durch eine Schleife|%{...}
. Bei jeder Iteration wird das aktuelle Zeichen$_
als Zeichenfolge"$_"
multipliziert mit einem Booleschen Wert ausgegeben, der nur dann$TRUE
(implizit1
hierher gewandelt) wird, wenn der entsprechende Punkt im Hilfsarray kleiner ist als2
(dh, wir haben dieses Zeichen noch nicht zweimal gesehen). Die resultierende Sammlung von Zeichenfolgen wird in Parens eingekapselt und-join
zu einer einzigen Ausgabezeichenfolge zusammengefasst. Das bleibt in der Pipeline und die Ausgabe ist implizit.quelle
$b=@{};-join($args|% t*y|?{++$b.$_-lt3})
.Mathematica, 39 Bytes
Anonyme Funktion. Nimmt eine Zeichenliste als Eingabe und gibt die disziplinierte Liste als Ausgabe zurück. Verwendet die Methode des Umklappens der Liste und des Zurückweisens dreifacher Elemente, es ist nicht zu kompliziert.
quelle
05AB1E, 12 Bytes
Erläuterung
Probieren Sie es online aus
quelle
MATL , 8 Bytes
Probieren Sie es online!
Erläuterung
Beispiel
Angenommen
'aaababbc'
, der Stack enthält nach den angegebenen Anweisungen Folgendes:t
t&=
t&=R
t&=Rs
t&=Rs3<
t&=Rs3<)
quelle
Retina , 14 Bytes
Überprüfen Sie alle Testfälle. (Der
%
Aktiviert Pro-Line-Modus)Verwendet die neue Stufe "Deduplizieren", um ein paar Bytes gegenüber Kobis Ansatz zu sparen . Deduplizieren sammelt eine Liste aller Übereinstimmungen mit dem regulären Ausdruck und ersetzt alle bis auf die erste durch die leere Zeichenfolge. Der reguläre Ausdruck stimmt mit einem Zeichen überein, das bereits einmal in der Zeichenfolge enthalten ist, sodass die ersten beiden Zeichen beibehalten werden.
quelle
Pyke, 16 Bytes
Probieren Sie es hier aus!
quelle
K, 18 Bytes
K4 steht zum kostenlosen Download zur Verfügung . K6 ist in Entwicklung . Wenn Sie KDB heruntergeladen haben, können Sie mit Backslash in K einsteigen .
Es mag am einfachsten sein, dies auseinanderzubrechen, aber zuerst einige Syntax:
g:x
setztg
aufx
.{x+1}
ist eine Funktion, die ein Argument x annimmt . In K ist das erste Argument für eine Funktionx
(das zweite isty
und das dritte istz
. Benötige kein viertes).Jetzt:
=x
bedeutet Gruppe x , die erzeugt:2#'
bedeutet zwei genommene (von) jeder, die erzeugtWie Sie sehen können, sind dies die Offsets der ersten beiden Übereinstimmungen jedes Charakters. Die 2 könnte verallgemeinert werden.
,/
bedeutet verbinden und wird oft als raze bezeichnet . Es wird uns nur die Werte unseres Wörterbuchs bringen. So,/"abcd"!(0 1;3 5;4 6;8 12)
entsteht:was wir sortieren müssen.
{x@<x}@
ist eine Redewendung, die K-Programmierer oft sehen (Q nennt sie asc ), die x beim Hochstufen x sagt . Brechen Sie es auseinander:gab die Indizes des sortierten Arrays zurück, die wir aus dem ursprünglichen Array nehmen wollen.
x@y
Bedeutet x bei y, so indiziert dies das Array mit den Indizes der Sortierung (falls dies irgendeinen Sinn ergibt).was wir einfach jetzt in unserem ursprünglichen Array indizieren. Wir könnten
x@
hier sagen , aber K unterstützt ein wirklich leistungsfähiges Konzept, das wir hier nutzen können: Funktionsanwendung ist Indizierung. Das bedeutet, dassa[0]
der nullte Slot von nachgeschlagena
oder0
die aufgerufene Funktion angewendet werden könntea
. Der Grund , warum wir die benötigten@
vorher in{x@<x}
ist , weilx<y
Mittel xs weniger als ys : Operatoren in K eine dyadische Form haben (zwei Argumente) und eine monadische Form (ein Argument) , die von APL kommt. Q hat diese "Ambivalenz" nicht.quelle
g"aaabcbccdbabdcd"
g"..."
den Trick. Leider wird Ihr Codeaabbcc
zur Eingabe zurückgegebenabc
.{x{?x@<x}@,/2#'=x}"abc"
jeden Fall zurück"abc"
. Es würde zurückkehren,"aabbcc"
wenn Sie den?
Unterschied verpassen .Python 2, 51 Bytes
Teste es auf Ideone .
quelle
Java 8 Lambda, 90 Zeichen
Ungolfed-Version:
Erstellt ein Array für alle ASCII-Zeichen. Wenn ein Zeichen vorkommt, wird der entsprechende Zähler erhöht. Wenn es über 2 liegt, wird das Zeichen nicht an die Ergebniszeichenfolge angehängt. Sehr einfach, sehr kurz;)
quelle
Perl 6, 27 Bytes
Erläuterung:
(Hinweis: Perl 6 ist nicht so "golforientiert" wie seine Schwester Perl 5 ... Also ja, dieser Platz vor dem
<
ist notwendig. Das%.{}
ist ein anonymer Hash).quelle
SmileBASIC,
77726968 BytesErklärt:
quelle
Common Lisp, 127
Hübsch bedruckt
quelle
Q , 52 Bytes
quelle
K , 27 Bytes
quelle
Ruby ,
796257 BytesDas ist ziemlich unhandlich, aber ich bin mir nicht sicher, ob ich im Moment so viel besser Golf spielen kann. Anregungen zum Golfen sind willkommen. Probieren Sie es online!
Bearbeiten: -17 Bytes dank Value Ink, indem eine bessere Methode zum Entfernen dreifacher Zeichen vorgeschlagen wird. -5 Bytes vom Entfernen der
.uniq
Methode.Ungolfed:
quelle
->s{s.chars.uniq.map{|a|s[s.rindex a]=""while s.count(a)>2};s}
JavaScript, 30 Bytes
Mit der Methode, die @ edc65 zum Zählen entwickelte, aber mit einem Arrayfilter. Das erste Mal, wenn ein Zeichen erscheint, wird der Objektwert "undefined" plus das Zeichen (dh "undefinedx"). Beim nächsten Mal wird der Objektwert "undefinedxx".
Danach gibt v [x] [11] true zurück, und in Kombination mit dem Operator not wird false zurückgegeben, was bedeutet, dass Zeichen, die bereits zweimal vorkommen, gefiltert werden.
quelle
Javascript (mit externer Bibliothek) (80 Bytes)
Das war gut! Hat nicht gewonnen, aber es hat Spaß gemacht
Link zu lib: https://github.com/mvegh1/Enumerable/
Codeerklärung: Die Methode akzeptiert eine Zeichenfolge, die Bibliothek analysiert sie als Zeichenarray, und die Where-Klausel ist ein komplexes Filterprädikat, das die 'a'-Hashmap auf Vorhandensein des aktuellen Zeichens überprüft. Wenn vorhanden, Inkrementzähler, sonst auf 1 gesetzt. Wenn <2, besteht das Prädikat (und das aktuelle Zeichen), sonst schlägt fehl
quelle
return
aber machen Sie Ihre Funktion eine durch Kommata getrennte Liste von einem Ausdrücke in Klammern:n=>(a={},_From(n)....)
. Der letzte Ausdruck ist der Rückgabewert. In IhrerWhere
Funktion können Sie die Zwischen beseitigenb
vollständig durch einen Vergleich gegen das Ergebnis der Zuordnung oder Schritt:x=>(a[x]?a[x]++:a[x]=1)<2
.filter
mitjoin
:[...n].filter(...).join("")
. Drehen Sie die Wahr / Falsch - Logik beim WechselWhere
zufilter
.Clojure, 72 Bytes
So viele Bytes ...
quelle
Pascal (FPC) , 103 Bytes
Probieren Sie es online!
Erläuterung:
quelle