Anhängen und löschen

14

Wenn eine Zeile nur aus Buchstaben besteht, verfahren Sie wie folgt:

  • Sie pflegen eine Zeichenfolge, die am Anfang leer ist.
  • Wenn sich das nächste Eingabezeichen in der Zeichenfolge befindet, entfernen Sie es aus der Zeichenfolge.
  • Wenn das nächste Eingabezeichen nicht in der Zeichenfolge enthalten ist, hängen Sie es an die Zeichenfolge an.

Gibt den Endzustand der Zeichenkette aus.

Sie können davon ausgehen, dass die Eingabe aus mindestens einem Zeichen besteht (dh nicht leer ist), es kann jedoch nicht garantiert werden, dass die Ausgabe nicht leer ist.

Pseudocode (Fühlen Sie sich frei, dies zu spielen):

str = EMPTY
for each character ch in input
  if ch exists in str
    remove all ch from str
  else
    append ch to str
print str

Die Eingabe entspricht dem regulären Ausdruck ^[A-Za-z]+$.

Beispiel Testfälle:

ABCDBCCBE -> ADCBE
ABCXYZCABXAYZ -> A
aAABBbAbbB -> aAbB
GG -> (empty)

Die Eingabe kann auf beliebige Weise erfolgen, muss jedoch als Zeichenfolge behandelt werden und für die Ausgabe identisch sein. Das Programm sollte nicht mit einem Fehler beendet werden.

Das kürzeste Programm in jeder Sprache gewinnt!

Extra (Optional): Bitte erläutern Sie, wie Ihr Programm funktioniert. Vielen Dank.

iBug
quelle
Darf die Zeile leer sein?
User202729
1
@ user202729 Nein. Ich habe mich ein wenig geändert (es macht keine Antwort ungültig), sodass die Eingabe niemals leer ist.
iBug
1
Warum haben Sie den Änderungsvorschlag von ais523 (Link) abgelehnt ?
user202729

Antworten:

10

Haskell , 44 42 Bytes

foldl(#)""
s#x|z<-filter(/=x)s=z++[x|z==s]

Probieren Sie es online! Edit: -2 Bytes dank Zgarb!

Erläuterung:

Die zweite Zeile definiert eine Funktion, (#)die eine Zeichenfolge sund ein Zeichen xakzeptiert und entweder das Entfernen oder das Anhängen ausführt. Dies wird erreicht durch filtering aus jedem Auftreten xin s, was in der Zeichenfolge z. Wenn in xnicht vorkommt s, dann zist gleich sund z++[x|z==s]ergibt den Originalstring mit xangehängtem. Andernfalls wird [x|z==s]die leere Zeichenfolge ausgegeben und nur die gefilterte Zeichenfolge zurückgegeben.

foldl(#)""ist eine anonyme Funktion, die eine Zeichenfolge verwendet und ""der Funktion eine anfangs leere Zeichenfolge nach der anderen hinzufügt (#).

Laikoni
quelle
2
42 Bytes durch Wiederverwendung des Filters.
Zgarb
9

Gelee , 3 Bytes

œ^/

Probieren Sie es online!

Volles Programm.

Erik der Outgolfer
quelle
Warum ist œ^/nicht genug?
Jonathan Allan
@ JonathanAllan Das Programm sollte nicht mit einem Fehler beendet werden.
Erik der Outgolfer
the input is never emptyNun, jetzt funktioniert es.
User202729
8

J , 21 19 Bytes

#~~:&.|.(2|*)1#.=/~

Wie es funktioniert:

=/~ - erstellt eine Gleichheitstabelle der Zeichen in der Zeichenfolge:

   a =. 'ABCXYZCABXAYZ'
   ]b =: =/~ a 
1 0 0 0 0 0 0 1 0 0 1 0 0
0 1 0 0 0 0 0 0 1 0 0 0 0
0 0 1 0 0 0 1 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 1 0 0 0
0 0 0 0 1 0 0 0 0 0 0 1 0
0 0 0 0 0 1 0 0 0 0 0 0 1
0 0 1 0 0 0 1 0 0 0 0 0 0
1 0 0 0 0 0 0 1 0 0 1 0 0
0 1 0 0 0 0 0 0 1 0 0 0 0
0 0 0 1 0 0 0 0 0 1 0 0 0
1 0 0 0 0 0 0 1 0 0 1 0 0
0 0 0 0 1 0 0 0 0 0 0 1 0
0 0 0 0 0 1 0 0 0 0 0 0 1

1#. - Summe jeder Zeile nach Basis 1-Konvertierung (wie oft der Buchstabe vorkommt)

   ]c =: 1#. b
3 2 2 2 2 2 2 3 2 2 3 2 2

~:&.|- umkehren, dann Noppensieb auftragen (ist das Zeichen einzigartig) und erneut umkehren. So finde ich die letzten Vorkommen der Zeichen in der Zeichenkette:

   ]d =. ~:&.|. a
