Regex (ECMAScript 2018 veya .NET), 140 126 118 100 98 82 bayt
^(?!(^.*)(.+)(.*$)(?<!^\2|^\1(?=(|(<?(|(?!\8).)*(\8|\3$){1}){2})*$).*(.)+\3$)!?=*)
Bu 98 byte versiyonundan daha yavaştır, çünkü ^\1
gözetleme kafasından çıkar ve bundan sonra değerlendirilir. Hızı geri kazandıran basit bir switcheroo için aşağıya bakınız. Ancak, bu nedenle, aşağıdaki iki TIO, öncekinden daha küçük bir test senaryosunu tamamlamakla sınırlıdır ve .NET, kendi regex'ini kontrol etmek için çok yavaştır.
Çevrimiçi deneyin! (ECMAScript 2018)
Çevrimiçi deneyin! (.AĞ)
18 baytı (118 → 100) düşürmek için utanmadan, Neil'in regex'inden negatif bir göz alıcıya bir bakış açısı koyma ihtiyacını önleyen (80 byte sınırsız regex veren) gerçekten güzel bir optimizasyon çaldım . Teşekkürler Neil!
Jaytea'nın 69 bayt sınırsız regex'e yol açan fikirleri sayesinde inanılmaz 16 bayt (98 → 82) düşürdüğünde bu modası geçmiş oldu ! Çok daha yavaş, ama bu golf!
O Not (|(
iyi bağlantılı regex yapmak için no-op yapma sonucunu var çok yavaş .NET altında değerlendirir. ECMAScript'te bu etkiye sahip değillerdir, çünkü sıfır genişlikteki isteğe bağlı eşleşmeler eşleşme dışı olarak değerlendirilir .
ECMAScript, iddiaların nicelleştirilmesini yasaklar, bu nedenle kısıtlı kaynak gereksinimlerinin golf oynamasını zorlaştırır. Ancak, bu noktada o kadar iyi golf oynuyor ki, belirli bir kısıtlamanın kaldırılmasının başka golf olanakları açabileceğini düşünmüyorum.
Kısıtlamaları geçmek için gereken fazladan karakterler olmadan ( 101 69 bayt):
^(?!(.*)(.+)(.*$)(?<!^\2|^\1(?=((((?!\8).)*(\8|\3$)){2})*$).*(.)+\3))
Yavaş, ancak bu basit düzenleme (sadece 2 ekstra bayt için) tüm kayıp hızını ve daha fazlasını geri kazanıyor:
^(?!(.*)(.+)(.*$)(?<!^\2|(?=\1((((?!\8).)*(\8|\3$)){2})*$)^\1.*(.)+\3))
^
(?!
(.*) # cycle through all starting points of substrings;
# \1 = part to exclude from the start
(.+) # cycle through all ending points of non-empty substrings;
# \2 = the substring
(.*$) # \3 = part to exclude from the end
(?<! # Assert that every character in the substring appears a total
# even number of times.
^\2 # Assert that our substring is not the whole string. We don't
# need a $ anchor because we were already at the end before
# entering this lookbehind.
| # Note that the following steps are evaluated right to left,
# so please read them from bottom to top.
^\1 # Do not look further left than the start of our substring.
(?=
# Assert that the number of times the character \8 appears in our
# substring is odd.
(
(
((?!\8).)*
(\8|\3$) # This is the best part. Until the very last iteration
# of the loop outside the {2} loop, this alternation
# can only match \8, and once it reaches the end of the
# substring, it can match \3$ only once. This guarantees
# that it will match \8 an odd number of times, in matched
# pairs until finding one more at the end of the substring,
# which is paired with the \3$ instead of another \8.
){2}
)*$
)
.*(.)+ # \8 = cycle through all characters in this substring
# Assert (within this context) that at least one character appears an odd
# number of times within our substring. (Outside this negative lookbehind,
# that is equivalent to asserting that no character appears an odd number
# of times in our substring.)
\3 # Skip to our substring (do not look further right than its end)
)
)
Değişken uzunluklu görünüme dönüştürmeden önce moleküler görünüş ( 103 69 bayt) kullanarak yazdım :
^(?!.*(?*(.+)(.*$))(?!^\1$|(?*(.)+.*\2$)((((?!\3).)*(\3|\2$)){2})*$))
^
(?!
.*(?*(.+)(.*$)) # cycle through all non-empty substrings;
# \1 = the current substring;
# \2 = the part to exclude from the end
(?! # Assert that no character in the substring appears a
# total even number of times.
^\1$ # Assert that our substring is not the whole string
# (i.e. it's a strict substring)
|
(?*(.)+.*\2$) # \3 = Cycle through all characters that appear in this
# substring.
# Assert (within this context) that this character appears an odd number
# of times within our substring.
(
(
((?!\3).)*
(\3|\2$)
){2}
)*$
)
)
Ve regex'imin kendisini iyi bir şekilde bağlamasına yardımcı olmak için yukarıdaki regex'in bir varyasyonunu kullanıyorum:
(?*(.+)(.*$))(?!^\1$|(?*(.)+.*\2$)((((?!\3).)*(\3|\2$)){2})*$)\1
regex -xml,rs -o
Bununla birlikte kullanıldığında , (varsa) her karakterden eşit bir sayı içeren girdilerin katı bir alt dizesini tanımlar. Tabii, benim için bunu yapmak için regex olmayan bir program yazabilirdim, ama bunun neresinde eğlenceli olurdu?
abcbca -> False
.