양방향 회문 폐쇄 발전기


24

소개

입력 문자열의 회문 폐쇄는 최종 문자열이 입력 문자열로 시작하는 입력 문자열에서 구성 할 수있는 가장 짧은 회문입니다.

이 문제를 해결하기 위해 양방향 회문 폐쇄를 고려할 것입니다.

  • 입력 문자열의 왼쪽 회문 폐쇄 는 입력 문자열로 시작하는 가장 짧은 회문입니다.
  • 입력 문자열의 오른쪽 회문 폐쇄 는 입력 문자열로 끝나는 가장 짧은 회문입니다.
  • 입력 문자열의 양방향 Palindromic 폐쇄 는 입력 문자열의 왼쪽 또는 오른쪽 Palindromic 폐쇄 중 더 짧습니다.

태스크

당신의 작업은 간단합니다. 문자열 (인쇄 가능한 ASCII, 줄 바꿈 및 공백만으로 구성됨)이 주어진 경우 해당 문자열의 양방향 회문 폐쇄를 출력합니다. 동점 인 경우, 왼쪽 또는 오른쪽 회문 폐쇄는 유효한 출력입니다.

STDIN (또는 가장 가까운 대안), 명령 행 인수 또는 함수 인수를 통해 입력을 받고 결과를 STDOUT (또는 가장 가까운 대안)에 인쇄하거나 문자열로 리턴하여 프로그램 또는 함수를 작성할 수 있습니다.

입력이 절대 빈 문자열이 아니라고 가정 할 수 있습니다.

몇 가지 예 :

<Input>   -> <Output>
"abcdef"  -> "abcdefedcba"  (or "fedcbabcdef")
"abcba"   -> "abcba"
"abcb"    -> "abcba"
"cbca"    -> "acbca"

초기 아이디어 크레딧은 VisualMelon으로갑니다. 최종 아이디어는 Martin과 Zgarb의 도움으로

회문 폐쇄, 좌회 폐쇄 폐쇄 및 우회 폐쇄 폐쇄라는 용어가 본 논문에 의해 처음 사용되었고 정의되었다 .


1
회문 솔루션을보고 싶습니다 ...
ojdo

2
@ojdo 나는 그것을 보너스로 추가하려고 생각했지만 대부분의 답변이 회문을 만들기 위해 주석을 사용했을 것이라고 확신합니다. 의견에 의존하지 않고 답변이 실제로 회문이 될 수 있다면, 나는 그 답변에 대한 현상금을 남길 것입니다!
Optimizer

답변:


11

피스, 22 19

hfq_TTsm,+z_d+_dzyz

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

설명

양방향 palindromic 클로저는 형식 AX이거나 또는 XA여기서 X입력 문자열이며 A의 하위 문자열입니다 X. 실제로는 인접한 하위 문자열 X, 한 양식의 접두사, 다른 양식의 접미사 여야합니다 . 그러나 나는 이러한 실패에 대해서는 신경 쓰지 않습니다. Pyth에서 필요한 부분 문자열은 연속적이든 아니든 상관 없습니다.

                        Implicit: z = raw_input() // Read a string
                 yz     A list with all substrings (contiguous or not) of z
       m                For each of these substrings d, build
        ,                  a pair of two strings:
         +z_d              ( z + inveres(d) ,
             +_dz            inverse(d) + z )
      s                 Sum (put all created pairs into a list)
 fq_TT                  filter elements T, where inverse(T) == T (Palindrom)
h                          Take the first element

편집하다

이전 버전은 길이별로 필터링 한 후 문자열을 정렬했습니다 .olN.... 방금 인식하면 y길이별로 정렬 된 하위 문자열 을 반환합니다. 따라서이 회문은 이미 분류되어 있습니다.


6

클립 , 40