0 0 0 0 0 0 1 0 1 1 1 1 1

* - multipliziert die Anzahl mit 1 für die letzte Position des Zeichens im Ring, ansonsten mit 0, wie oben berechnet ~:&.|

   ]e =. c * d
0 0 0 0 0 0 2 0 2 2 3 2 2

2| - Modulo 2 (setzt die Position der Zeichen, die gerade zählen, auf 0):

   ]f =. 2| e 
0 0 0 0 0 0 0 0 0 0 1 0 0

#~- Kopieren Sie das rechte Argument left arg. times (~ kehrt die Orte der Argumente um)

]f # a A

Probieren Sie es online!

Galen Ivanov
quelle
6

Brainfuck, 95 Bytes

,[<<<[[->+>>>+<<<<]>>>[-<+<->>]<<[[-]<]>[[-]>>[-]>[[-<+>]>]<<[<]<<]<<]<[->>>>[-]<<<]>>>>[->+<]>>[>]>>,]<<<[.<]

Probieren Sie es online

Wie es funktioniert

, Gets first input
[ Starts loop
    <<< Go to start of string
    [ Loop over the string
        [->+>>>+<<<<] Duplicates the current char of the string
        >>>[-<+<->>] Duplicates and subtracts the inputted char from the duplicate of the string char
        <<[[-]<] If the char is different to the input, remove the difference
        > If the char is the same
        [
            [-]>>[-]>[[-<+>]>]<<[<]<< Remove the char from the string and sets the inputted char to 0
        ]
        << Moves to the next char of the string
    ]
    >>>[->+<] adds the inputted char to the string
    >>[>]>>, gets the next input
]
<<<[.<] prints the string
Scherzen
quelle
4

Haskell , 47 Bytes

Ein weiteres Mal kommt Bruce Forte zu Hilfe.

import Data.List
foldl1(\x y->union(x\\y)$y\\x)

Probieren Sie es online!

Nimmt eine Liste von Strings auf.

Symmetrischer Unterschied ist ärgerlich ...

total menschlich
quelle
++Spart unionmit dieser Methode 2 Bytes .
Ørjan Johansen
2

R , 92 84 77 Bytes

for(i in el(strsplit(scan(,y<-''),y)))y=c(y[y!=i],if(!i%in%y)i);cat(y,sep='')

Probieren Sie es online!

-15 Bytes dank Djhurio

Erläuterung

djhurio lieferte eine ausgezeichnete R-Antwort, die eine forSchleife vermeidet - wie es R-Programmierer in der Regel instinktiv tun (ich selbst eingeschlossen). Hier ist eine R-Antwort, die eine forSchleife verwendet (und dabei einige Bytes einspart).

  • x=scan(,''); - ordnen Sie den Eingang der Variablen zu x
  • y=''; - Erstellen Sie eine leere Zeichenfolge in einer Variablen namens y
  • for(i in el(strsplit(x,'')))- Für jedes Zeichen iinx
  • y=c(y[y!=i],if(!i%in%y)i)- Weisen Sie yjedem Element zu y, das nicht gleich ist, iund fügen Sie hinzu, iwenn ies nicht bereits vorhanden wary
  • cat(y,sep='')- drucke die Elemente yohne Zwischenraum aus

Hinweis

