Chuỗi không trùng lặp


33

Giới thiệu

Hãy quan sát chuỗi sau:

AABBCCDDEFFGG

Bạn có thể thấy rằng mọi chữ cái đã được sao chép , ngoại trừ chữ cái E. Điều đó có nghĩa là bức thư Eđã được sao chép lại . Vì vậy, điều duy nhất chúng ta cần làm ở đây là đảo ngược quá trình đó, cung cấp cho chúng ta chuỗi không trùng lặp sau:

AABBCCDDEEFFGG

Hãy lấy một ví dụ khó hơn:

AAAABBBCCCCDD

Bạn có thể thấy rằng có một số lượng không đồng đều liên tiếp B, vì vậy điều đó có nghĩa là một trong số đó BBđã được sao chép lại từ chuỗi ban đầu. Chúng tôi chỉ cần hủy bỏ trùng lặp thư này, cung cấp cho chúng tôi:

AAAABBBBCCCCDD


Các thách thức

Cho một chuỗi không trùng lặp không trống , chỉ bao gồm các ký tự chữ cái (chỉ viết hoa hoặc chỉ viết thường), trả về chuỗi không trùng lặp . Bạn có thể giả định rằng sẽ luôn có ít nhất một ký tự được nhân đôi trong chuỗi.


Các trường hợp thử nghiệm

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

Đây là , vì vậy bài nộp hợp lệ ngắn nhất tính bằng byte sẽ thắng!


@ mbomb007 Có, điều đó sẽ dẫn đến AABBBB.
Ad Nam

1
Tôi không chắc là tôi hiểu thử thách. Tại sao ABBBbản đồ đến AABBBB, không AABBBBBB?
Dennis

2
@Dennis Nếu bạn tách từng nhóm nhân vật thành các nhóm 2, bạn sẽ nhận được những điều sau đây : A BB B. Các ký tự không được ghép nối (và do đó không được sao chép) cần được sao chép, dẫn đến AA BB BB, đó là chuỗi không được sao chép.
Ad Nam

8
Vì vậy: Đảm bảo rằng mỗi lần chạy ký tự có số phần tử chẵn bằng cách thêm tối đa một phần tử vào phần chạy?
Nhà vật lý điên

1
@MadPhysicist Vâng, đúng vậy
Adnan

Câu trả lời:



11

Võng mạc , 11 byte

(.)\1?
$1$1

Dùng thử trực tuyến - chứa tất cả các trường hợp thử nghiệm


1
Tôi dự đoán Retina sẽ thắng.
Adám

@ Adám Vâng, nó khá ngắn, nhưng câu trả lời MATL rất hay. Tất cả các ngôn ngữ chơi golf đã kết thúc với các giải pháp ngắn hơn.
mbomb007

8

Perl, 16 byte

15 byte mã + -pcờ.

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

Để chạy nó:

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

Ví dụ sử dụng: u "OOQQO"-> "OOQQOO".

Nếu chuỗi có ít nhất 2 phần tử, hãy lấy hai bản sao của phần đầu tiên và nối một cuộc gọi đệ quy với

  • phần tử thứ hai là phần còn lại nếu hai phần tử thứ nhất khác nhau hoặc
  • chỉ là phần còn lại

Nếu có ít hơn hai yếu tố (một hoặc không), hãy lấy hai bản sao của danh sách.


6

Brachylog , 17 byte

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

Hãy thử trực tuyến!

Giải trình

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

JavaScript (ES6), 37 30 byte

Đã lưu 7 byte bằng cách sử dụng '$ 1 $ 1' hiệu quả hơn nhiều như [khác] [câu trả lời] đã làm

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

Các trường hợp thử nghiệm


4

Toán học, 41 byte

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

Hàm không tên được nhập vào một chuỗi và xuất ra một chuỗi. Hoàn toàn lặp lại sau đó hoàn toàn không trùng lặp. Không thực sự ngắn, nhưng tôi không thể làm tốt hơn bây giờ.


4

Befunge 98 , 24 byte

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

Hãy thử trực tuyến!

$có thể dễ dàng thay thế bằng -, và thứ 2 @với ;.

Tôi nghĩ rằng điều này có thể được chơi golf hơn nữa do -vào đầu của cả hai -,(hoặc $,ở trên) và -\,.

Làm sao?

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

Ung dung:

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

Mã kiểm tra:

