Phù hợp với hoán vị!


15

Thách thức của bạn là tạo ra một biểu thức chính phù hợp với mọi hoán vị chuỗi của chính nó và không có gì khác. Trận đấu cũng phải phân biệt chữ hoa chữ thường.

Vì vậy, ví dụ, nếu regex của bạn là:

ABC

Nó phải khớp (và chỉ khớp) các chuỗi này:

ABC
ACB
BAC
BCA
CAB
CBA

Nó không phù hợp với những thứ như:

AABC (contains an extra A)
ABCD (contains an extra D)
AC   (no B)
AAA  (no B and C, extra 2 A's)
abc  (case-sensitive)

Quy tắc:

  • Bạn được phép sử dụng bất kỳ hương vị của regex nào bạn thích.
  • Tiêu chuẩn áp dụng.
  • Bạn phải có ít nhất hai ký tự khác nhau trong mã của mình. Điều đó có nghĩa là các giải pháp như 1không hợp lệ.
  • Regex chỉ nên chứa ASCII có thể in và không có gì khác.


Cũng liên quan: Số ký tự trong mã nguồn
jimmy23013

Tôi nghĩ (ABC|ACB|BAC|BCA|CAB|CBA)nhưng bạn muốn một câu trả lời khái quát.
Stephen Quan

Câu trả lời:


11

JavaScript, 64 57 byte

4 byte bị xóa nhờ Martin Ender.

^(?!.*([^])(.*\1){3}]?)[$$[-^?!!.'''-*11{33}5577\\-]{57}$

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

Giải thích (lỗi thời)

^                                  # Beginning of the string.
(?!.*                              # Match only the strings that don't contain...
  (.)(.*\1){4}                     #     5 occurrences of the same character.
  [^1]?[^1]?                       #     Something that doesn't matter.
)
[]zzz^(?!!!.**[)\\1{{44}}666]{64}  # 64 occurrences of these 16 characters.
                                   # Some are duplicated to make sure the regex
                                   # contains 4 occurrences of each character.
\z                                 # End of the string.

2
Tôi nghĩ rằng điều này hoạt động trong 60: ^(?!.*(\S)(.*\1){3}[^1]?)[]zzSS[-^?!!.'''-*1{33}0066-]{60}\z regex101
Martin Ender

Điều này gần như hoạt động trong .NET:^(?'4'(?!(.*\4){3})[]$$[\\^^?!!..'-*{}33-5-]){54}$[5]*
jimmy23013

Cái gì không hoạt động? Trailing linefeed?
Martin Ender

@MartinEnder Có.
jimmy23013

2

Regex Perl và PCRE, 280 byte

^(?=(.*z){2})(?=(.*\(){43})(?=(.*\)){43})(?=(.*\*){22})(?=(.*\.){23})(?=(.*0){2})(?=(.*1){6})(?=(.*2){16})(?=(.*3){7})(?=(.*4){4})(?=(.*5){1})(?=(.*6){3})(?=(.*7){2})(?=(.*8){2})(?=(.*9){1})(?=(.*=){22})(?=(.*\?){22})(?=(.*\\){11})(?=(.*\^){2})(?=(.*\{){23})(?=(.*\}){23}).{280}\z

(Hơi) dễ đọc hơn:

^
(?=(.*z){2})
(?=(.*\(){43})
(?=(.*\)){43})
(?=(.*\*){22})
(?=(.*\.){23})
(?=(.*0){2})
(?=(.*1){6})
(?=(.*2){16})
(?=(.*3){7})
(?=(.*4){4})
(?=(.*5){1})
(?=(.*6){3})
(?=(.*7){2})
(?=(.*8){2})
(?=(.*9){1})
(?=(.*=){22})
(?=(.*\?){22})
(?=(.*\\){11})
(?=(.*\^){2})
(?=(.*\{){23})
(?=(.*\}){23})
.{280}\z

Điều này chạy trong thời gian O (2 ^ n) như được viết, vì vậy rất kém hiệu quả. Cách dễ nhất để kiểm tra nó là để thay thế mỗi lần xuất hiện của .*.*?, gây ra các trường hợp nó phù hợp để được kiểm tra đầu tiên (nghĩa là nó phù hợp trong thời gian tuyến tính, nhưng vẫn cần có thời gian theo cấp số nhân nếu nó không phù hợp).

Ý tưởng cơ bản là chúng ta thực thi độ dài của regex bằng 280 và sử dụng các xác nhận tìm kiếm để buộc mỗi nhân vật trong regex xuất hiện ít nhất một số lần nhất định, ví dụ như (?=(.*z){2})buộc znhân vật xuất hiện ít nhất hai lần. 2+43+43+22+23+2+6+16+7+4+1+3+2+2+1+22+22+11+2+23+23là 280, vì vậy chúng tôi không thể có bất kỳ sự xuất hiện "thêm" nào của bất kỳ nhân vật nào.

Đây là một ví dụ lập trình của một chữ ký , một câu mô tả chính nó bằng cách liệt kê số lượng của mỗi ký tự mà nó chứa (và, trong trường hợp này, cũng là tổng chiều dài). Tôi đã khá may mắn khi xây dựng nó (thông thường bạn phải sử dụng vũ lực nhưng tôi tình cờ tìm thấy giải pháp này trong khi thử nghiệm chương trình vũ phu của mình trước khi tôi hoàn thành việc viết nó).

Regex Perl và PCRE, 253 byte, phối hợp với Martin Ender

Tôi đã đưa ra giả thuyết rằng có thể có các giải pháp ngắn hơn mà bỏ qua một số chữ số (rất có thể là 9, 8 hoặc 7). Martin Ender tìm thấy một, hiển thị dưới đây:

^(?=(.*z){2})(?=(.*\(){39})(?=(.*\)){39})(?=(.*\*){20})(?=(.*\.){21})(?=(.*0){4})(?=(.*1){6})(?=(.*2){11})(?=(.*3){6})(?=(.*4){3})(?=(.*5){2})(?=(.*6){3})(?=(.*9){4})(?=(.*=){20})(?=(.*\?){20})(?=(.*\\){9})(?=(.*\^){2})(?=(.*{){21})(?=(.*}){21}).{253}\z

Phiên bản dễ đọc:

^
(? = (. * z) {2})
(? = (. * \ () {39})
(? = (. * \)) {39})
(? = (. * \ *) {20})
(? = (. * \.) {21})
(? = (. * 0) {4})
(? = (. * 1) {6})
(? = (. * 2) {11})
(? = (. * 3) {6})
(? = (. * 4) {3})
(? = (. * 5) {2})
(? = (. * 6) {3})
(? = (. * 9) {4})
(? = (. * =) {20})
(? = (. * \?) {20})
(? = (. * \\) {9})
(? = (. * \ ^) {2})
(? = (. * {) {21})
(? = (. *}) {21})
. {253} \ z

Tôi không nghĩ rằng bạn cần phải thoát khỏi những cái nhìn {}trong hai cái nhìn cuối cùng. Bạn cũng không cần phải thêm những thứ như (?=(.*5){1})sẽ không có 5nếu bạn không có cái nhìn đó. Một vấn đề là $cho phép một nguồn cấp dữ liệu theo dõi, vì vậy bạn sẽ cần sử dụng \zở đó thay vì $như jimmy đã làm, nhưng điều đó sẽ không làm bạn mất một byte tôi nghĩ vì bạn lưu \trong cái nhìn đầu tiên.
Martin Ender

Tôi biết rằng có thể bỏ qua những thứ như chữ số. Tuy nhiên, họ ở đó để làm cho chữ hoạt động. Loại bỏ bất kỳ phần nào của chương trình sẽ khiến tất cả phần còn lại bị phá vỡ, vì nó không còn mô tả chính xác chương trình. (Đếm cho mỗi dòng đếm số đếm cho mỗi dòng! Vì vậy, về cơ bản, nói chung về cơ bản là không thể thay đổi chương trình.) Về việc $cho phép một dòng mới ở cuối chuỗi, điều đó thường phụ thuộc vào cách regex được gọi bởi xung quanh chương trình (chúng thường chạy trên mã đã được phân tích thành dòng).

Hay nói chính xác hơn: tôi cần (?=(.*5){1})trong trường hợp này. Nếu tôi loại bỏ nó, sẽ có 5 trong chương trình, vì (?=(.*1){6})bây giờ dòng này sẽ phải đọc (?=(.*1){5}).

Đối với nguồn cấp dữ liệu theo dõi, dường như không có bất kỳ hạn chế nào trong thử thách đối với loại đầu vào cho biểu thức chính của bạn, do đó, điều đó thường có nghĩa là nó sẽ hoạt động cho bất kỳ chuỗi nào và thay đổi $thành \zkhông gây hại (và không làm hại 't phá vỡ chữ ký).
Martin Ender

Ồ, tôi hiểu rồi; bạn thay đổi \$... $để z... \z. Điều đó làm việc; Tôi sẽ đi thay đổi nó.
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.