Wenn Sie oben auf den TIO-Link klicken, finden Sie ihn in der Kopfzeile library(methods). Dies soll den Fehler behandeln, den djhurio in Bezug auf die el()Funktion hatte - die Funktion wird durch das methodsPaket bereitgestellt, das in jeder Version von R, die ich verwendet habe, standardmäßig geladen ist, aber aus irgendeinem Grund nicht von TIO. Wenn library(methods)aus dem Header entfernt und durch ersetzt unlistwird el, erhalte ich vier Bytes, aber djhurio würde dies auch tun und unsere Byteanzahl auf 96 88 bzw. 99 setzen.

duckmayr
quelle
Schön. Nie gedacht, dass die Schleife kürzer wird. Sie können es noch kürzer machen, indem Sie else-Anweisung weglassen for(i in el(strsplit(scan(,y<-''),y)))y=c(y[y!=i],if(!i%in%y)i);cat(y,sep='').
Djhurio
@djhurio - Ich weiß, es ist fast nie der Fall, dass in R eine for-Schleife bei irgendetwas hilft. Zu Ihrem Vorschlag: Tolle Idee! Der Vorschlag ist jetzt in der Antwort enthalten.
duckmayr
1
@ Djhurio - fair genug; Ich war zu beschäftigt damit, den Unterschied zu betrachten, der durch das Weglassen der else-Anweisung eingeführt wurde. Ich habe nicht gesehen, wie Sie den Anfang verändert haben. Bearbeiten Sie jetzt. Gute Arbeit!
duckmayr
1
@djhurio @duckmayr Es gibt eine 73-Byte-Lösung , die im Grunde genommen diese Lösung verwendet und einen etwas anderen Ansatz zum Extrahieren von Zeichen verwendet. Ich hatte nicht wirklich Lust, es als separate Antwort zu veröffentlichen. Beachten Sie auch, dass ...[[1]]es länger als, el(...)aber kürzer als ist unlist(...), sofern es sich ...um eine Liste der Länge 1 handelt.
Giuseppe
1
Scratch das, fand ich eine 70 bye Antwort, da 0ist das nulZeichen und wird in die leere Zeichenfolge konvertiert.
Giuseppe
2

MATL , 6 Bytes

vi"@X~

Funktioniert nicht in der TIO-Umgebung, funktioniert aber gut in der MATLAB-Implementierung, und dank eines neuen Patches können Sie es in MATL Online ausprobieren

X~Gleich setxoroder symmetrischer Unterschied, der genau das tut, was die Herausforderung verlangt. Der Rest durchläuft einfach die Eingabe i"@und beginnt mit einer leeren Zeichenfolge, indem der gesamte Stapel verkettet wird, der zu Beginn leer ist (danke Luis Mendo).

Sanchises
quelle
2

Python 2 , 56 Bytes

-2 Bytes dank xnor. -3 Bytes dank ovs.

lambda s:reduce(lambda a,c:a.replace(c,'')+c[c in a:],s)

Probieren Sie es online!

Ich habe buchstäblich nur den Pseudocode gespielt. : P

total menschlich
quelle
1
Speicher 2 Bytes: s=(s+c).replace(c,c[c in s:]).
25.
@xnor Das ist ein einfaches Golfspiel, das sehr geschickt ausgeführt wird. Vielen Dank!
Totalhuman
1
-1 Byte :s=s.replace(c,'')+c[c in s:]
Ovs
1

JavaScript (ES6), 60 Byte

s=>[...s].map(c=>s=s.match(c)?s.split(c).join``:s+c,s='')&&s

Testfälle

Arnauld
quelle
Ich portierte @ MartinEnder Retina Antwort und es war nur 45 Bytes ...
Neil
1

q , 38 Bytes

""{$[y in x;except;,][x;y]}/
Skeevey
quelle
1

APL + WIN, 19 Bytes

Logik ähnlich der Galenschen J-Lösung.

(2|+⌿⌽<\⌽c∘.=c)/c←⎕     
Graham
quelle
1

Wolfram Language (Mathematica) , 36 Byte

#//.{a___,x_,b___,x_,c___}:>{a,b,c}&

Probieren Sie es online!

Nimmt die Eingabe und Ausgabe als Liste von Zeichen.

