페어링 가능한 문자열


28

문자열을 서브 트레이 로 분할 할 수있는 경우 을 지정할 수 있습니다. 각 문자열은 연속적으로 두 번 반복되는 문자열입니다. 예를 들어, aabaaababbbaba다음과 같이 페어링 가능합니다.

aaba aaba
b b
ba ba

비어 있지 않은 문자열과 a의 문자열이 주어지면 b쌍을 이룰 수있는 경우 Truthy 값을 출력하고 그렇지 않으면 Falsey 값을 출력하십시오.

페어링 가능 :

aa
abaaba
bbababbb
aabaaababbbaba
babababa
bbbbbbbbbbbb
aaababbabbabbbababbaabaabaababaaba
aaaabaab

페어링 불가 :

a
ba
baab
abaabaaba
bbbbbbbbbbbbbbb
baababbabaaaab
aaaaabbaaaaa

귀하의 언어로 된 정규식 답변이 이미 짧은 경우에도 정규식이 아닌 솔루션을 제안하는 것이 좋습니다. "정규식 없음"으로 표시 할 수 있습니다. 정규식에서는 내장 문자열 패턴 일치 하위 시스템을 의미합니다.


리더 보드 :


이외의 다른 것을 사용할 수 있습니까 ab?
Outgolfer Erik

bbababbb가 쌍을 이룰 수 있다면 왜 baab과 aaaaabbaaaaa는 그렇지 않습니까?
rnso

@rnso 내 이해에서 bbababbb는 3 쌍으로 쏟을 수 있습니다 : bb, abab 및 bb는 순서대로 연결되어 원래 문자열을 형성하지만 다른 두 개는 할 수 없습니다.
Sunny Pun

"각 문자열 (하위 문자열)은 두 번 연속 반복되는 문자열"이라는 질문에 의해 babbabbb에 만족하지 않습니다. 그렇지 않으면 baab을 baab으로, aaaaabbaaaaa를 aaaaa bb aaaaa로 나눌 수도 있습니다.
rnso

@rnso 무슨 뜻인지 잘 모르겠습니다. 연속적으로, 나는 두 개의 반복이 서로 옆에 있음을 의미합니다. "baa b"에서 두 b는 a로 구분되므로 작동하지 않습니다.
xnor

답변:


11

파이썬 2, 68 63 바이트

f=lambda s,n=1:s==2*s[:n]or''<s[n:]>-f(s,n+1)<f(s[n:])*f(s[:n])

True 또는 False를 반환합니다 . Ideone에서 테스트하십시오 .


4
더블의 중심과 파티션의 중심 모두에 대한 인덱스를 사용하여 정말 깨끗한 재귀입니다. 진실성이 무언가보다 작은 것으로 확인되는 것은 재미있다. 나는 몇 가지 개선을 참조하십시오 ...
xnor

8

레티 나 , 11 바이트

^((.+)\2)+$

모든 테스트 사례를 시도하십시오. 처음 두 바이트는 여러 줄로 만듭니다.

규칙에 대한 문자 그대로의 해석은 모든 Retina 프로그램과 마찬가지로 정규식을 사용합니다.


2
Dangit, 나는 이것을 게시하기 위해 3 주 동안 기다리고 있었다 ...
ETHproductions


5
으악! 나도 그를 10 초만 때렸다 ... 글쎄, 내가 Hexagony 답을 쓰면 그는 나를 용서할 것이다.
FryAmTheEggman

5
@FryAmTheEggman 기대하고 있습니다. :)
Martin Ender 2016

2
Perl과 정확히 동일합니다.perl -pE '$_=/^((.+)\2)+$/'
Dada

8

젤리 , 10 바이트

ẆŒPẋ€€2F€ċ

정확히 효율적이지 않습니다 ... 온라인으로 사용해보십시오!

작동 원리

ẆŒPẋ€€2F€ċ  Main link. Argument: s (string)

Ẇ           Window, generate the array of all substrings of s.
 ŒP         Powerset; generate all subarrays of substrings of s.
   ẋ€€2     Repeat each substring in each subarray twice.
            For example, ["ab", "a", "b"] becomes ["abab", "aa", "bb"].
       F€   Flatten the subarrays by concatenating their strings.
         ċ  Count how many times s appears in the generated strings.