(sl`f[a=ava}+m[i+v+ixx}Rlxm[i+xvu0ix}Rlx

Documents>java -jar Clip4.jar palindrome.clip
abcb
abcba

설명

(sl`                                        .- The shortest                     -.
    f[a=ava}                                .- palindrome                       -.
            +                               .- among the following two sets:    -.
             m[i      }Rlx                  .- For each number up to length(x)  -.
                +                           .- combine                          -.
                 v+ix                       .- the last i chars of x, reversed  -.
                     x                      .- and x.                           -.
                          m[i       }Rlx    .- For each number up to length(x)  -.
                             +              .- combine                          -.
                              x             .- x and                            -.
                               vu0ix        .- the first i chars of x, reversed.-.

6

CJam, 30 바이트

실제로 CJam의 답변을보기를 바랐습니다.

q:Q,{)QW%/(Q+Q@+s}%{,}${_W%=}=

나는 그 {,}$블록을 정말로 싫어 하지만 사용중인 생성 알고리즘으로 인해 가능한 회 문의 정렬되지 않은 목록을 얻습니다.

코드 설명

q:Q,{            }%             "Read the input string, store in Q, take length and";
                                "run the code block that many times";
     )QW%                       "Increment the iteration index and Put reversed Q on stack";
         /                      "Split reversed Q into parts of incremented iteration index";
          (Q+                   "Take out the first part and prepend it to Q";
             Q@+s               "Take the rest of the parts and append them to Q";
                   {,}$         "At this point, we have all possible prepended and appended";
                                "sequences of the input string. Sort them by length";
                       {_W%=}=  "Take the first sequence which is a palindrome";

여기에서 온라인으로 사용해보십시오


6
나도 그 {,}$블록을 정말 싫어 ! 농담이야. CJam의 어떤 일인지 모르겠다.
Alex A.

4

파이썬 2, 115 113 109 105 96 바이트

f=lambda x:[x for x in sum([[x[:~i:-1]+x,x+x[i::-1]]for i in range(len(x))],[])if x==x[::-1]][0]

희망적으로 더 아래로 골프 수 있습니다. 주목할만한 비트 :

  • 하나의 두 목록 이해에 대한 합계 사용
  • 분의 필요성을 피하기 위해 정렬 된 순서로 용어 구성 (@Jakube에서 제안)

1
항목이 정렬 순서가 맞지 않기 때문에와 같은 문자열에서는 실패합니다 a.
Sp3000

4

수학, 96 바이트

이것보다 더 우아한 방법이 있어야합니다 ...

""<>#&@@SortBy[r=Reverse;#/.{b___,a__/;r@{a}=={a}}:>{b,r@{b,a}}&/@{r@#,#}&@Characters@#,Length]&

문자열을 가져와 결과를 반환하는 명명되지 않은 함수를 정의합니다.

기본 아이디어는

  • 문자열을 Characters .
  • 이리스트와 그 역순으로 배열을 구성하십시오.
  • 패턴 일치를 사용하여 각각의 올바른 회문을 찾으십시오.

    {b___,a__/;r@{a}=={a}}:>{b,r@{b,a}}
    

    이것은 실제로 단순 목록을 반환하지는 않습니다. 예를 위해 {a,b,c}당신이 얻을 것

    {a,b,{c,b,a}}
    
  • 두 결과를 길이별로 정렬하십시오.

  • 더 짧은 것을 고르고 문자열로 다시 합치십시오 ""<>#&@@.

abacaba입력이이면 출력 됩니다 abac. 정답은 cabac입니다. 길이별로 정렬하기 전에 평평하게 만들어야한다고 생각합니다.
alephalpha

1
@alephalpha 코드 크기를 변경할 필요가없는 더 나은 수정 프로그램을 찾았습니다 (실제로 정렬하지 않는 것이 제 의도였습니다).
Martin Ender

2

Brachylog (2), 6 바이트, 언어 날짜 도전 과제

~{↔?a}

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

Brachylog의 경우와 마찬가지로 이것은 전체 프로그램이 아니라 함수입니다.

설명

~{↔?a}
~{   }   Find a value that produces {the input} upon doing the following:
  ↔        reversing it;
   ?       asserting that we still have the same value;
    a      and taking either a prefix, or a suffix.

내가 아는 한 (내 언어는 아니지만 어려워 보인다) a 이 도전을 위해 Brachylog에 추가되지는 않았지만 여기서는 매우 편리합니다. 우리는 우리가 찾은 가치가 회문이라는 것을 주장하기 위해 "역전되고 변하지 않았다고 주장하는"방법을 사용합니다.

이것이 가장 짧은 회문을 생성하는 이유에 관해서는 , Prolog (및 Brachylog)의 평가 순서는 가장 먼저 평가되는 것에 크게 영향을받습니다. 이 경우 "역방향"명령이며 대부분의 목록 작업과 마찬가지로 결과 목록의 크기를 최소화하는 평가 순서를 설정합니다. 그것이 출력의 크기와 동일하기 때문에 프로그램은 우연히 옳은 일을 정확하게 최소화하여 결국 명확한 힌트를 추가 할 필요가 없다는 것을 의미합니다.


a-이 과제에는 Adfix가 추가되지 않았습니다. 접두사와 접미사에 대한 좋은 니모닉으로 사용할 수있는 기호가 없었으므로 필요한 경우에만 접두사 또는 접미사를 선택하기 위해 아래 첨자를 사용할 수있는 adfix로 병합했습니다.
Fatalize

1

루비, 76 + 2 = 78

명령 행 플래그를 사용하여 -pl( l입력 방식에 따라 필요하지 않을 수 있음)

$_=[[$_,r=$_.reverse]*"\0",r+"\0#$_"].min_by{|s|s.sub!(/(.*)\0\1/){$1}.size}

문자열 'abaa'가 주어지면 문자열 'cbca 0 acbc'및 'acbc 0 cbca'를 생성합니다. 여기서 0 은 ASCII 코드가 0 인 인쇄 할 수없는 문자입니다. 그런 다음 가장 긴 반복 문자열 프레이밍 0의 사본 하나를 삭제합니다. 은 각각의 발견은, 두 번째 클로저를 얻으려면 첫 번째 'a'와 두 번째 'cbc'입니다. 그런 다음 가장 짧은 결과를 출력합니다.

골프 코드의 유일한 이상한 점은 정렬하는 동안 문자열을 제자리에 단축시키는 min_by것입니다. 비교할 요소 당 한 번만 블록을 실행 하기 때문에 해결할 수 있습니다 (두 가지 모두 Schwartzian 변환 이므로 두 개만 있기 때문에) 비교할 요소).


