Nicht-Deduplizieren von Strings

33

Einführung

Beobachten wir die folgende Zeichenfolge:

AABBCCDDEFFGG

Sie können sehen, dass jeder Buchstabe mit Ausnahme des Buchstabens dupliziert wurde E. Das bedeutet , dass der Brief Ewurde dedupliziert . Das Einzige, was wir hier tun müssen, ist, diesen Prozess umzukehren, wodurch wir die folgende nicht-duplizierte Zeichenfolge erhalten:

AABBCCDDEEFFGG

Nehmen wir ein schwierigeres Beispiel:

AAAABBBCCCCDD

Sie können sehen, dass eine ungerade Anzahl aufeinanderfolgender Zeichenfolgen Bvorliegt, was bedeutet, dass eine der BBZeichenfolgen von der ursprünglichen Zeichenfolge desupliziert wurde. Wir brauchen nur diesen Brief zu entduplizieren, was uns ergibt:

AAAABBBBCCCCDD


Die Herausforderung

Bei einer nicht leeren, nicht duplizierten Zeichenfolge, die nur aus alphabetischen Zeichen besteht (entweder nur in Groß- oder Kleinbuchstaben), wird die nicht duplizierte Zeichenfolge zurückgegeben. Sie können davon ausgehen, dass die Zeichenfolge immer mindestens ein nicht dupliziertes Zeichen enthält.


Testfälle

AAABBBCCCCDDDD    -->    AAAABBBBCCCCDDDD
HEY               -->    HHEEYY
AAAAAAA           -->    AAAAAAAA
N                 -->    NN
OOQQO             -->    OOQQOO
ABBB              -->    AABBBB
ABBA              -->    AABBAA

Das ist , also gewinnt die kürzeste gültige Einsendung in Bytes!

Adnan
quelle
@ mbomb007 Ja, das würde dazu führen AABBBB.
Adnan
1
Ich bin mir nicht sicher, ob ich die Herausforderung verstehe. Warum macht ABBBKarte auf AABBBB, nicht AABBBBBB?
Dennis
2
@ Dennis Wenn Sie jede Gruppe von Zeichen in Gruppen von 2 trennen, würden Sie die folgende erhalten: A BB B. Die Zeichen, die nicht gepaart (und daher nicht dupliziert) sind, müssen dupliziert werden, was dazu führt AA BB BB, dass es sich um die nicht-duplizierte Zeichenfolge handelt.
Adnan
8
Also: Sicherstellen, dass jede Zeichenfolge eine gerade Anzahl von Elementen enthält, indem höchstens ein Element zur Folge hinzugefügt wird?
Mad Physicist
1
@ MadPhysicist Ja, das ist richtig
Adnan

Antworten:

20

MATL , 7 Bytes

Y'to+Y"

Probieren Sie es online! Oder überprüfen Sie alle Testfälle .

Nehmen wir 'ABBA'als Beispiel die Eingabe.

Y'   % Implicit input. Run-length decoding
     % STACK: 'ABA', [1 2 1]
t    % Duplicate top of the stack
     % STACK: 'ABA', [1 2 1], [1 2 1]
o    % Modulo 2
     % STACK: 'ABA', [1 2 1], [1 0 1]
+    % Add, element-wise
     % STACK: 'ABA', [2 2 2]
Y"   % Run-length encoding. Implicit display
     % STACK: 'AABBAA'
Luis Mendo
quelle
11

Retina , 11 Bytes

(.)\1?
$1$1

Online testen - enthält alle Testfälle

mbomb007
quelle
1
Ich hatte erwartet, dass Retina gewinnt.
Adám
@ Adám Ja, es ist ziemlich kurz, aber diese MATL-Antwort ist großartig. Alle Golfsprachen endeten mit kürzeren Lösungen.
mbomb007
8

Perl, 16 Bytes

15 Byte Code + -pFlag.

s/(.)\1?/$1$1/g

Um es auszuführen:

perl -pe 's/(.)\1?/$1$1/g' <<< 'HEY'
Dada
quelle
7

Haskell, 36 Bytes

u(a:b:c)=a:a:u([b|a/=b]++c)
u x=x++x

Anwendungsbeispiel: u "OOQQO"-> "OOQQOO".