이것은 ... 비효율적 인 것 같습니다. 합리적인 시간 내에 입력을 얼마나 오래 처리 할 수 ​​있습니까?
John Dvorak

1
그것은 매우 비효율적입니다 ( O (2 ^ n ^ 2) , 나는 생각합니다). 현지에서 확인해야합니다. 길이가 6 인 문자열에 대한 메모리가 부족합니다 .
Dennis

8
길이가 6 인 문자열은 컴퓨터에서 3:20 분이 걸리고 6GB의 메모리가 필요합니다.
Dennis

1
@Dennis 모든 것이 충돌하기 때문에 길이 100을 입력 하지 마십시오 . 예, 심지어 TIO.
Outgolfer Erik

@EriktheGolfer 그것은 다른 용도로 TIO를 불필요하게 느리게 할 것이기 때문에 좋은 생각이지만 충돌하지는 않습니다. 시스템에 메모리가 부족 해지면 OOM에 의해 프로세스가 종료됩니다.
Dennis

5

Haskell, 72 69 바이트 (정규식 없음)

g(a:b:c)|a==b=g c
g x=x==[]
any(g.words.concat).mapM(\c->[[c],c:" "])

무차별 접근 방식. Ideone에서 사용해보십시오 .

-3 바이트의 BlackCap 덕분입니다.

설명

도우미 함수 g는 문자열 목록을 가져 와서 같은 문자열 쌍으로 구성되어 있는지 확인합니다 ["aa","aa","bba","bba","ab","ab"]. (익명) 메인 함수는 가능한 모든 방법으로 문자열을 분할하고 적어도 하나의 분할이 g허용 목록을 생성하는지 확인 합니다.

g(a:b:c)                                  g on list with elements a, b and tail c,
        |a==b                              in the case that a==b,
             =g c                          recurses to the tail c.
g x=                                      g on any other list x
    x==[]                                  checks that x is empty.
                                           This includes the case where a is not equal
                                           to b, resulting in False.
any(g.words.concat).mapM(\c->[[c],c:" "]) The main function:
                    mapM(\c->[[c],c:" "])  Replace each letter c with either "c" or "c "
                                           in all possible ways, return list of results.
any(              ).                       Check that at least one result satisfies this:
            concat                          Concatenate the 1- or 2-letter strings,
      words.                                split again at each space,
    g.                                      apply g.

당신은 대체 할 수 or.mapany
BlackCap

@BlackCap 물론 감사합니다! 나는 처음에 가지고 any g.map(words.concat)와 "이봐, 내가 할 수있는 골프 생각 anyor..."
Zgarb

5

파이썬 2, 60 바이트

f=lambda s,t='':''<s>f(s[1:],t+s[0])|f(t and s)*f(t)>-(s==t)

이것이 정확하기를 바랍니다. 꽤 느리게 실행되며 and최적으로 보이지 않습니다.


1
문자열을 사용해 보았지만 색인 기반 점수 근처에서는 얻을 수 없었습니다. 그것은 and당신이 가지고있는 영리한 것입니다.
Dennis

축하합니다! 파티션을 되풀이하는 것은 내가 생각한 속임수였습니다.
xnor

4

젤리 , 12 바이트

ŒṖµœs€2ZEµ€S

내 다른 대답 보다 2 바이트 더 길지만 이 방법은 훨씬 효율적이며 테스트 사례 중 하나를 제외하고 모두 처리합니다.

온라인으로 사용해보십시오!

작동 원리

ŒṖµœs€2ZEµ€S  Main link. Argument: s (string)

ŒṖ            Generate all partitions of s.
  µ      µ€   Map the monadic chain between the µ's over the partitions.
   œs€2         Split each string in the partition into two chunks of equal length.
       Z        Zip/transpose, collecting the first halves in one array and the
                second halves in another.
        E       Test the arrays of halves for equality.
           S  Return the sum of the results, counting the number of different
              ways s can be paired.

3

Pyth-정규 표현식 없음 -13 12 바이트

파티션이 둘로 잘릴 때 서로 같은 모든 문자열로 구성되어 있는지 확인합니다.

sm.AqMcL2d./

테스트 스위트 .


3

Brachylog , 14 바이트 (정규식 없음)

lye~l:1j@2zcc?

온라인으로 사용해보십시오!

일부 테스트 사례에서는 너무 느립니다.

설명