Hãy thử nó ở đây.

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

Đầu ra:

AABBCCDDEEFFGG
AAAABBBBCCCCDD
AAAABBBBCCCCDDDD
HHEEYY
AAAAAAAA
NN
OOQQOO
AABBBB
AABBAA

2

PHP, 65 byte, không có biểu thức chính quy

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

lấy đầu vào từ đối số dòng lệnh. Chạy với -r.

regex? Trong PHP, regex được sử dụng bởi hầu hết các câu trả lời trùng lặp mọi ký tự. sẽ là 44 byte:

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

2

Brain-Flak 69 byte

Bao gồm +3 cho -c

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

Hãy thử trực tuyến!

Giải trình:

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

ͨ.©±½/±±

Dùng thử

Chỉ cần tìm và thay thế regex như tất cả phần còn lại trong chuỗi. Sự khác biệt duy nhất là tôi có thể thay thế bất cứ thứ gì yêu cầu \phía trước nó bằng ký tự có cùng giá trị ascii, nhưng bộ bit cao. (Vì vậy (, 00101000 trở thành ¨, 10101000)


1

Perl 6 , 17 byte

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

với chuyển đổi dòng lệnh -p

Thí dụ:

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

1

Vợt 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)))])))

Ung dung:

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

Kiểm tra:

(f "ABBBCDDEFFGGG")

Đầu ra:

"AABBBBCCDDEEFFGGGG"

1

05AB1E , 10 byte

.¡vy¬ygÉ×J

Hãy thử trực tuyến!

Giải trình

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

Cảm ơn xnor vì đã tiết kiệm 8 byte! -> bithack.


Điều này không giữ các chữ cái theo đúng thứ tự.
xnor

@xnor Cảm ơn đã đề cập! Đã sửa.
Yytsi

Có vẻ tốt. Bạn có thể viết biểu thức x+x%2như x&-2.
xnor

@xnor Tôi đã thử s.count(c)&-2và nó trả về một chuỗi trống ...: / Bạn có suy nghĩ gì không?
Yytsi

1
Ồ, bạn nói đúng và tôi đã phạm sai lầm. Tôi nghĩ x+1&-2nên làm điều đó. Evens tự đi và tỷ lệ cược tròn lên để phát triển.
xnor

1

R, 81 byte

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

Đọc một chuỗi từ stdin, splin thành vectơ ký tự và thực hiện mã hóa độ dài chạy (rle). Sau đó lặp lại từng giá trị từ rle, tổng độ dài và mod độ dài 2.

Nếu chúng ta có thể đọc đầu vào được phân tách bằng dấu cách (ngầm định là một vectơ / mảng ký tự) thì chúng ta có thể bỏ qua phần tách và chương trình giảm xuống còn 64 byte:

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

1

> <> (Cá) 39 byte

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

Khá chắc chắn rằng điều này có thể được đánh golf rất nhiều bằng cách sử dụng một kỹ thuật khác.

Nó nhận một đầu vào và so sánh với mục ngăn xếp hiện tại, nếu khác, nó sẽ in mục ngăn xếp đầu tiên hai lần, nếu cùng một mục in cả hai.

Ngăn xếp khi trống được cung cấp 0 mà không in gì nên có thể được thêm vào bất cứ khi nào.


1

Bình thường, 15 byte

Vrz8p*+hN%hN2eN

Xác nhận tất cả các trường hợp thử nghiệm ở đây.

Cảm ơn Luis Mendo cho phương pháp luận.

Giải trình

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

Như thường lệ, tôi cảm thấy như thế này có thể ngắn hơn. Tôi nghĩ nên có một cách tốt hơn để trích xuất các yếu tố từ danh sách so với những gì tôi đang sử dụng ở đây.


1

PowerShell , 28 byte

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

Hãy thử trực tuyến!(bao gồm tất cả các trường hợp thử nghiệm)

Cổng của câu trả lời Retina . Điểm lưu ý duy nhất là chúng tôi có $argsthay vì thông thường $args[0](vì -replacesẽ lặp lại từng mục trong mảng đầu vào, chúng tôi có thể loại bỏ chỉ mục) và '$1$1'cần phải được trích dẫn để chúng được thay thế bằng biểu thức chính quy các biến thay vì được coi là biến PowerShell (điều này sẽ xảy ra nếu chúng được trích dẫn kép).


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

Gọi với:

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.