Wie es funktioniert

Verwendet //.(Alias ReplaceRepeated), um zwei wiederholte Zeichen zu finden und beide zu löschen, bis keine wiederholten Zeichen mehr vorhanden sind. Wenn das Zeichen mehr als zweimal vorkommt, löscht Mathematica immer die ersten beiden Vorkommen. Wenn ein Charakter also ungerade oft vorkommt, ist seine letzte Instanz immer diejenige, die überlebt.

Mischa Lawrow
quelle
1

Prolog 81 Byte

a([],O,O).
a([I|J],K,O):-delete(K,I,F),(K=F->append(K,[I],M),a(J,M,O);a(J,F,O)).

Nicht verschleierte Version:

append_and_eraze([], Output, Output).
append_and_eraze([I | Input], Interim, Output) :-
    delete(Interim, I, Filtered),
    ( Interim = Filtered ->
      append(Interim, [I], Interim1),
      append_and_eraze(Input, Interim1, Output)
    ;
    append_and_eraze(Input, Filtered, Output)
    ).
  1. delete/3 Stellt sicher, dass das dritte Argument mit dem ersten Argument vereinigt wird, wobei alle Instanzen des zweiten Arguments entfernt werden.
  2. Wenn sich herausstellt, dass diese identisch sind, fügen wir das Element an (es wurde nicht entfernt).
  3. append/3 Fügt gemäß seinem Namen ein Element an die Liste an.
  4. Wir wiederholen die Elemente der Eingabe, bis wir die treffen [] (leere Liste) An diesem Punkt wird das Zwischenergebnis mit dem gewünschten Ergebnis vereinheitlicht.

Prüfung:

?- append_and_eraze(`ABCDBCCBE`, [], X), string_codes(Y, X).
X = [65, 68, 67, 66, 69],
Y = "ADCBE".

?- append_and_eraze(`ABCXYZCABXAYZ`, [], X), string_codes(Y, X).
X = [65],
Y = "A".

?- append_and_eraze(`aAABBbAbbB`, [], X), string_codes(Y, X).
X = [97, 65, 98, 66],
Y = "aAbB".

?- append_and_eraze(`GG`, [], X), string_codes(Y, X).
X = [],
Y = "".

Einige Prologe behandeln Strings in doppelten Anführungszeichen als Listen. SWI kann so konfiguriert werden, dass es dasselbe tut. Der Einfachheit halber habe ich die string_codes/2Ausgabe jedoch ordentlich formatiert.

wvxvw
quelle
1

R 84 Bytes

y=el(strsplit(scan(,""),""));cat(unique(y[colSums(outer(y,y,"=="))%%2>0],,T),sep="")

Probieren Sie es online!

Eine andere Lösung, aber hier gibt es bessere R- Antworten.

R 88 Bytes

z=table(y<-el(strsplit(scan(,""),"")));cat(setdiff(unique(y,,T),names(z[!z%%2])),sep="")

Probieren Sie es online!

Danke an Giuseppe für -7 Bytes!

Es gibt eine kürzere Antwort von duckmayr .

  1. scan(,"") Eingabe von stdin lesen.
  2. y<-el(strsplit(scan(,""),""))Eingabe nach Zeichen aufteilen und speichern unter y.
  3. z=table(y<-el(strsplit(scan(,""),"")))Berechne die Häufigkeit jedes Zeichens und speichere die resultierende Tabelle als z;
  4. unique(y,,T) Nimm einzigartige Charaktere von der rechten Seite.
  5. names(z[!z%%2]) wähle nur gerade Zählungen und extrahiere Namen.
  6. setdiff(unique(y,,T),names(z[!z%%2])) Zeichen mit gerader Anzahl entfernen.
  7. cat(setdiff(unique(y,,T),names(z[!z%%2])),sep="") Ausgabe drucken.
