Loại bỏ trường hợp trùng lặp và chuyển đổi


27

Mục tiêu

Mục tiêu của thử thách này là: đưa ra một chuỗi làm đầu vào, loại bỏ các cặp chữ cái trùng lặp, nếu mục thứ hai trong cặp có chữ viết hoa ngược lại. (tức là chữ hoa trở thành chữ thường và ngược lại).

Các cặp nên được thay thế từ trái sang phải. Ví dụ, aAanên trở thành aavà không aA.

ví dụ

Đầu vào và đầu ra:

Input:         Output:  
bBaAdD         bad     
NniIcCeE       Nice    
Tt eE Ss tT    T e S t 
sS Ee tT       s E t   
1!1!1sStT!     1!1!1st!
nN00bB         n00b    
(eE.gG.)       (e.g.)  
Hh3lL|@!       H3l|@!
Aaa            Aa
aaaaa          aaaaa
aaAaa          aaaa

Đầu vào bao gồm các ký hiệu ASCII có thể in được.

Bạn không nên xóa các chữ số trùng lặp hoặc các ký tự không phải chữ cái khác.

Nhìn nhận

Thử thách này trái ngược với "Trường hợp trùng lặp & chuyển đổi" của @nicael . Bạn có thể đảo ngược nó?

Cảm ơn bạn cho tất cả những người đóng góp từ hộp cát!

Mục lục

Đoạn trích đoạn ở cuối bài này tạo ra danh mục từ các câu trả lời a) dưới dạng danh sách các giải pháp ngắn nhất cho mỗi ngôn ngữ và b) dưới dạng bảng xếp hạng tổng thể.

Để đảm bảo rằng câu trả lời của bạn hiển thị, vui lòng bắt đầu câu trả lời của bạn bằng một tiêu đề, sử dụng mẫu Markdown sau:

## Language Name, N bytes

nơi Nlà kích thước của trình của bạn. Nếu bạn cải thiện điểm số của mình, bạn có thể giữ điểm số cũ trong tiêu đề, bằng cách đánh bại chúng thông qua. Ví dụ:

## Ruby, <s>104</s> <s>101</s> 96 bytes

Nếu bạn muốn bao gồm nhiều số trong tiêu đề của mình (ví dụ: vì điểm của bạn là tổng của hai tệp hoặc bạn muốn liệt kê riêng các hình phạt cờ của thông dịch viên), hãy đảm bảo rằng điểm thực tế là số cuối cùng trong tiêu đề:

## Perl, 43 + 2 (-p flag) = 45 bytes

Bạn cũng có thể đặt tên ngôn ngữ thành liên kết sau đó sẽ hiển thị trong đoạn trích:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes


4
Haha, đó là NniIcCeE :)
nicael 16/07/2016

@nicael Tôi rất vui khi bạn chấp thuận :)
aloisdg nói Phục hồi lại

đầu ra để làm abBgì : ? abBhay ab?
Hạ cấp

@Downgoat abBnên xuấtab
aloisdg nói Phục hồi lại

1
@raznagul tại sao vậy? Tách nó ra : aa; aA; AA, chỉ có cặp giữa phù hợp với mẫu và trở thành a, vì vậy aa; a; AA
LLlAMnYP

Câu trả lời:


12

Thạch , 8 byte

ṛŒsḟḟȧµ\

Hãy thử trực tuyến! hoặc xác minh tất cả các trường hợp thử nghiệm .

Làm thế nào nó hoạt động

ṛŒsḟḟȧµ\  Main link. Argument: s (string)

      µ   Convert all links to the left into a chain (unknown arity) and begin a
          new chain.
       \  Do a cumulative reduce by the chain to the left.
          Left argument:   r (previous result or first character)
          Right argument:  c (next character)
ṛ           Set the return value to c.
 Œs         Swap c's case.
    ḟ       Remove c from r (if present).
            This yields an empty string if c and r are identical (repeated letter
            with the same case or non-letter) and r otherwise.
            Note that r will be empty if the previous character has been removed.
   ḟ        Remove the resulting characters (if any) from c with swapped case.
            This yields c with swapped case if the result to the right does not
            contain c; otherwise, it yields the empty string.
     ȧ      Flat logical AND with c.
            Replace swapped case c with c; do not modify an empty string.

Ngắn hơn Regex chết tiệt!
aloisdg nói Phục hồi lại

2
Đánh bại Retina trong một thử thách chuỗi ._.
Thiền vào

11

Võng mạc , 18 byte

(.)(?!\1)(?i)\1
$1

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

Giải trình