ly                  The list [0, …, length(Input)]
  e~l               A list whose length is an element of the previous list
     :1j            Append itself to this list
        @2zc        Split in half, zip and concatenate so that the list contains pairs of
                      consecutive identical elements
            c?      The concatenation of that list must result in the Input

3

자바 스크립트 (ES6), 정규 표현식 없음, 75 74 바이트

f=s=>!s|[...s].some((_,i)=>i&&s[e='slice'](0,i)==s[e](i,i+=i)&&f(s[e](i)))

반환 1그렇지 않으면 pairable에 대한 0. 편집 : @ edc65 덕분에 1 바이트가 절약되었습니다.


좋은! substr를 수정하지 않고 사용하는 횟수는 동일 합니다 i. 그러나 slice3 번 반복하면 1 바이트 앨리어싱을 저장할 수 있습니다.
edc65

@ edc65 수정하지 않고 어떻게 같은 수를 얻 i습니까? 나는 그것이 s.substr(i,i+i)같은 것을 반환 s.slice(i,i+=i)하지만 i나중에 수정 된 값을 사용 한다는 것을 알고 있습니다 ...
Neil

그건 s.substr(i,i)2 바이트 이하, 다음 s.slice(i+i)2 바이트 이상
edc65

@ edc65 물론, 더 많은 커피가 필요합니다 ...
Neil

3

파이썬, 58 바이트

f=lambda s,p='':s>''and(f(p)>-(s==p)<f(s))|f(s[1:],p+s[0])

이는 Dennis의 재귀 적 방법을 기반으로합니다 . 부울 부정 트릭도 거기에서 가져옵니다.

새로운 아이디어는 의 첫 번째 문자로 (p,s)시작하여 ('',s)반복 하여 원래 문자열의 파티션 을 반복 s하여 마지막 문자가되도록하는 것입니다 p. 이를 통해 스트링 슬라이싱없이 부품을 직접 참조 할 수 있습니다. 그러나 파티션이 p비어있는 것으로 시작하기 때문에 무한 루프 f(s)호출 을 피해야합니다 f(s).


2

자바 스크립트 (ES6), 24 바이트

x=>/^((.+)\2)+$/.test(x)

아마 이것보다 짧지 않을 것입니다.


그렇지 \2않습니까?
Neil

어떤 이유 @Neil, 나는 그것이 일한 생각 \1하지만, aab반환 true수정에 대한 ... 감사합니다.
ETHproductions



1

라켓 230 바이트

(let((sl string-length)(ss substring))(if(odd?(sl s))(printf ".~n")(begin(let p((s s))(if(equal? s "")(printf "!")
(for((i(range 1(add1(/(sl s)2)))))(when(equal?(ss s 0 i)(ss s i(* 2 i)))(p(ss s(* 2 i)(sl s)))))))(printf ".~n"))))

'!'를 인쇄합니다 문자열이 쌍을 이루는 각 방법에 대해. '.'를 인쇄합니다 끝에.

언 골프 드 :

(define (f s)
  (let ((sl string-length)                              ; create short names of built-in fns
        (ss substring))
    (if (odd? (sl s))  (printf ".~n")                   ; odd length strings cannot be pairable; end here.
        (begin
          (let loop ((s s))                             ; start testing here
            (if (equal? s "") (printf "!")              ; if no remaining string, it must be pairable
                (for ((i (range 1 (add1 (/(sl s)2)))))  ; ch lengths varying from 1 to half of string length
                  (when (equal? (ss s 0 i)              ; ch if substrings are same
                                (ss s i (* 2 i)))
                    (loop (ss s (* 2 i) (sl s) ))))))   ; if yes, loop to check remaining string.
          (printf ".~n")))))                            ; End of testing.

테스트 :

(println "Following should be pairable")
(f "bbaabbaa")            ; should produce 2 '!' since 2 ways are possible.
(f "aa")
(f "abaaba")
(f "bbababbb")
(f "aabaaababbbaba")
(f "babababa")                    ; should be pairable in 2 ways.
(f "bbbbbbbbbbbb")                ; should be pairable in many ways.
(f "aaababbabbabbbababbaabaabaababaaba")
(f "aaaabaab")
(println "Following should be unpairable")
; (f "a")
(f "ba")
(f "baab")
(f "abaabaaba")
(f "bbbbbbbbbbbbbbb")
(f "baababbabaaaab")
(f "aaaaabbaaaaa")