Wenn die Zeichenfolge mindestens 2 Elemente enthält, nehmen Sie zwei Kopien der ersten und fügen Sie einen rekursiven Aufruf mit an

  • das zweite Element und der Rest, wenn sich die ersten beiden Elemente unterscheiden oder
  • nur der rest

Wenn weniger als zwei Elemente (eins oder null) vorhanden sind, erstellen Sie zwei Kopien der Liste.

nimi
quelle
6

Brachylog , 17 Bytes

@b:{~b#=.l#e,|}ac

Probieren Sie es online!

Erläuterung

Example input: "ABBB"

@b                  Blocks: Split into ["A", "BBB"]
  :{          }a    Apply the predicate below to each element of the list: ["AA", "BBBB"]
                c   Concatenate: "AABBBB"

    ~b#=.             Output is the input with an additional element at the beginning, and
                        all elements of the output are the same (e.g. append a leading "B")
        .l#e,         The length of the Output is an even number
             |        Or: Input = Output (i.e. do nothing)
Tödlich
quelle
4

Ruby, 21 Bytes

20 Bytes plus das -pFlag.

gsub(/(.)\1?/){$1*2}
Wert Tinte
quelle
4

JavaScript (ES6), 37-30 Byte

Gespeichert 7 Bytes durch die viel effiziente ‚$ 1 $ 1‘ wie mit [andere] [Antworten] tat

s=>s.replace(/(.)\1?/g,'$1$1')

Testfälle

Arnauld
quelle
4

Mathematica, 41 Bytes

s=StringReplace;s[s[#,a_~~a_->a],b_->b~~b]&

Unbenannte Funktion, die eine Zeichenfolge eingibt und eine Zeichenfolge ausgibt. Vollständige Deduplizierung, dann vollständige Nicht-Deduplizierung. Nicht wirklich kurz, aber ich könnte es vorerst nicht besser machen.

Greg Martin
quelle
4

Befunge 98 , 24 Bytes

#@~#;:::#@,~-:!j;$,;-\,;

Probieren Sie es online!

$kann leicht ersetzt werden mit -, und die 2. @mit ;.

Ich denke, dies kann aufgrund der -am Anfang von beiden -,(oder $,höher) und weiter golfen werden -\,.

Wie?

Stack notation:  bottom [A, B, C, D] top

#@~     Pushes the first character onto the stack (C henceforth) and ends if EOF
#;      No-op to be used later
:::     Now stack is [C, C, C, C]

#@,~    Prints C, and if EOF is next (odd consecutive Cs), prints again and ends
        Lets call the next character D

-       Now stack is [C, C, C-D]
:!j;    If C == D, go to "$," Else, go to "-\,"

===(C == D)===

$,      C == D (i.e. a pair of Cs) so we discard top and print C (Stack is now [C])
;-\,;   Skipped, IP wraps, and loop starts again

===(C != D)===

-       Stack is [C, C-(C-D)]  By expanding: [C, C - C + D] or just [C, D]
\,      Prints C (Stack is now [D])

;#@~#;  This is skipped, because we already read the first character of a set of Ds,
        and this algorithm works by checking the odd character in a set of
        consecutive similar characters. We already read D, so we don't
        need to read another character.
MilderMilquetoast
quelle
3

Java 7, 58 Bytes

String c(String s){return s.replaceAll("(.)\\1?","$1$1");}

Ungolfed:

String c(String s){
  return s.replaceAll("(.)\\1?", "$1$1");
}

Testcode:

Probieren Sie es hier aus.

class M{
  static String c(String s){return s.replaceAll("(.)\\1?","$1$1");}

  public static void main(String[] a){
    System.out.println(c("AABBCCDDEFFGG"));
    System.out.println(c("AAAABBBCCCCDD"));
    System.out.println(c("AAABBBCCCCDDDD"));
    System.out.println(c("HEY"));
    System.out.println(c("AAAAAAA"));
    System.out.println(c("N"));
    System.out.println(c("OOQQO"));
    System.out.println(c("ABBB"));
    System.out.println(c("ABBA"));
  }
}

Ausgabe:

AABBCCDDEEFFGG
AAAABBBBCCCCDD
AAAABBBBCCCCDDDD
HHEEYY
AAAAAAAA
NN
OOQQOO
AABBBB
AABBAA
Kevin Cruijssen
quelle
2

PHP, 65 Bytes, kein regulärer Ausdruck

while(""<$c=($s=$argv[1])[$i])if($c!=$s[++$i]||!$k=!$k)echo$c.$c;

Nimmt Eingaben vom Kommandozeilenargument entgegen. Laufen Sie mit -r.

Regex? In PHP dupliziert der reguläre Ausdruck, der von den meisten Antworten verwendet wird, jedes Zeichen. wäre 44 Bytes:

<?=preg_replace("#(.)\1?#","$1$1",$argv[1]);
Titus
quelle
2

Brain-Flak 69 Bytes

Beinhaltet +3 für -c

{((({}<>))<>[({})]<(())>){((<{}{}>))}{}{(<{}{}>)}{}}<>{({}<>)<>}<>

Probieren Sie es online!

Erläuterung:

Part 1:
{((({}<>))<>[({})]<(())>){((<{}{}>))}{}{(<{}{}>)}{}}<>

{                                                  }   # loop through all letters
 (   {}     [ {} ]<(())>){((<{}{}>))}{}                # equals from the wiki   
                                                       # but first:
  ((  <>))<>                                           # push the top letter on the other 
                                                       # stack twice  
             (  )                                      # push the second letter back on
                                       {        }      # if they were equal:
                                        (<    >)       # push a 0 to exit this loop
                                          {}{}         # after popping the 1 from the 
                                                       # comparison and the next letter
                                                       # (the duplicate)
                                                 {}    # pop the extra 0
                                                    <> # switch stacks

Part 2 (at this point, everything is duplicated in reverse order):
{({}<>)<>}<>

{        }   # for every letter:
 ({}<>)      # move the top letter to the other stack
       <>    # and switch back
          <> # Finally switch stacks and implicitly print
Riley
quelle
1

V 10 Bytes

ͨ.©±½/±±

TryItOnline

Nur ein Regex wie alle anderen im Thread finden und ersetzen. Der einzige Unterschied ist, dass ich alles, was ein \davor erfordert , durch das Zeichen mit demselben ASCII-Wert ersetzen kann , aber das hohe Bit gesetzt ist. (So (wird 00101000 zu ¨10101000)

nmjcman101
quelle
1

Perl 6 , 17 Bytes

s:g/(.)$0?/$0$0/

mit -p Befehlszeilenoption

Beispiel:

$ perl6 -pe 's:g/(.)$0?/$0$0/' <<< 'AAABBBCCCCDDDD
> HEY
> AAAAAAA
> N
> OOQQO
> ABBB
> ABBA'
AAAABBBBCCCCDDDD
HHEEYY
AAAAAAAA
NN
OOQQOO
AABBBB
AABBAA
Brad Gilbert b2gills
quelle
1

Schläger 261 Bytes

(let((l(string->list s))(r reverse)(c cons)(e even?)(t rest)(i first))(let p((l(t l))(ol(c(i l)'())))
(cond[(empty? l)(list->string(if(e(length ol))(r ol)(r(c(i ol)ol))))][(or(equal?(i ol)(i l))(e(length ol)))
(p(t l)(c(i l)ol))][(p(t l)(c(i l)(c(i ol)ol)))])))

Ungolfed:

(define (f s)
  (let ((l (string->list s)))
    (let loop ((l (rest l))
               (ol (cons (first l) '())))
      (cond
        [(empty? l)
         (list->string(if (even? (length ol))
                          (reverse ol)
                          (reverse (cons (first ol) ol))))]
        [(or (equal? (first ol) (first l)) 
             (even? (length ol)))
         (loop (rest l) (cons (first l) ol))]
        [else
         (loop (rest l) (cons (first l) (cons (first ol) ol)))] ))))

Testen:

(f "ABBBCDDEFFGGG")

Ausgabe:

"AABBBBCCDDEEFFGGGG"
rnso
quelle
1

05AB1E , 10 Bytes

.¡vy¬ygÉ×J

Probieren Sie es online!

Erläuterung

.¡           # split string into groups of the same char
  v          # for each group
   y         # push the group
    ¬        # push the char the group consists of
     yg      # push the length of the group
       É     # check if the length of the group is odd
        ×    # repeat the char is-odd times (0 or 1)
         J   # join to string
Emigna
quelle
1

Python3, 102 bis 94 Bytes

from collections import*
lambda s:"".join(c*(s.count(c)+1&-2)for c in OrderedDict.fromkeys(s))

Danke an xnor für das Speichern von 8 Bytes! -> Bithack.

Yytsi
quelle
Dies hält die Buchstaben nicht in der richtigen Reihenfolge.
Xnor
@xnor Danke für die Erwähnung! Fest.
Yytsi
Sieht gut aus. Sie können den Ausdruck x+x%2als schreiben x&-2.
Xnor
@xnor Ich habe es versucht s.count(c)&-2und es gab eine leere Zeichenfolge zurück ...: / Irgendwelche Gedanken?
Yytsi
1
Oh, du hast recht und ich habe einen Fehler gemacht. Ich denke x+1&-2sollte es tun. Evens gehen für sich und die Gewinnchancen werden aufgerundet.
16.
1

R, 81 Bytes

r=rle(el(strsplit(scan(,""),"")));cat(do.call("rep",list(r$v,r$l+r$l%%2)),sep="")

Liest einen String aus stdin, splintet in einen Vektor von Zeichen und führt eine Lauflängencodierung (rle) durch. Wiederholen Sie anschließend die einzelnen Werte aus der Reihe, der Summe der Längen und der Längen mod 2.

Wenn wir durch Leerzeichen getrennte Eingaben lesen können (implizit als Vektor / Array von Zeichen), können wir den Aufteilungsteil überspringen und das Programm reduziert sich auf 64 Bytes:

r=rle(scan(,""));cat(do.call("rep",list(r$v,r$l+r$l%%2)),sep="")
Billywob
quelle
1

> <> (Fisch) 39 Bytes

0v ;oo:~/:@@:@=?!voo
 >i:1+?!\|o !:  !<

Ich bin mir ziemlich sicher, dass man mit einer anderen Technik viel Golf spielen kann.

Es nimmt eine Eingabe entgegen und vergleicht sie mit dem aktuellen Stapelelement. Wenn es anders ist, wird das erste Stapelelement zweimal gedruckt, wenn es dasselbe ist, werden beide gedruckt.

Der Stapel wird, wenn er leer ist, mit einer 0 versorgt, die nichts druckt, und kann jederzeit angehängt werden.

Blaugrüner Pelikan
quelle
1

Pyth, 15 Bytes

Vrz8p*+hN%hN2eN

Überprüfen Sie hier alle Testfälle.

Vielen Dank an Luis Mendo für die Methodik.

Erläuterung

Vrz8p*+hN%hN2eN    z autoinitializes to the input
 rz8               run-length encode the input, returned as list of tuples (A -> [[1,"A"]])
V                  for every element N in this list
      +hN          add the head element of N (the number in the tuple)
         %hN2      to the head element of N mod 2
     *       eN    repeat the tail element of N that many times (the letter in the tuple)
    p              print repeated character without trailing newline

Wie so oft habe ich das Gefühl, dass dies kürzer sein könnte. Ich denke, es sollte einen besseren Weg geben, um Elemente aus der Liste zu extrahieren, als den, den ich hier verwende.

Mike Bufardeci
quelle
1

PowerShell , 28 Byte

$args-replace'(.)\1?','$1$1'

Probieren Sie es online! (beinhaltet alle Testfälle)

Port of the Retina antworten . Die einzigen Punkte, die wir beachten müssen, sind die, die wir $argsanstelle des Üblichen haben $args[0](da das -replacejedes Element im Eingabearray durchlaufen wird, können wir vom Index abschneiden), und die '$1$1'müssen einfache Anführungszeichen sein, damit sie durch den regulären Ausdruck ersetzt werden Variablen, anstatt als PowerShell-Variablen behandelt zu werden (was passieren würde, wenn sie in doppelte Anführungszeichen gesetzt würden).

AdmBorkBork
quelle
1

C 67 Bytes

i;f(char*s,char*d){i=*s++;*d++=i;*d++=i;*s?f(i-*s?s:++s,d):(*d=0);}

Rufen Sie an mit:

int main()
{
    char *in="AAABBBCCCCDDDD";
    char out[128];
    f(in,out);
    puts(out);
}
Steadybox
quelle
1

Brainfuck, 22 Bytes

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

Probieren Sie es online aus.

Druckt das aktuelle Zeichen zweimal, es sei denn, es entspricht einem Zeichen, das gerade zweimal gedruckt wurde.

Mitch Schwartz
quelle