1

파이썬 3, 107 바이트


f=lambda a:[i for i in[a[:i:-1]*j+a+a[-1-i::-1]*(1-j)for i in range(len(a))for j in(0,1)]if i==i[::-1]][-1]

테스트하려면 :

>>> print("\n".join(map(f, ["abcdef", "abcba", "abcb", "cbca"])))
abcdefedcba
abcba
abcba
acbca

1

하스켈, 107 바이트

import Data.List
r=reverse
f s=snd$minimum[(length x,x)|x<-map(s++)(tails$r s)++map(++s)(inits$r s),x==r x]

테스트:

*Main> mapM_ (putStrLn.f) ["abcdef", "abcba", "abcb", "cbca"]
abcdefedcba
abcba
abcba
acbca

1

J, 66 62 바이트

3 :'>({~[:(i.>./)(#%~[-:|.)@>),(<@([,|.@{.~)"#:i.@#"1)y,:|.y'

아주 간단합니다. 내가 사용하는 두 가지 트릭 :

오른쪽 회문 폐쇄는 반전 된 끈의 왼쪽 회문 폐쇄입니다.

min (is_palindrome / length) 표현식을 사용하여 최소 길이 및 palindromity를 가진 문자열의 길이 찾기

   f=.3 :'>({~[:(i.>./)(#%~[-:|.)@>),(<@([,|.@{.~)"#:i.@#"1)y,:|.y'

   f 'lama'
lamal

여기에서 온라인으로 사용해보십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.