산출:

"Following should be pairable"
!!.
!.
!.
!.
!.
!!.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.
!.
!.
"Following should be unpairable"
.
.
.
.
.
.

1

Perl, 16 +2 = 18 바이트 (정규식 사용)

-nl플래그로 실행하십시오 . -E무료입니다.

say/^((.+)\2)+$/

다음으로 실행 :

perl -nlE 'say/^((.+)\2)+$/'

페어링 가능한 경우 캡처 그룹 (진실한)의 목록을 반환하고, 페어링 할 수없는 경우 null 문자열을 반환합니다.

설명

-nl플래그는 루프의 코드를 (실행 -n(때문에 제거 된 줄 바꿈을 후행 입력을 가하고,) -l변수에) $_프로그램을 수동으로 종료 될 때까지, 각 시간 입력이 입력 한 코드를 평가, 때마다. -E플래그는 명령 줄에서 코드를 평가할 수 있도록하고 수 say명령을 사용합니다.

say/^((.+)\2)+$/

   /^((.+)\2)+$/  #The regex engine
      (.+)\2      #Find any set of at least one character, followed by itself
     (      )+    #Do this at least one time
   /^         $/  #Make sure that this matches the entire string from start to end
say               #Output the result of the regex

일치하는 것이 발견되면 (예 : 문자열을 쌍으로 묶을 수있는 경우) 정규식은 캡처 그룹의 목록을 반환합니다 say. 일치하는 것이 없으면 정규식은 빈 문자열을 반환합니다.이 문자열은 거짓으로 평가되어로 전달되어 say출력됩니다.

견본:

$ perl -nlE 'say/^((.+)\2)+$/'
aaababbabbabbbababbaabaabaababaaba
baababaababaaba                      #Truthy
baababbabaaaab
                                     #Falsy
bbababbb
bbb                                  #Truthy
aabaaababbbaba
bababa                               #Truthy
abaabaaba
                                     #Falsy

1

GNU 프롤로그, 49 46 바이트

문자열을 모두 같은 방식으로 나타내지는 않지만 다른 변형에서도 작동합니다. GNU Prolog의 표현은이 문제에 유용한 것입니다.

이것이 정규식을 사용하는지 여부는 확실하지 않습니다. 정규식과 같은 기능을 사용하지 않지만 언어의 전체 의미는 정규식과 유사합니다.

새 버전 (다른 답변에서 볼 수있는 재귀 트릭 사용) :

s(X):-append(A,B,X),(A=B;A\=X,B\=X,s(A),s(B)).

이전 버전 :

s(X):-X=[];append(A,B,X),B\=X,append(C,C,A),s(B).

이것은 s완전한 프로그램이 아닌 이라고하는 술어 (프롤로그의 기능과 동등한 기능) 입니다. 다음과 같이 사용하십시오.

| ?- s("aa").
true ?
yes
| ?- s("aaababbabbabbbababbaabaabaababaaba").
true ?
yes
| ?- s("baababbabaaaab").
no
| ?- s("bbbbbbbbbbbbbbb").
no

이전 솔루션의 흥미로운 특징은 통역사에 "더 많은 솔루션이 있습니까?" 의 사용을 통해 ;상기 true ?프롬프트가 여러 번 문자열이 표현 될 수있는 다른 방법의 수와 같다 "true"를 반환 (오히려 물어보다 내가 위에서처럼, 프롬프트에서 수익을 누르면 통해 "모든 솔루션이있다") 주어진 형식으로 (예 : s("aaaa").(a a)(a a)또는로 구문 분석 될 수 있으므로)를 사용 하여 "true"를 두 번 리턴합니다 (aa aa).

프롤로그 프로그램은 종종 뒤집을 수 있습니다 ( 주어진 속성으로 문자열 목록 s생성 할 수 있음 ). 오래된 것은 그렇지 않습니다 (무한한 루프로갑니다). 왜냐하면 C가 비어 있지 않은지 확인하기 위해 사용한 골프 방법 때문입니다. C를 명시 적으로 비어 있지 않은 것으로 지정하도록 프로그램을 다시 작성하는 경우 "aa", "aabb", "aabbcc"등의 문자열이 생성됩니다 (Prolog는 프롤로그이므로이를 만드는 문자의 ID는 지정하지 않습니다) 위로, 어떤 문자가 동일한 지에 대한 사양). 최신 버전은 "aa", "abab", "abcabc"등의 문자열을 생성합니다. 이것은 그 자체로는 무한 루프이므로 길이가 0 인 문자열을 감지하지 못해 멈추는 지점에 절대로 도달하지 않습니다.


