Permütasyonları eşleştirin!


15

Zorluğunuz, kendisinin her dize permütasyonuyla eşleşen bir normal ifade oluşturmaktır ve başka bir şey değildir. Maç ayrıca büyük / küçük harfe duyarlı olmalıdır.

Örneğin, normal ifadeniz:

ABC

Şu dizelerle eşleşmeli (ve eşleşmelidir):

ABC
ACB
BAC
BCA
CAB
CBA

Şunun gibi şeylerle eşleşmemelidir:

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)

Kurallar:

  • İstediğiniz herhangi bir normal ifadeyi kullanmanıza izin verilir.
  • Standart boşluklar geçerlidir.
  • Kodunuzda en az iki farklı karakter olmalıdır. Bu, gibi çözümlerin 1geçersiz olduğu anlamına gelir .
  • Normal ifade yalnızca yazdırılabilir ASCII içermeli ve başka bir şey içermemelidir.



Düşündüm (ABC|ACB|BAC|BCA|CAB|CBA)ama genel bir cevap istedin.
Stephen Quan

Yanıtlar:


11

JavaScript, 64 57 bayt

Martin Ender sayesinde 4 bayt kaldı.

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

Burada deneyin.

Açıklamalar (modası geçmiş)

^                                  # 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
Bunun 60 için işe yaradığını düşünüyorum: ^(?!.*(\S)(.*\1){3}[^1]?)[]zzSS[-^?!!.'''-*1{33}0066-]{60}\z regex101
Martin Ender

Bu neredeyse .NET çalışır:^(?'4'(?!(.*\4){3})[]$$[\\^^?!!..'-*{}33-5-]){54}$[5]*
jimmy23013

Ne işe yaramaz? Sondaki hat beslemeleri?
Martin Ender

@MartinEnder Evet.
jimmy23013

2

Perl ve PCRE normal ifadesi, 280 bayt

^(?=(.*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

(Biraz) daha okunabilir:

^
(?=(.*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

Bu, O (2 ^ n) zamanında yazıldığı gibi çalışır, bu yüzden inanılmaz derecede verimsizdir. Bunu test etmenin en kolay yolu her geçtiği değiştirmektir .*ile .*?ilk kontrol edilecek maçları davayı neden olur (bu doğrusal zamanda maçları, yani ancak maç için başarısız olursa hala üstel zaman alır).

Temel fikir, normal ifadenin uzunluğunu 280'e eşit tutmamız ve normal ifadedeki her karakteri en az belirli sayıda görünmeye zorlamak için ileriye dönük iddialar kullanmamızdır, örneğin (?=(.*z){2}), zkarakteri en az iki kez görünmeye zorlar . 2+43+43+22+23+2+6+16+7+4+1+3+2+2+1+22+22+11+2+23+23280 olduğundan herhangi bir karakterin "ekstra" tekrarına sahip olamazız.

Bu bir programlama örneğidir autogram , (bu durumda, ayrıca toplam uzunluğu ve benzeri) içerdiği her karakter sayısını listeleyerek kendisini tanımlayan bir cümle. Onu inşa etmede oldukça şanslıydım (normalde kaba kuvvet kullanmanız gerekiyor, ancak kaba kuvvet programımı yazmayı tamamen bitirmeden önce test ederken bu çözümde tökezledim).

Perl ve PCRE regex, 253 bayt, Martin Ender ile işbirliği içinde

Bazı rakamları (muhtemelen 9, 8 veya 7) atlayan daha kısa çözümlerin olabileceğini varsaydım. Martin Ender aşağıda gösterilen birini buldu:

^(?=(.*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

Okunabilir sürüm:

^
(? = (. X 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

{}Son iki gözcüde bunlardan kaçman gerektiğini sanmıyorum . Ayrıca, böyle bir şey (?=(.*5){1})olmasaydı, böyle bir şey eklemenize de gerek yok 5. Bir sorun, $sondaki bir hat beslemesine izin vermesidir, bu yüzden jimmy'nin yaptığı gibi \zorada kullanmanız gerekir $, ancak \ilk bakışta kaydettiğiniz için bence bir bayta mal olmaz .
Martin Ender

Rakam gibi şeyleri atlamanın mümkün olduğunun farkındayım. Ancak, otogramın çalışmasını sağlamak için oradalar . Programın herhangi bir parçasının kaldırılması, kalanların bozulmasına neden olur, çünkü artık programı doğru şekilde tanımlamaz. (Her satır için sayım, her satır için sayımı sayar! Bu nedenle, programı değiştirmek genel olarak imkansızdır.) $Dizenin sonunda bir yeni satıra izin vermek için, genellikle regex'in çevreleyen tarafından nasıl çağrıldığına bağlıdır. (normalde zaten satırlara ayrıştırılmış kodda çalıştırılır).

Veya daha kesin olmak gerekirse: (?=(.*5){1})Bu durumda ihtiyacım var . Eğer kaldırırsam , programda 5 olurdu , çünkü (?=(.*1){6})satır şimdi okumak zorunda kalacaktı (?=(.*1){5}).

Sondaki satır beslemesine gelince, regex'inize giriş türüyle ilgili zorlukta herhangi bir kısıtlama görünmemektedir, bu nedenle genellikle herhangi bir dize için çalışması gerektiği anlamına gelir ve değiştirmek $, \zherhangi bir zarar vermez (ve otogramı kırmayın).
Martin Ender

Ah anlıyorum; \$$değerini z… olarak değiştirirsiniz \z. Bu çalışır; Gidip değiştireceğim.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.