Batalkan non-duplikasi string

33

pengantar

Mari kita amati string berikut:

AABBCCDDEFFGG

Anda dapat melihat bahwa setiap huruf telah digandakan , kecuali untuk surat itu E. Itu berarti bahwa surat Eitu telah diduplikasi . Jadi, satu-satunya hal yang perlu kita lakukan di sini adalah membalikkan proses itu, yang memberi kita string tidak terduplikasi berikut :

AABBCCDDEEFFGG

Mari kita ambil contoh yang lebih sulit:

AAAABBBCCCCDD

Anda dapat melihat bahwa ada jumlah yang tidak sama berturut-turut B, sehingga itu berarti bahwa salah satu dari BBitu diduplikasi dari string asli. Kami hanya perlu menghapus duplikat surat ini, yang memberi kami:

AAAABBBBCCCCDD


Tantangan

Diberikan string de-duplikat yang tidak kosong , yang hanya terdiri dari karakter alfabet (baik huruf besar atau huruf kecil saja), kembalikan string yang tidak terduplikasi . Anda dapat mengasumsikan bahwa akan selalu ada setidaknya satu karakter yang tidak terduplikasi dalam string.


Uji kasus

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

Ini adalah , jadi pengiriman terpendek yang valid dalam byte menang!

Adnan
sumber
@ mbomb007 Ya, itu akan menghasilkan AABBBB.
Adnan
1
Saya tidak yakin saya mengerti tantangannya. Mengapa ABBBdipetakan ke AABBBB, bukan AABBBBBB?
Dennis
2
@Dennis Jika Anda memisahkan masing-masing kelompok karakter ke dalam kelompok 2, Anda akan mendapatkan berikut: A BB B. Karakter yang tidak dipasangkan (dan karena itu tidak digandakan) perlu digandakan, menghasilkan AA BB BB, yang merupakan string yang tidak terduplikasi.
Adnan
8
Jadi: Pastikan bahwa setiap penayangan karakter memiliki jumlah elemen yang sama dengan menambahkan paling banyak satu elemen ke penayangan?
Fisikawan Gila
1
@MadPhysicist Ya, itu benar
Adnan

Jawaban:

20

MATL , 7 byte

Y'to+Y"

Cobalah online! Atau verifikasi semua kasus uji .

Mari kita ambil 'ABBA'contoh 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'
Luis Mendo
sumber
11

Retina , 11 byte

(.)\1?
$1$1

Cobalah online - berisi semua kotak uji

mbomb007
sumber
1
Saya berharap Retina menang.
Adám
@ Adm Ya, cukup singkat, tapi jawaban MATL itu bagus. Semua bahasa golf berakhir dengan solusi yang lebih pendek.
mbomb007
8

Perl, 16 byte

15 byte kode + -pbendera.

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

Untuk menjalankannya:

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

Haskell, 36 byte

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

Contoh penggunaan: u "OOQQO"-> "OOQQOO".

Jika string memiliki setidaknya 2 elemen, ambil dua salinan dari yang pertama dan tambahkan panggilan rekursif

  • elemen kedua dan sisanya jika dua elemen pertama berbeda atau
  • hanya sisanya

Jika ada kurang dari dua elemen (satu atau nol), ambil dua salinan dari daftar.

nimi
sumber
6

Brachylog , 17 byte

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

Cobalah online!

Penjelasan

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)
Fatalisasi
sumber
4

Ruby, 21 byte

20 byte plus -pbendera.

gsub(/(.)\1?/){$1*2}
Nilai Tinta
sumber
4

JavaScript (ES6), 37 30 byte

Disimpan 7 byte dengan menggunakan '$ 1 $ 1' yang jauh lebih efisien seperti [lainnya] [jawaban] lakukan

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

Uji kasus

Arnauld
sumber
4

Mathematica, 41 byte

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

Fungsi tanpa nama yang menginput string dan menghasilkan string. Deduplicate sepenuhnya maka sepenuhnya undeduplicate. Tidak terlalu pendek, tapi aku tidak bisa melakukan yang lebih baik untuk saat ini.

Greg Martin
sumber
4

Menembus 98 , 24 byte

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

Cobalah secara Online!

$dapat dengan mudah diganti dengan -, dan ke-2 @dengan ;.

Saya pikir ini bisa golf lebih lanjut karena -pada awal keduanya -,(atau di $,atas) dan -\,.

