순열을 일치시킵니다!


15

당신의 도전은 그 자체의 모든 문자열 순열과 일치하는 정규 표현식을 만드는 것입니다. 일치는 대소 문자를 구분해야합니다.

예를 들어 정규 표현식이 다음과 같은 경우

ABC

다음 문자열과 일치해야합니다.

ABC
ACB
BAC
BCA
CAB
CBA

다음과 일치하지 않아야합니다.

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)

규칙 :

  • 원하는 정규식을 사용할 수 있습니다.
  • 표준 허점이 적용됩니다.
  • 코드에 두 개 이상의 다른 문자가 있어야합니다. 그것은 같은 솔루션 1이 잘못 되었음을 의미합니다 .
  • 정규식은 인쇄 가능한 ASCII 만 포함해야하며 다른 것은 포함하지 않아야합니다.



나는 생각 (ABC|ACB|BAC|BCA|CAB|CBA)했지만 당신은 일반적인 대답을 원했습니다.
Stephen Quan

답변:


11

자바 스크립트, 64 57 바이트

Martin Ender 덕분에 4 바이트가 제거되었습니다.

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

여기에서 시도하십시오.

설명 (오래된)

^                                  # 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
나는 이것이 60에 효과적이라고 생각한다 : ^(?!.*(\S)(.*\1){3}[^1]?)[]zzSS[-^?!!.'''-*1{33}0066-]{60}\z regex101
Martin Ender

이것은 거의 .NET에서 작동합니다.^(?'4'(?!(.*\4){3})[]$$[\\^^?!!..'-*{}33-5-]){54}$[5]*
jimmy23013

작동하지 않는 것은 무엇입니까? 후행 줄 바꿈?
Martin Ender

@MartinEnder 예.
jimmy23013

2

Perl 및 PCRE 정규식, 280 바이트

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

(약간) 더 읽기 쉽다 :

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

이것은 기록 된대로 O (2 ^ n) 시간으로 실행되므로 매우 비효율적입니다. 테스트하는 가장 간단한 방법은 모든 발생을 대체하는 것이다 .*.*?먼저 확인하는 일치하는 경우가 발생 (이를 선형 시간에 일치 의미하지만 일치하지 않을 경우 여전히 지수 시간 소요).

기본적인 아이디어는 우리가 동일한 280 정규식의 길이를 시행하고, 몇 번 이상, 예를 들어 표시 정규식에서 각 문자를 강제로 내다 주장을 사용하는 것입니다 (?=(.*z){2})강제로 z두 배 이상에 표시하는 문자를. 2+43+43+22+23+2+6+16+7+4+1+3+2+2+1+22+22+11+2+23+23280이므로 어떤 문자도 "추가"로 표현할 수 없습니다.

이것은 오토 그램 의 프로그래밍 예제로, 포함 된 각 문자의 수 (이 경우 총 길이)를 나열하여 자신을 설명하는 문장입니다. 나는 그것을 구성하는 데 상당히 운이 좋았습니다 (일반적으로 당신은 무차별 대입을 사용해야하지만 완전히 작성하기 전에 무차별 대입 프로그램을 테스트하는 동안이 솔루션을 우연히 발견했습니다).

Martin Ender와 공동 작업 한 Perl 및 PCRE 정규식 (253 바이트)

나는 일부 숫자 (대부분 9, 8 또는 7)를 생략하는 더 짧은 솔루션이있을 수 있다고 가정했습니다. Martin Ender가 아래와 같이 발견했습니다.

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

읽을 수있는 버전 :

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

{}마지막 두 예견에서 탈출 할 필요는 없다고 생각합니다 . 또한 미리보기가 없었기 (?=(.*5){1})때문에 추가 할 필요 가 없습니다 5. 한 가지 문제는 $후행 줄 바꿈 을 허용하므로 지미가했던 것처럼 \z대신에 줄 바꿈을 사용해야 한다는 것입니다 $. 그러나 \첫 번째 미리보기에 저장 한 이후로 생각하는 바이트 비용은 들지 않습니다 .
Martin Ender

숫자와 같은 것을 생략 할 수 있다는 것을 알고 있습니다. 그러나 그들은 오토 그램을 작동 시키기 위해 존재합니다 . 더 이상 프로그램을 올바르게 설명하지 않기 때문에 프로그램의 일부를 제거하면 나머지가 모두 중단됩니다. (각 줄의 개수는 각 줄의 개수를 계산합니다! 따라서 일반적으로 프로그램을 변경하는 것은 불가능합니다.) $문자열 끝에 줄 바꿈 을 허용하는 경우 일반적으로 주변에서 정규 표현식을 호출하는 방법에 따라 다릅니다. 프로그램 (일반적으로 이미 행으로 구문 분석 된 코드에서 실행됩니다).

또는 더 정확하게 말하면 (?=(.*5){1})이 경우에는 필요합니다 . 내가 그것을 제거 하면 프로그램에 5 가있을 것입니다 . 왜냐하면 (?=(.*1){6})줄은 이제 읽어야 하기 때문 (?=(.*1){5})입니다.

후행 줄 바꿈에 관해서는 정규식에 대한 입력 유형에 대한 도전에 제한이없는 것처럼 보이므로 일반적으로 문자열에 상관없이 작동하고 변경 $하면 \z아무런 해를 끼치 지 않습니다. 오토 그램을 중단하지 마십시오).
Martin Ender

아, 그렇습니다. \$$z…로 변경합니다 \z. 작동합니다. 갈 게요
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.