Wyzwanie polega na utworzeniu wyrażenia regularnego pasującego do każdej permutacji ciągu znaków i nic więcej. W dopasowaniu należy również rozróżniać małe i wielkie litery.
Na przykład jeśli wyrażenie regularne to:
ABC
Powinien pasować (i tylko pasować) następujące ciągi:
ABC
ACB
BAC
BCA
CAB
CBA
Nie powinno pasować do takich rzeczy jak:
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)
Zasady:
- Możesz używać dowolnego smaku wyrażenia regularnego, który ci się podoba.
- Obowiązują standardowe luki.
- Musisz mieć co najmniej dwa różne znaki w kodzie. Oznacza to, że takie rozwiązania
1
są nieprawidłowe. - Wyrażenie regularne powinno zawierać tylko ASCII do wydruku i nic więcej.
(ABC|ACB|BAC|BCA|CAB|CBA)
ale chciałeś uogólnionej odpowiedzi.Odpowiedzi:
JavaScript,
6457 bajtów4 bajty usunięte dzięki Martinowi Enderowi.
Wypróbuj tutaj.
Objaśnienia (nieaktualne)
źródło
^(?!.*(\S)(.*\1){3}[^1]?)[]zzSS[-^?!!.'''-*1{33}0066-]{60}\z
regex101^(?'4'(?!(.*\4){3})[]$$[\\^^?!!..'-*{}33-5-]){54}$[5]*
Wyrażenia regularne Perl i PCRE, 280 bajtów
(Nieco) bardziej czytelny:
Działa to w czasie O (2 ^ n), jak napisano, więc jest niezwykle nieefektywne. Najprostszym sposobem, aby go przetestować ma zastąpić wszystkie wystąpienia
.*
z.*?
, co powoduje sytuację, w której to pasuje do sprawdzenia pierwszy (co oznacza, że mecze w czasie liniowym, ale nadal trwa wykładniczą czasu, jeżeli nie pasuje).Podstawową ideą jest to, że wymuszamy długość wyrażenia regularnego równego 280 i używamy twierdzeń typu lookahead, aby zmusić każdy znak w wyrażeniu regularnym do pojawienia się co najmniej pewną liczbę razy, np.
(?=(.*z){2})
Zmuszaz
postać do pojawienia się co najmniej dwa razy.2+43+43+22+23+2+6+16+7+4+1+3+2+2+1+22+22+11+2+23+23
wynosi 280, więc nie możemy mieć żadnych „dodatkowych” wystąpień żadnych znaków.To jest przykład programowania autogramu , zdanie, które opisuje się, wymieniając liczbę każdego znaku, który zawiera (a w tym przypadku także całkowitą długość). Miałem dość szczęścia w jego tworzeniu (zwykle musisz użyć brutalnej siły, ale natknąłem się na to rozwiązanie podczas testowania mojego programu brutalnej siły, zanim w pełni go napisałem).
Wyrażenia regularne Perl i PCRE, 253 bajty, we współpracy z Martinem Enderem
Postawiłem hipotezę, że mogą istnieć krótsze rozwiązania pomijające niektóre cyfry (najprawdopodobniej 9, 8 lub 7). Martin Ender znalazł taki, pokazany poniżej:
Wersja do odczytu:
źródło
{}
z ostatnich dwóch lat. Nie musisz też dodawać takich rzeczy,(?=(.*5){1})
ponieważ nie byłoby5
, gdybyś nie miał tego spojrzenia w przyszłość. Jednym z problemów jest to, że$
zezwala na końcowe podawanie linii, więc musisz użyć go\z
zamiast$
jak Jimmy, ale myślę, że to nie będzie kosztować bajtu, ponieważ zapisujesz go\
w pierwszym spojrzeniu.$
zezwolenie na nową linię na końcu łańcucha, to na ogół zależy od tego, jak regex jest wywoływany przez otaczające program (zwykle są uruchamiane na kodzie, który został już parsowany na linie).(?=(.*5){1})
w tym przypadku. Gdybym go usunął, w programie byłoby 5, ponieważ(?=(.*1){6})
linia musiałaby teraz czytać(?=(.*1){5})
.$
na\z
nie powoduje żadnej szkody (i nie złamać autogram).\$
…$
naz
…\z
. To działa; Pójdę to zmienić.