Bagaimana?

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
sumber
3

Java 7, 58 byte

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

Tidak Disatukan:

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

Kode uji:

Coba di sini.

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

Keluaran:

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

PHP, 65 byte, tidak ada regex

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

mengambil input dari argumen baris perintah. Jalankan dengan -r.

regex? Di PHP, regex yang digunakan oleh sebagian besar jawaban menduplikasi setiap karakter. akan menjadi 44 byte:

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

Brain-Flak 69 Bytes

Termasuk +3 untuk -c

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

Cobalah secara Online!

Penjelasan:

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
sumber
1

V 10 byte

ͨ.©±½/±±

TryItOnline

Temukan dan ganti regex seperti yang lainnya di utas. Satu-satunya perbedaan adalah bahwa saya dapat mengganti apa saja yang memerlukan \di depannya dengan karakter dengan nilai ascii yang sama, tetapi bit set tinggi. (Jadi (, 00101000 menjadi ¨, 10101000)

nmjcman101
sumber
1

Perl 6 , 17 byte

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

dengan -p command-line switch

Contoh:

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

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

Tidak Disatukan:

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

Pengujian:

(f "ABBBCDDEFFGGG")

Keluaran:

"AABBBBCCDDEEFFGGGG"
juga
sumber
1

05AB1E , 10 byte

.¡vy¬ygÉ×J

Cobalah online!

Penjelasan

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

Python3, 102 94 byte

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

Terima kasih kepada xnor karena telah menghemat 8 byte! -> bithack.

Yytsi
sumber
Ini tidak menyimpan surat-surat dalam urutan yang benar.
xnor
@ xnor Terima kasih telah menyebutkan! Tetap.
Yytsi
Kelihatan bagus. Anda dapat menuliskan ekspresi x+x%2sebagai x&-2.
xnor
@ xnor saya mencoba s.count(c)&-2dan mengembalikan sebuah string kosong ...: / Ada pikiran?
Yytsi
1
Oh, Anda benar dan saya membuat kesalahan. Saya pikir x+1&-2harus melakukannya. Merata pergi ke diri mereka sendiri dan peluang bulat untuk meratakan.
xnor
1

R, 81 byte

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

Membaca string dari stdin, splin menjadi vektor karakter dan melakukan pengkodean run-length (rle). Selanjutnya ulangi setiap nilai dari rle, jumlah panjang dan panjang mod2 .

Jika kita dapat membaca input yang dipisahkan oleh spasi (secara implisit sebagai vektor / larik karakter) maka kita dapat melewati bagian pemisahan dan program dikurangi menjadi 64 byte:

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

> <> (Ikan) 39 byte

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

Cukup yakin ini bisa banyak bermain golf menggunakan teknik yang berbeda.

Dibutuhkan input dan membandingkannya dengan item tumpukan saat ini, jika berbeda maka akan mencetak item tumpukan pertama dua kali, jika sama mencetak keduanya.

Tumpukan saat kosong diberikan dengan 0 yang tidak mencetak apa pun sehingga dapat ditambahkan kapan saja.

Pelican teal
sumber
1

Pyth, 15 byte

Vrz8p*+hN%hN2eN

Verifikasi semua kasus uji di sini.

Terima kasih kepada Luis Mendo untuk metodologi ini.

Penjelasan

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

Seperti yang sering terjadi, saya merasa ini bisa lebih pendek. Saya pikir harus ada cara yang lebih baik untuk mengekstrak elemen dari daftar daripada apa yang saya gunakan di sini.

Mike Bufardeci
sumber
1

PowerShell , 28 byte

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

Cobalah online! (termasuk semua kasus uji)

Port of the Retina menjawab . Satu-satunya hal yang perlu diperhatikan adalah kita mendapatkan $argsalih - alih yang biasa $args[0](karena -replacekehendak iterate atas setiap item dalam array input, kita dapat bermain golf dari indeks), dan '$1$1'perlu menjadi tanda kutip tunggal sehingga mereka diganti dengan regex variabel daripada diperlakukan sebagai variabel PowerShell (yang akan terjadi jika mereka adalah kuotasi ganda).

AdmBorkBork
sumber
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);}

Telepon dengan:

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

brainfuck, 22 byte

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

Cobalah online.

Mencetak karakter saat ini dua kali, kecuali itu sama dengan karakter yang baru saja dicetak dua kali.

Mitch Schwartz
sumber