1

Brainfuck, 177 바이트

+[<<<<,]>>>>[>+[>+[[>>]<+<[<<]>+>-]<[>+<-]>>>,>>[>>]+<<[<+>>-<-]<[>+<-]>>[,>[-<<
<<]<[<<<<]>]<[[<<]>]>>]>>[[>+>>>]>>>[>]<<<<[>+[-<<<,<]<[<<<[[<<<<]>>]<]>]>>]<[[-
>>>>]>>[<]<]<<]<.

형식화 :

+[<<<<,]
>>>>
[
  >+
  [
    >+
    [
      [>>]
      <+<[<<]
      >+>-
    ]
    <[>+<-]>
    >>,>>[>>]
    +<<[<+> >-<-]
    <[>+<-]>
    >
    [
      not equal
      ,>[-<<<<]
      <[<<<<]
      >
    ]
    <
    [
      equal
      [<<]
      >
    ]
    >>
  ]
  >>
  [
    mismatch
    [>+>>>]
    >>>[>]
    <<<<
    [
      backtrack
      >+[-<<<,<]
      <
      [
        not done yet
        <<<
        [
          [<<<<]
          >>
        ]
        <
      ]
      >
    ]
    >>
  ]
  <
  [
    match
    [->>>>]
    >>[<]
    <
  ]
  <<
]
<.

후행 줄 바꿈없이 입력을 예상합니다. \x00거짓과 \x01참으로 인쇄 합니다.

온라인으로 사용해보십시오.

이것은 깊이 우선 검색을 구현합니다. 특히 : 현재 접미사에서 시작하여 길이가 늘어나는 반복 접두사를 확인한 다음 일치하는 항목이 있으면 다음 접미사로 이동하고, 그렇지 않으면 역 추적합니다.

처음에는 문자열이 반전되고 센티넬 \x01이 끝에 배치됩니다.

테이프는 4 셀 노드로 나뉩니다. 노드의 메모리 레이아웃은 다음과 같습니다.

c h x 0

여기서, c캐릭터는, h캐릭터가 반복 프리픽스의 전반부에 있는지 여부에 대한 플래그이고, x비교되는 캐릭터의 현재 쌍을 추적하기위한 플래그이다. h그동안 플래그는 장소에 머물 x플래그가 움직이는 창을 형성한다.

스트링이 쌍을 이룰 수있는 경우 포인터는 메인 루프의 끝에서 센티넬 옆에 놓입니다. 그렇지 않으면 역 추적하는 동안 포인터가 문자열의 왼쪽에서 떨어집니다.


1

Brachylog , 5 바이트

~c~jᵐ

온라인으로 사용해보십시오!

이 알고리즘이 걸릴 수 있습니다 매우 는 입력 문자열의 가능한 모든 파티션을 검사하기 때문에, 특히 falsey 경우에, 긴 시간.

설명

~c     Reversed concatenate: find a list that, when concatenated, results in the input string
       This examines all partitions of the input
  ~jᵐ  Map reversed juxtapose: for each string in that list, is it the result of concatenating
       a string to itself?

같은 입력 문자열의 경우 "ababcc", ~c이에 올 때까지 다른 파티션을 시도 ["abab", "cc"]하는 시점, ~j목록의 두 항목에 대한 성공 출력 ["ab", "c"]하고, 술어는 성공합니다.



0

Lithp , 57 자

#S::((? (!= (null) (match S "^((.+)\\2)+$")) true false))

샘플 사용법 :

% pairable_strings.lithp
(
    (def f #S::((? (!= (null) (match S "^((.+)\\2)+$")) true false)))
    (print (f "aa"))
    (print (f "aabaaababbbaba"))
    (print (f "aaababbabbabbbababbaabaabaababaaba"))
    (print (f "ba"))
)

# ./run.js pairable_strings.lithp
AtomValue { value: 2, type: 'Atom', name: 'true' }
AtomValue { value: 2, type: 'Atom', name: 'true' }
AtomValue { value: 2, type: 'Atom', name: 'true' }
AtomValue { value: 3, type: 'Atom', name: 'false' }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.