Annulation de la duplication des chaînes

33

introduction

Observons la chaîne suivante:

AABBCCDDEFFGG

Vous pouvez voir que chaque lettre a été dupliquée , à l'exception de la lettre E. Cela signifie que la lettre Ea été dédoublée . Donc, la seule chose que nous devons faire ici est d'inverser ce processus, ce qui nous donne les éléments suivants non dédupliquées chaîne:

AABBCCDDEEFFGG

Prenons un exemple plus difficile:

AAAABBBCCCCDD

Vous pouvez voir qu'il y a un nombre impair de suites B, ce qui signifie que l'un des fichiers a BBété dédupliqué de la chaîne d'origine. Il nous suffit de dé-dupliquer cette lettre, qui nous donne:

AAAABBBBCCCCDD


Le défi

Compte tenu d' un non-vide dédupliquées chaîne, composée de seulement des caractères alphabétiques (soit uniquement en majuscules ou en minuscules seulement), le retour non dédupliquées chaîne. Vous pouvez supposer qu'il y aura toujours au moins un caractère dédupliqué dans la chaîne.


Cas de test

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

C'est du , donc la soumission valide la plus courte en octets gagne!

Adnan
la source
@ mbomb007 Oui, cela aboutirait à AABBBB.
Adnan
1
Je ne suis pas sûr de comprendre le défi. Pourquoi la ABBBcarte à AABBBB, pas AABBBBBB?
Dennis
2
@Dennis Si vous séparer chaque groupe de personnages en groupes de 2, vous obtiendrez ce qui suit: A BB B. Les caractères qui ne sont pas associés (et donc non dupliqués) doivent être dupliqués, ce AA BB BBqui correspond à la chaîne non dédupliquée.
Adnan
8
Donc: Assurez-vous que chaque série de caractères a un nombre pair d’éléments en ajoutant au plus un élément à la série?
Mad Physicist
1
@MadPhysicist Oui, c'est exact
Adnan

Réponses:

20

MATL , 7 octets

Y'to+Y"

Essayez-le en ligne! Ou vérifiez tous les cas de test .

Prenons 'ABBA'comme exemple l'entrée.

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
la source
11

Rétine , 11 octets

(.)\1?
$1$1

Essayez-le en ligne - contient tous les cas de test

mbomb007
la source
1
Je m'attendais à ce que Retina gagne.
Adám
@ Adám Oui, c'est assez court, mais cette réponse MATL est excellente. Toutes les langues de golf ont abouti à des solutions plus courtes.
mbomb007
8

Perl, 16 octets

15 octets de code + -pdrapeau.

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

Pour l'exécuter:

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

Haskell, 36 octets

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

Exemple d'utilisation: u "OOQQO"-> "OOQQOO".

Si la chaîne a au moins 2 éléments, prenez deux copies du premier et ajoutez un appel récursif avec

  • le deuxième élément et le reste si les deux premiers éléments diffèrent ou
  • juste le reste

S'il y a moins de deux éléments (un ou zéro), prenez deux copies de la liste.

nimi
la source
6

Brachylog , 17 octets

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

Essayez-le en ligne!

Explication

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)
Fataliser
la source
4

Ruby, 21 octets

20 octets plus le -pdrapeau.

gsub(/(.)\1?/){$1*2}
Valeur d'encre
la source
4

JavaScript (ES6), 37 à 30 octets

Économisé 7 octets en utilisant le '$ 1 $ 1' beaucoup plus efficace comme le faisaient [autre] [réponses]

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

Cas de test

Arnauld
la source
4

Mathematica, 41 octets

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

Fonction sans nom qui entre une chaîne et en sort une chaîne. Dédupliquer complètement puis complètement non dédupliqué. Pas vraiment court, mais je ne pourrais pas faire mieux pour le moment.

Greg Martin
la source
4

Befunge 98 , 24 octets

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

Essayez-le en ligne!

$peut être facilement remplacé par -, et le second @avec ;.

Je pense que cela peut être joué plus loin en raison -du début des deux -,(ou $,plus) et -\,.

Comment?

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.
MildlyMilquetoast
la source
3