Đây là một thay thế duy nhất (và khá đơn giản) phù hợp với các cặp có liên quan và thay thế chúng chỉ bằng ký tự đầu tiên. Các cặp được khớp bằng cách kích hoạt nửa không phân biệt chữ hoa chữ thường

(.)     # Match a character and capture it into group 1.
(?!\1)  # Use a negative lookahead to ensure that the next character *isn't* the same
        # as the character we just captured. This doesn't advance the position of the
        # regex engine's "cursor".
(?i)    # Now activate case-insensitivity for the remainder of the pattern.
\1      # Match the second character with a backreference to the first. With the i
        # modifier activated, this will match if the two characters only differ
        # by case.

Việc thay thế chỉ đơn giản là viết lại ký tự mà chúng ta đã bắt trong nhóm 1.


1
Câu trả lời tốt đẹp! Debuggex hoạt động tuyệt vời với cái này!
aloisdg nói Phục hồi lại

5

Brachylog , 44 byte

.v|.l1|hA,?bhB(@uA;A@uB),?bb&~b.hA|?b&~b.h~h?

Brachylog không có biểu thức chính quy.

Giải trình

    .v          Input = Output = ""
|               OR
    .l1         Input = Output = string of one character
|               OR
    hA,         A is the first char or the Input
    ?bhB        B is the second char of the Input
    (
        @uA         B uppercased is A
        ;           OR
        A@uB        A uppercased is B
    ),
    ?bb&        Call recursively on Input minus the first two elements
    ~b.hA       Output is the result of that call with A appended before it
|               OR
    b&          Call recursively on Input minus the first element
    ~b.h~h?     Output is the result of that call with the first element of Input appended
                  before it

5

C #, 87 75 byte

s=>System.Text.RegularExpressions.Regex.Replace(s,@"(.)(?!\1)(?i)\1","$1");

Với regex hùng mạnh từ Martin Ender. C # lambda nơi đầu vào và đầu ra làstring .

12 byte được lưu bởi Martin Ender và TùxCräftîñg.


C #, 141 134 byte

s=>{var r="";for(int i=0,l=s.Length;i<l;i++){var c=s[i];r+=c;if(char.IsLetter(c)&i+1<l&&(c|32)==(s[i+1]|32)&c!=s[i+1])i++;}return r;};

C # lambda nơi đầu vào và đầu ra là string. Thuật toán là ngây thơ. Đây là cái tôi dùng làm tài liệu tham khảo.

Mã số:

s=>{
    var r = "";
    for(int i = 0; i < s.Length; i++)
    {
        r+=s[i];
        if (char.IsLetter(s[i]) & i+1 < s.Length)
            if (char.ToLower(s[i])==char.ToLower(s[i+1])
              & char.IsLower(s[i])!=char.IsLower(s[i+1]))
                i += 1;
    }       
    return r;
};

7 byte nhờ Martin Ender!


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


@ TùxCräftîñg Thật vậy nhưng nó rất dễ đọc như thế này. Kiểm tra phiên bản chơi gôn của tôi để có câu trả lời ít dài dòng hơn :)
aloisdg nói Phục hồi lại

4

Perl, 40 24 + 1 = 25 byte

Sử dụng regex giống như Martin.
Sử dụng -pcờ

s/(.)(?!\1)(?i)\1/\1/g

Kiểm tra nó trên ideone


Nếu bạn sử dụng cờ -p, bạn có thể xóa gần như tất cả mã của mình ngoại trừ s /// để tiết kiệm tốt!
Dom Hastings

4

Con trăn 3, 64 59 58 byte

r=input()
for c in r:r=c[c.swapcase()==r!=c:];print(end=r)

Kiểm tra nó trên Ideone .


4

C, 66 byte

l;main(c){for(;~(c=getchar());)l=l^c^32|!isalpha(c)?putchar(c):0;}

3

Bình thường, 24 20 byte

4 byte nhờ @Jakube.

Điều này vẫn sử dụng regex, nhưng chỉ để token hóa.

shM:zj\|+s_BVGrG1\.1

Bộ thử nghiệm.

shM:zj\|+s_BVGrG1\.1   input as z
         s_BVGrG1      generate ['aA', 'Aa', 'bB', 'Bb', ..., 'zZ', 'Zz']
        +        \.    add "." to the back of the array
     j\|               insert "|" between every element of the array,
                       forming a new long string, which will be our
                       tokenizer: "aA|Aa|bB|Bb|cC|Cc|...|yY|Yy|zZ|Zz|."
                       the "." at the end is to capture the remaining characters
  :z               1   return all matches of z against that regex
                       this is effectively a tokenizer
 hM                    take the first character of each token
