Stringhe senza deduplicazione


33

introduzione

Osserviamo la seguente stringa:

AABBCCDDEFFGG

Puoi vedere che ogni lettera è stata duplicata , tranne la lettera E. Ciò significa che la lettera Eè stata de-duplicata . Quindi, l'unica cosa che dobbiamo fare qui è invertire quel processo, che ci fornisce la seguente stringa non de-duplicata :

AABBCCDDEEFFGG

Facciamo un esempio più duro:

AAAABBBCCCCDD

Puoi vedere che c'è un numero irregolare di numeri consecutivi B, quindi ciò significa che uno dei è BBstato de-duplicato dalla stringa originale. Dobbiamo solo annullare la duplicazione di questa lettera, che ci dà:

AAAABBBBCCCCDD


La sfida

Data una stringa de-duplicata non vuota , composta solo da caratteri alfabetici (solo maiuscoli o solo minuscoli), restituisce la stringa non de-duplicata . Puoi presumere che ci sarà sempre almeno un carattere de-duplicato nella stringa.


Casi test

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

Questo è , quindi vince l'invio valido più breve in byte!


@ mbomb007 Sì, ciò comporterebbe AABBBB.
Adnan,

1
Non sono sicuro di aver capito la sfida. Perché la ABBBmappa AABBBBnon lo fa AABBBBBB?
Dennis,

2
@Dennis Se separare ciascun gruppo di personaggi in gruppi di 2, si otterrebbe quanto segue: A BB B. I caratteri che non sono associati (e quindi non duplicati) devono essere duplicati, risultando AA BB BB, che è la stringa non de-duplicata.
Adnan,

8
Quindi: assicurati che ogni serie di caratteri abbia un numero pari di elementi aggiungendo al massimo un elemento alla serie?
Mad Physicist,

1
@MadPhysicist Sì, è corretto
Adnan,

Risposte:


20

MATL , 7 byte

Y'to+Y"

Provalo online! Oppure verifica tutti i casi di test .

Prendiamo 'ABBA'come esempio di input.

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'

11

Retina , 11 byte

(.)\1?
$1$1

Provalo online : contiene tutti i casi di test


1
Mi aspettavo che Retina vincesse.
Adám,

@Adám Sì, è piuttosto breve, ma quella risposta MATL è fantastica. Tutte le lingue del golf finirono con soluzioni più brevi.
mbomb007,

8

Perl, 16 byte

15 byte di codice + -pflag.

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

Per eseguirlo:

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

7

Haskell, 36 byte

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

Esempio di utilizzo: u "OOQQO"-> "OOQQOO".

Se la stringa ha almeno 2 elementi, prendi due copie del primo e aggiungi una chiamata ricorsiva con

  • il secondo elemento e il resto se i primi due elementi differiscono o
  • solo il resto

Se sono presenti meno di due elementi (uno o zero), prendere due copie dell'elenco.


6

Brachylog , 17 byte

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

Provalo online!

Spiegazione

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)

4

Rubino, 21 byte

20 byte più la -pbandiera.

gsub(/(.)\1?/){$1*2}

4

JavaScript (ES6), 37 30 byte

Salvato 7 byte utilizzando le molto più efficienti '$ 1 $ 1' come [altri] [risposte] ha fatto

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

Casi test


4

Mathematica, 41 byte

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

Funzione senza nome che immette una stringa e genera una stringa. Completamente deduplicato quindi completamente non duplicato. Non molto breve, ma per ora non potrei fare di meglio.


4

Befunge 98 , 24 byte

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

Provalo online!

$può essere facilmente sostituito con -e il 2o @con ;.

Penso che questo possa essere ulteriormente migliorato a causa -dell'inizio di entrambi -,(o $,sopra) e -\,.

Come?

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.

3

Java 7, 58 byte

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

Ungolfed:

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

Codice di prova:

Provalo qui.

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

Produzione:

AABBCCDDEEFFGG
AAAABBBBCCCCDD
AAAABBBBCCCCDDDD
HHEEYY
AAAAAAAA
NN
OOQQOO
AABBBB
AABBAA

2

PHP, 65 byte, nessuna regex

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

accetta input dall'argomento della riga di comando. Corri con -r.

regex? In PHP, la regex utilizzata dalla maggior parte delle risposte duplica ogni personaggio. sarebbe 44 byte:

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

2

Brain-Flak 69 byte

Include +3 per -c

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

Provalo online!

Spiegazione:

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


1

V 10 byte

ͨ.©±½/±±

TryItOnline

Basta trovare e sostituire regex come tutto il resto nel thread. L'unica differenza è che posso sostituire tutto ciò che richiederebbe un carattere \davanti con il carattere con lo stesso valore ASCII, ma il bit alto impostato. (Quindi (, 00101000 diventa ¨, 10101000)


1

Perl 6 , 17 byte

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

con l'opzione -p della riga di comando

Esempio:

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

1

Racchetta 261 byte

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

test:

(f "ABBBCDDEFFGGG")

Produzione:

"AABBBBCCDDEEFFGGGG"

1

05AB1E , 10 byte

.¡vy¬ygÉ×J

Provalo online!

Spiegazione

.¡           # 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

1

Python3, 102 94 byte

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

Grazie a xnor per aver salvato 8 byte! -> bithack.


Questo non mantiene le lettere nel giusto ordine.
xnor

@xnor Grazie per averlo menzionato! Fisso.
Yytsi il

Sembra buono. Puoi scrivere l'espressione x+x%2come x&-2.
xnor

@xnor Ho provato s.count(c)&-2e ha restituito una stringa vuota ...: / Qualche idea?
Yytsi il

1
Oh, hai ragione e ho fatto un errore. credox+1&-2 dovrebbe farlo. I mali vanno da soli e le probabilità si sommano ai mali.
xnor

1

R, 81 byte

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

Legge una stringa da stdin, splin in vettore di caratteri ed esegue la codifica run-length (rle). Successivamente ripeti ciascuno dei valori dalla riga, la somma delle lunghezze e delle lunghezze mod 2.

Se possiamo leggere l'input separato dallo spazio (implicitamente come un vettore / array di caratteri), possiamo saltare la parte di divisione e il programma si riduce a 64 byte:

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

1

> <> (Pesce) 39 byte

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

Abbastanza sicuro che questo può essere giocato molto usando una tecnica diversa.

Prende un input e lo confronta con lo stack corrente, se è diverso stamperà due volte il primo stack, se lo stesso li stampa entrambi.

Lo stack quando vuoto viene fornito con uno 0 che non stampa nulla, quindi può essere aggiunto ogni volta.


1

Pyth, 15 byte

Vrz8p*+hN%hN2eN

Verifica qui tutti i casi di test.

Grazie a Luis Mendo per la metodologia.

Spiegazione

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

Come spesso accade, penso che questo potrebbe essere più breve. Penso che dovrebbe esserci un modo migliore per estrarre elementi dall'elenco rispetto a quello che sto usando qui.


1

PowerShell , 28 byte

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

Provalo online!(include tutti i casi di test)

Risposta Port of the Retina . L'unico punto da notare è che abbiamo $argsinvece del solito $args[0](dal momento che -replaceeseguirà l'iterazione su ogni elemento nell'array di input, possiamo golf sull'indice) e le '$1$1'necessità devono essere virgolette singole in modo che vengano sostituite con regex variabili anziché essere trattate come variabili di PowerShell (cosa che accadrebbe se fossero doppie virgolette).


1

C, 67 byte

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

Chiama con:

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

1

Brainfuck, 22 byte

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

Provalo online.

Stampa il carattere corrente due volte, a meno che non sia uguale a un carattere appena stampato due volte.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.