Java 7, 58 octets

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

Ungolfed:

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

Code de test:

Essayez ici.

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"));
  }
}

Sortie:

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

PHP, 65 octets, pas de regex

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

prend en entrée l'argument de la ligne de commande. Courez avec -r.

regex? En PHP, l'expression régulière utilisée par la plupart des réponses duplique chaque caractère. serait 44 octets:

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

Brain-Flak 69 Octets

Comprend +3 pour -c

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

Essayez-le en ligne!

Explication:

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
la source
1

V 10 octets

ͨ.©±½/±±

TryItOnline

Juste une recherche et remplacer regex comme tout le reste dans le fil. La seule différence est que je peux remplacer tout ce qui nécessiterait un \devant avec le caractère ayant la même valeur ASCII, mais le bit haut défini. (Donc (, 00101000 devient ¨, 10101000)

nmjcman101
la source
1

Perl 6 , 17 octets

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

avec l'option de ligne de commande -p

Exemple:

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

Raquette 261 octets

(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)))] ))))

Essai:

(f "ABBBCDDEFFGGG")

Sortie:

"AABBBBCCDDEEFFGGGG"
rnso
la source
1

05AB1E , 10 octets

.¡vy¬ygÉ×J

Essayez-le en ligne!

Explication

.¡           # 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
la source
1

Python3, 102 à 94 octets

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

Merci à xnor d’ avoir économisé 8 octets! -> bithack.

Yytsi
la source
Cela ne garde pas les lettres dans le bon ordre.
xnor
@xnor Merci d'avoir mentionné! Fixé.
Yytsi
Cela semble bon. Vous pouvez écrire l'expression x+x%2comme x&-2.
xnor
@xnor j'ai essayé s.count(c)&-2et il a renvoyé une chaîne vide ...: / Des pensées?
Yytsi
1
Oh, tu as raison et j'ai commis une erreur. Je pense que x+1&-2devrait le faire. Les choses vont à elles-mêmes et les chances se rapprochent.
xnor
1

R, 81 octets

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

Lit une chaîne de stdin, divise en vecteur de caractères et effectue un codage de longueur d'exécution (rle). Répétez ensuite les valeurs de chaque élément à partir du rôle, de la somme des longueurs et des longueurs mod 2.

Si nous pouvons lire les entrées séparées par un espace (implicitement sous forme de vecteur / tableau de caractères), nous pouvons alors ignorer la partie division et le programme réduit à 64 octets:

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

> <> (Poisson) 39 octets

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

Je suis sûr que cela peut être joué beaucoup au golf avec une technique différente.

Il prend une entrée et compare à l'élément de pile actuel. S'il est différent, il imprimera le premier élément de pile deux fois, si le même élément les imprime tous les deux.

La pile à vide reçoit un 0 qui n'imprime rien et peut donc être ajoutée à tout moment.

Sarcelle
la source
1

Pyth, 15 octets

Vrz8p*+hN%hN2eN

Vérifiez tous les cas de test ici.

Merci à Luis Mendo pour la méthodologie.

Explication

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

Comme souvent, j’ai le sentiment que cela pourrait être plus court. Je pense qu'il devrait exister un meilleur moyen d'extraire des éléments de la liste que ce que j'utilise ici.

Mike Bufardeci
la source
1

PowerShell , 28 octets

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

Essayez-le en ligne! (inclut tous les cas de test)

Le port de la rétine répond . Les seuls points à noter sont ceux que nous avons $argsau lieu de l’habituel $args[0](puisque l’ -replaceitération sera faite sur chaque élément du tableau d’entrée, nous pouvons jouer en dehors de l’index), et les '$1$1'guillemets simples doivent être remplacés par la regex variables plutôt que d'être traitées comme des variables PowerShell (ce qui se produirait si elles étaient doubles guillemets).

AdmBorkBork
la source
1

C, 67 octets

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

Appeler avec:

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

brainfuck, 22 octets

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

Essayez-le en ligne.

Imprime le caractère actuel deux fois, sauf s'il est égal à un caractère qui vient d'être imprimé deux fois.

Mitch Schwartz
la source