s                      join all the transformed tokens together, and then
                       implicitly print to STDOUT.

3

JavaScript (ES6), 71 68 byte

s=>s.replace(/./g,c=>l=c!=l&&c>'0'&&parseInt(c+l,36)%37<1?'':c,l='')

Giải trình:

s=>s.replace(/./g,c=>   Loop over each character in the string
 l=                     Save result for next loop
  c!=l&&                Check whether characters differ
  c>'@'&&               Check minimum character code
  parseInt(c+l,36)%37<1 Check if characters have same value
  ?'':c,                If so then delete this character
 l='')                  Initial empty previous character

Cho c>'@', cách duy nhất parseInt(c+l,36)để là bội số của 37 là cho cả hai cl có cùng giá trị (chúng không thể có giá trị 0 vì chúng tôi loại trừ không gian và 0 và nếu chúng không có giá trị thì biểu thức sẽ đánh giá NaN<1đó là sai) là cho họ là cùng một chữ cái. Tuy nhiên, chúng tôi biết rằng chúng không phải là cùng một trường hợp chữ cái nhạy cảm, vì vậy chúng phải giống nhau - không nhạy cảm.

Lưu ý rằng thuật toán này chỉ hoạt động nếu tôi kiểm tra mọi ký tự; Nếu tôi cố gắng đơn giản hóa nó bằng cách ghép các chữ cái thì nó sẽ thất bại ở những thứ như"a+A" .

Chỉnh sửa: Đã lưu 3 byte nhờ @ edc65.


Sử dụng thay thế thay vì bản đồ. 68. Nhưng tôi quá lười biếng để tìm ra cách đặt '`' trong một bình luận (mẹo hay mod 37)
edc65

