9의 배수를 인식하는 유한 상태 머신을 쉽게 설명 할 수 있습니다. 숫자 합 (mod 9)을 추적하고 다음에 허용되는 숫자를 추가하십시오. 이러한 FSM에는 9 개의 상태 만 있으며 매우 간단합니다! FSM 인식과 정규 언어의 동등성으로 인해 9의 배수에 대한 정규 표현식이 있습니다. 그러나 그러한 정규 표현식은 ... 매우 길다. 마찬가지로 기가 바이트 정도입니다.
https://www.quaxio.com/triple/ 에 3의 배수에 대한 실제 예제가 있습니다 . 페이지 하단에서 저자는 순진한 전환보다 약간 짧은 "손으로 최적화 된"솔루션을 제공합니다. 정규식에 FSM.
도전 과제 :
9의 배수를 탐지하려면 정규식을 만들어야합니다. 이러한 정규식은 매우 길 것으로 예상되므로 정규식을 인쇄 할 수있는 프로그램을 제공 할 것을 요청합니다. (정말로 전체 정규 표현식을 제공하려면 다른 곳에서 호스팅하고 여기에 연결하십시오!)
프로그램 출력의 정확한 문자 수를 알려줄 수 있어야합니다. 따라서 모든 정규 표현식을 특정 길이까지 시도하는 프로그램은 작동하는 것을 찾을 때까지 허용되지 않습니다. 완료까지 실행하고 결과 정규식 길이를 제공하십시오!
포인트는 물론 프로그램 길이를 기준으로하지 않고 가장 짧은 출력 정규식을 갖기위한 것입니다. 정규식은 내가 요청하는 "프로그램"이므로 여기에 편리하게 전송하기에는 너무 길기 때문에 여전히이 코드 골프에 태그를 지정하고 있습니다.
규칙 :
- 입력은 일치하는 문자 만 포함합니다
[0-9]*
. - 정규식은 9의 배수 와 일치 하지만 다른 것은 일치 하지 않아야합니다. 숫자 0-9로만 만들어지지 않은 경우와 유효하지 않은 입력은 원하는대로 일치하거나 실패 할 수 있습니다.
- DFA에서 쉽게 인식 할 수있는 동기를 감안할 때 정규 표현식 은보다 이론적 인 용어 로 정규 표현식 이어야합니다 . 즉 정규 언어를 닫는 연산자 만 사용해야합니다 . 정확히 말하면, 허용되는 유일한 것 :
- 리터럴 문자 범위 (
[ab]
,[a-f]
,[^k]
), 149) 클린의 별 (Kleene star (*
), 앵커 (^
과$
), 괄호를 통해, 교대 (그룹화|
), 선택적인 용어 (?
), 하나 또는-이상의 용어 (+
), lookaheads ((?=)
), 부정적인 lookaheads을 ((?!)
) lookbehinds ((?<=)
), 네거티브 lookbehinds는 ((?<!)
), 조건식 (같이 https://www.regular-expressions.info/conditional.html -(?(?=test)then|else)
), 및 제한된 길이의 역 참조 (아래 참조).
- 리터럴 문자 범위 (
- 허용 되지 않는 것들의 예 :
- 임의의 길이, 순방향 참조, 재귀, 서브 루틴, 루핑 구문, 실행 코드, 'eval'변형 또는 문자열을 산술 값으로 캐스팅하기위한 내장 구문의 역 참조
- 제한된 길이의 바인딩 문자열을 갖는 것으로 표시 될 수있는 역 참조는 유한 상태로 저장 될 수 있고 언어의 규칙 성을 변경하지 않기 때문에 허용됩니다. 예를 들어,
(..2.[3-5])4\1.\1
캡처 그룹에 바인딩 된 길이가 있으므로 정규식을 사용할 수\1
있습니다. 이것은 일반적인 구조입니다.(2*)0\1
캡처 된 그룹을 유한 상태로 저장할 수 없으므로 와 같은 구성 은 허용되지 않습니다. - 정규식은 원하는대로 외부 0을 갖는 정수를 자유롭게 허용하거나 거부합니다. 그러나 문자열
"0"
을 승인해야합니다.
^(0|9|(?<c>1|(?<c>2|(?<c>3|(?<c>4|(?<c>5|(?<c>6|(?<c>7|(?<c>8))))))))((?<-c>){9})?)*$(?(c).)