이진 단어와 일치하는 가장 짧은 간단한 정규식


20

태스크

간단한 정규식 을 다음으로 만 구성된 비어 있지 않은 정규식 으로 정의하십시오.

  • 문자 01,
  • 괄호를 그룹화 (하고 ),
  • 하나 이상의 반복 수량 화기 +.

비어 있지 않은 0s 및 1s 문자열이 제공 되면 프로그램은 전체 입력 문자열과 일치하는 가장 짧은 간단한 정규식을 찾아야 합니다. (간단한 정규식과 일치하는 경우 즉,이 척에 의해 bookended하게 ^ 하고  $.) 다수의 최단 정규 표현식에가 있으면, 그들 중 일부 또는 전부를 출력한다.)

이므로 가장 짧은 제출 (바이트)이 이깁니다.

테스트 사례

1 -> 1
00 -> 00 or 0+
010 -> 010
1110 -> 1+0
01010 -> 01010
0101010 -> 0(10)+ or (01)+0
011111 -> 01+
10110110 -> (1+0)+
01100110 -> (0110)+ or (01+0)+
010010010 -> (010)+
111100111 -> 1+001+ or 1+0+1+
00000101010 -> 0+(10)+ or (0+1)+0
1010110001 -> 1(0+1+)+ or (1+0+)+1

3
정규식을 직접 작성하지 말고 정규식을 작성하는 프로그램을 작성하도록하십시오. 그러나 이것은 흥미로워 보입니다.
gcampbell 2016 년

1
내 테스트에서, 01100110순진 알고리즘을 작성합니다 ... 흥미로운 사건 01+0+1+0또는 (0+1+)+0최적이 아닌있다.
Neil

답변:


2

Pyth, 20 바이트

hf.x}z:zT1Zy*4"()01+

실행하는 데 약 30 초가 걸리므로 오프라인으로 실행해야합니다.

설명:

hf.x}z:zT1Zy*4"()01+
                        Implicit: z is the input string.
              "()01+    "()01+"
            *4          Repeated 4 times
           y            All subsequences in length order
hf                      Output the first one such that
      :zT1              Form all regex matches of z with the candidate string
    }z                  Check if the input is one of the strings
  .x      Z             Discard errors

모든 가장 짧은 문자열이 "() 01+"* 4의 하위 시퀀스인지는 확실하지 않지만 필요한 경우 바이트 비용없이 4를 9로 늘릴 수 있습니다.


9

자바 스크립트 (ES6), 488 341 바이트

s=>[s.replace(/(.)\1+/g,'$1+'),...[...Array(60)].map((_,i)=>`(${(i+4).toString(2).slice(1)})+`),...[...Array(1536)].map((_,i)=>`${i>>10?(i>>8&1)+(i&2?'+':''):''}(${i&1}${i&4?i>>4&1:i&16?'+':''}${i&8?''+(i>>7&1)+(i&64?i>>5&1:i&32?'+':''):''})+${i&512?(i>>8&1)+(i&2?'+':''):''}`)].filter(r=>s.match(`^${r}$`)).sort((a,b)=>a.length-b.length)[0]

설명 : 6 개의 정규 표현식이 가능한 모든 이진 단어를 표현할 수 있고 가장 긴 2 개의 단어는 9 자 길이이므로 해당 정규 표현식과 더 짧은 정규 표현식을 확인하면 충분합니다. 한 후보는 분명히 "실행 길이 인코딩"이있는 문자열입니다 (즉, 모든 숫자 실행이 적절한 +s 로 대체 됨 ). 또한 한 세트의 ()s가있는 문자열도 확인해야합니다. 나는 1596과 같은 정규 표현식을 생성하고 (이것은 중복 및 쓸모없는 정규 표현식을 포함하지만 제거 될 것입니다) 1597을 테스트하여 가장 짧은 일치 사항을 확인하십시오. 생성 된 정규 표현식은 \(\d{2,5}\)\+(60 정규 표현식)과 (\d\+?)?\(\d[\d+]?(\d[\d+]?)?\)(\d\+?)?(1536 정규 표현식으로 시작과 후행 숫자가 모두 정규 표현식을 생성하지 않기 때문에 ) 두 가지 유형으로 분류 됩니다.


@LeakyNun 원래 나는 길이가 9 인 정규 표현식이 4 개 있다고 생각했지만 분명히 잘못되었으므로 설명을 명확히했습니다.
Neil


1

루비, 109 바이트

지루한 무차별 접근 방식입니다. 정규 표현식이 닐 노트와 같이 9자를 초과 할 필요가 없으며 개별 문자를 4 번 이상 반복 할 필요가 없기 때문에 작동합니다 ( '01()+'.chars*9CPU를 불행하게 만들 면서 시도 ).

10.times{|i|('01()+'.chars*4).combination(i).map{|s|begin
/^#{s*''}$/=~$*[0]&&[puts(s*''),exit]
rescue
end}}
$ for word in `grep -Po '^\S+' test_cases.txt`; do nice -n20 ruby sre.rb $word; done
1
0+
010
1+0
01010
0(10)+
01+
(1+0)+
(01+0)+
(010)+
1+0+1+
0+(10)+
1(0+1+)+

1

파이썬 3, 186 바이트

나는 무차별 대입 외에도이 문제에 대한 접근 방식이 있는지 조사하고 있지만 지금은 파이썬 무차별 대입 솔루션이 있습니다.

import re,itertools
def a(b):
 for z in range(10):
  for i in itertools.combinations("01()+"*4,z):
   j=''.join(i)
   try:
    if re.fullmatch(j,b)and len(j)<=len(b):return j
   except:1
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.