@ edc65 Tôi không cần bất kỳ `s nếu tôi sử dụng replace. (Tôi chỉ có chúng trước đây để cố gắng nhất quán, nhưng sau đó tôi đã đánh golf câu trả lời của mình trong khi chỉnh sửa nó để gửi và trở nên không nhất quán một lần nữa. Thở dài ...)
Neil

3

C, 129 127 125 107 106 105 93 92 90 88 85 78 byte

c;d;f(char*s){for(;putchar(c=*s);)s+=isalpha(c)*(d=*++s)&&(!((c^d)&95)&&c^d);}

Cổng AC của câu trả lời C # của tôi . C của tôi có thể là một chút xấu. Tôi không sử dụng ngôn ngữ nhiều nữa. Bất kỳ trợ giúp đều được chào đón!

  • Lưu 1 byte nhờ thủ thuật Lowjacker : a!=b=a^b
  • Lưu 1 byte nhờ thủ thuật của Walpen : a&&b=a*b
  • 12 byte được lưu bởi thủ thuật của Lynn và được truyền cảm hứng ở đây bởi TùxCräftîñg
  • Lưu 1 byte nhờ thủ thuật của Joey Adams và được truyền cảm hứng ở đây bởi orlp: Di chuyển biến sang toàn cầu
  • 2 byte được SEJPM lưu bằng cách giải quyết (c|32)==(d|32) vấn đề bitwise
  • 5 byte được lưu bởi Pietu1998

Mã số:

c;d;f(char*s) {
    for(;putchar(c=*s);)
        s+=isalpha(c)*(d=*++s)&&(!((c^d)&95)&&c^d);
}

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


1
Tôi nghĩ bạn có thể tăng con trỏ để lưu một số byte. Tôi đã tìm thấy điều này (chưa được kiểm tra):f(char*s){while(*s) {char c=*s,d=s+1;putchar(c);s+=isalpha(c)&&d&&((c|32)==(d|32)&&c!=d);}}
Thiền vào

@ TùxCräftîñg Tôi quên mất cái này. Tôi đã sửa chữa đề xuất của bạn dựa trên câu trả lời của Lynn. Cảm ơn bạn vì sự giúp đỡ!
aloisdg nói Phục hồi Monica

1
Tôi nghĩ bạn có thể thay đổi s+++1để ++s.
PurkkaKoodari

@ Pietu1998 Thật vậy tôi có thể!
aloisdg nói Phục hồi lại

1
cdsẽ luôn có thể in ASCII, vì vậy 95nên hoạt động thay thế ~32. Ngoài ra, tôi nghĩ rằng c;d;f(char*s){for(;*s;){putchar(c=*s);s+=isalpha(c)*(d=*(++s))&&(!((c^d)&95)&&c^d);}}sẽ làm việc (nhưng chưa được kiểm tra).
PurkkaKoodari

3

MATL , 21 byte

"Kk@k=K@XK=>?4XKx}K&h

Hãy thử trực tuyến! . Hoặc xác minh tất cả các trường hợp thử nghiệm .

Giải trình

Điều này xử lý mỗi nhân vật trong một vòng lặp. Mỗi lần lặp lại so sánh ký tự hiện tại với ký tự trước đó. Cái sau được lưu trong clipboard K, được khởi tạo 4theo mặc định.

Nhân vật hiện tại được so sánh với nhân vật trước hai lần: trường hợp đầu tiên không nhạy cảm và sau đó là trường hợp nhạy cảm. Ký tự hiện tại nên được xóa nếu và chỉ khi so sánh đầu tiên là đúng và thứ hai là sai. Lưu ý rằng, vì clipboard K ban đầu chứa 4, ký tự đầu tiên sẽ luôn được giữ.

Nếu ký tự hiện tại bị xóa clipboard K nên được đặt lại (vì vậy ký tự tiếp theo sẽ được giữ lại); nếu không thì nên cập nhật với ký tự hiện tại.

"            % Take input string implicitly. For each char from this string:
  K          %   Push previous char, initiallized to number 4
  k          %   Convert to lower case. For numbers it rounds down
  @          %   Push current char
  k          %   Convert to lower case. 
  =          %   True if current and previous chars are (case-insensitively) equal
  K          %   Push previous char
  @          %   Push current char
  XK         %   Update clipboard K with current char. This doesn't affect the stack
  =          %   True if current and previous chars are (case-sensitively) equal
  >?         %   If first comparison was true and second was false
    4XKx     %     Reset clipboard K to 4
  }          %   Else
    K        %     Push previous char
    &h       %     Concatenate horizontally to gradually build the output string

2

Java 7, 66 byte

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

Đã sử dụng regex của Martin Ender từ câu trả lời Retina của mình .

Mã thử nghiệm & mã hóa:

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

class Main{
  static String c(String i){
    return i.replaceAll("(.)(?!\\1)(?i)\\1", "$1");
  }

  public static void main(String[] a){
    System.out.println(c("bBaAdD"));
    System.out.println(c("NniIcCeE"));
    System.out.println(c("Tt eE Ss tT"));
    System.out.println(c("sS Ee tT"));
    System.out.println(c("1!1!1sStT!"));
    System.out.println(c("nN00bB"));
    System.out.println(c("(eE.gG.)"));
    System.out.println(c("Hh3lL|@!"));
    System.out.println(c("Aaa"));
    System.out.println(c("aaaaa"));
    System.out.println(c("aaAaa"));
  }
}

Đầu ra:

bad
Nice
T e S t
s E t
1!1!1st!
n00b
(e.g.)
H3l|@!
Aa
aaaaa
aaaa

2

JavaScript (ES6), 61 byte , 57 byte

s=>s.replace(/./g,c=>l=c!=l&/(.)\1/i.test(l+c)?'':c,l='')

Cảm ơn Neil vì đã tiết kiệm 5 byte.


1
Tin xấu: bạn đã nhầm lẫn, và đó thực sự là 62 byte. Tin tốt: Tôi có thể giúp bạn tiết kiệm năm byte! s=>s.replace(/./g,c=>l=c!=l&/(.)\1/i.test(l+c)?'':c,l='')
Neil

Ồ, xin lỗi, tôi đã tính bằng cách sử dụng "code".length, không nhận ra có một chuỗi thoát trong đó. Cảm ơn
cPu1

Hãy thử sử dụng (code).toString().length.
Neil

Vâng, hoặc(code+"").length
cPu1

1

JavaScript (ES6) 70

(s,p,q)=>s.replace(/./g,c=>p!=c&q===(d=parseInt(c,36))?q='':(q=d,p=c))

f=(s,p,q)=>s.replace(/./g,c=>p!=c&q===(d=parseInt(c,36))?q='':(q=d,p=c))

;
[['bBaAdD','bad']
,['NniIcCeE','Nice']
,['Tt eE Ss tT','T e S t']
,['sS Ee tT','s E t']
,['1!1!1sStT!','1!1!1st!']
,['nN00bB','n00b']
,['(eE.gG.)','(e.g.)']
,['Hh3lL|@!','H3l|@!']
,['Aaa','Aa']
,['aaaaa','aaaaa']
,['aaAaa','aaaa']]
.forEach(
  x=>
  {
    var i=x[0],k=x[1],r=f(i)
    console.log(k==r?'OK':'KO',i,r)
  }
)


OK, tôi sẽ cắn. Tại sao ===?
Neil

0==""nhưng không phải 0===""@Neil
edc65

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.