Djhurio
quelle
Der Grund für Ihren Fehler ist, dass el()das methodsPaket, das normalerweise standardmäßig geladen wird, nicht von TIO stammt (
siehe
Warum verwenden Sie rev(unique(rev(y)))? Würde nicht einfach unique(y)funktionieren? ooohhh warte ich sehe, du willst die eindeutigen Zeichen von rechts nach links. In diesem Fall unique(y,,T)(Einstellung fromLast=T) wird 88 Bytes .
Giuseppe
0

Alice , 9 Bytes

/X&@
\io/

Probieren Sie es online!

Erläuterung

Grundsätzlich eine Portierung von Eriks Antwort . Abgesehen von ein bisschen IP-Umleitung ist der Code wirklich nur:

i&Xo@

was macht:

i   Read all input.
&X  Fold symmetric multiset difference over the input.
o   Output the result.
@   Terminate.
Martin Ender
quelle
0

APL (Dyalog) , 16 Bytes

{(,⍨~∩)/⍣(≢⍵)⊖⍵}

Probieren Sie es online!

Wenn Fehler erlaubt wären, wären dies 9 Bytes:

(,⍨~∩)/∘⊖
Erik der Outgolfer
quelle
Was meinst du mit fehler
FrownyFrog
@FrownyFrog Die 9-Byte-Version würde ein auslösen, DOMAIN ERRORwenn die Zeichenfolge leer ist, da (,⍨~∩)sie kein vordefiniertes Identitätselement hat.
Erik der Outgolfer
0

Ruby , 53 Bytes

->s{s.reverse.uniq.select{|c|s.count(c)%2>0}.reverse}

Probieren Sie es online!

Input und Output sind beide ein Array von Zeichen. Testen Sie Codeaufrufe .charsund .joinzur Vereinfachung.

Erläuterung

Verwendet die Tatsache, dass die Buchstaben in der resultierenden Zeichenfolge ungerade oft und in der Reihenfolge von rechts nach links erscheinen.

->s{                # lambda function taking char-array argument
    s.reverse           # reverse the input
    .uniq               # get unique characters
    .select{|c|         # select only those which...
        s.count(c)%2>0      # appear in the input array an odd number of times
    }.reverse           # reverse back and return
}
Justin Mariner
quelle
0

Pyth, 13 Bytes

{_xD_Qf%/QT2Q

Nimmt Eingaben als Liste von Zeichen auf. Probieren Sie es aus!

      f     Q            (f)ilter input (Q)
        /QT              On how many times (/) each character (T) appears in the 
                           input (Q)
       %   2             Only allow odd numbers of occurences (when x % 2 = 1)
 _xD_Q                   Sort (D) descending (the first _) by the location (x) of 
                           the last (the second _) inde(x) of the target character
                           in the input (Q)
{                        Remove duplicates
Steven H.
quelle
0

Röda , 34 Bytes

{a=[]a-=_ if[_1 in a]else a+=_1;a}

Probieren Sie es online!

Dies ist eine direkte Übersetzung des Pseudocodes. Eingaben und Ausgaben werden als Zeichenströme behandelt.

Erläuterung:

{                    /* Anonymous function                   */
    a=[]             /* initialize a                         */
                     /* For each character _1 in the stream: */
    a-=_ if[_1 in a] /*  Remove it from a if a contains it   */
    else a+=_1;      /*  Otherwise append it to a            */
    a                /* Push characters in a to the stream   */
}
fergusq
quelle
0

Python 3 , 73 Bytes

Nicht die kürzeste, aber ich mag diesen Ansatz.

lambda s:''.join(c*(s.count(c)%2)*(i==s.rfind(c))for i,c in enumerate(s))

Probieren Sie es online!

Durchläuft die Zeichenfolge und behält nur die Zeichen bei, bei denen:

  • (s.count(c)%2) == 0 - Der Buchstabe erscheint eine gerade Anzahl von Malen.
  • (i==s.rfind(c)) - Der aktuelle Index ist das letzte Auftreten des betreffenden Zeichens.
FlipTack
quelle
0

REXX , 102 Bytes

a=arg(1)
s=''
do while a>''
  b=right(a,1)
  if countstr(b,a)//2 then s=b||s
  a=changestr(b,a,'')
  end
say s

Probieren Sie es online!

So funktioniert es: Nehmen Sie den Buchstaben ganz rechts, prüfen Sie, ob die Anzahl der Vorkommen gerade oder ungerade ist (was auch als Wahrheitswert gilt), und fügen Sie ihn, falls ungerade, zur Ausgabezeichenfolge hinzu. Entfernen Sie dann alle Vorkommen des Buchstabens aus der Eingabezeichenfolge. Wiederholen, bis die Eingabe erschöpft ist.

idrougge
quelle
0

Java 8, 93 Bytes

Ein Lambda von Stringbis String. Nur eine Implementierung des Pseudocodes in der Frage.

s->{String o="";for(char c:s.toCharArray())o=o.indexOf(c)<0?o+c:o.replace(c+"","");return o;}

Probieren Sie es online

Java 8, 182 Bytes

Hier ist ein weiteres Lambda des gleichen Typs, das Streams verwendet! Es ist wahrscheinlich effizienter.

s->s.join("",s.chars().mapToObj(c->(char)c+"").filter(c->s.replaceAll("[^"+c+"]","").length()%2>0).distinct().sorted((c,d)->s.lastIndexOf(c)-s.lastIndexOf(d)).toArray(String[]::new))

Probieren Sie es online

Ungolfed

s ->
    s.join(
        "",
        s.chars()
            .mapToObj(c -> (char) c + "")
            .filter(c -> s.replaceAll("[^" + c + "]", "").length() % 2 < 0)
            .distinct()
            .sorted((c, d) -> s.lastIndexOf(c) - s.lastIndexOf(d))
            .toArray(String[]::new)
    )
Jakob
quelle
0

R , 70 Bytes

function(s){for(i in utf8ToInt(s))F=c(F[F!=i],i*!i%in%F);intToUtf8(F)}

Probieren Sie es online!

Djhurio hat mich ermutigt, diese lösung zu posten. Die Antwort von Djhurio finden Sie hier .

Dies verwendet die gleiche Idee wie die Antwort von duckmayr , nutzt jedoch einen numerischen Ansatz, indem die Zeichenfolge in ihre Codepunkte konvertiert wird, anstatt sie in Zeichen aufzuteilen , und ist eher eine Funktion als ein vollständiges Programm, sodass die neue Zeichenfolge zurückgegeben werden kann, anstatt zu stdout zu drucken .

function(s) {
 for(i in utf8ToInt(s))           # convert string to codepoints and iterate over it
  F=c(F[F!=i],                    # remove duplicates and append
      i*!i%in%F)                  # 0 if in F, i otherwise
 intToUtf8(F)                     # collapse from codepoints to string
}

Eine wichtige Beobachtung ist, dass Fmit FALSEoder 0und initialisiert wird utf8ToInt(0)=="", sodass dies sowohl für die leere Zeichenfolge als auch für das korrekte Reduzieren der Codepunkte gelingt.

Giuseppe
quelle
0

PHP, 71 + 1 Bytes

while(~$c=$argn[$i++])$s=strstr($s,$c)?strtr($s,[$c=>""]):$s.$c;echo$s;

Lauf als Pipe mit -nRoder versuche es online .

Titus
quelle
0

Python 3.6 , 69 Bytes

lambda a:"".join({c:1 for c in a[::-1] if a.count(c)%2}.keys())[::-1]

Probieren Sie es online!

Die Reihenfolge beim Einfügen von Dikten bleibt in Python 3.6 erhalten.

user285259
quelle
0

SNOBOL4 (CSNOBOL4) , 97 bis 95 Byte

	S =INPUT
N	S LEN(1) . C REM . S :F(O)
	O C :S(R)
	O =O C :(N)
R	O C =:S(R)F(N)
O	OUTPUT =O
END

Probieren Sie es online!

	S =INPUT			;* read input
N	S LEN(1) . C REM . S :F(O)	;* take the first character of S and assign it to C,
					;* assign the remainder to S, and if S has no characters left, goto O
	O C :S(R)			;* if C matches anything in O, goto R, otherwise go to next line
	O =O C :(N)			;* append C to O and goto N
R	O C =:S(R)F(N)			;* as long as C matches O, replace it with ''
					;* (unassigned variables default to the null string)
					;* then goto N once it fails to match
O	OUTPUT =O			;* output the string
END					;* terminate the program
Giuseppe
quelle