회문으로 다운 그레이드


47

문자열이 주어지면 s회문을 만들기 위해 제거 할 수있는 가장 작은 연속 하위 문자열 을 반환하십시오.


예 :

800233008   -> 2
racecarFOOL -> FOOL
abcdedcba   -> (empty string)
ngryL Myrgn -> "L " (or " M")
123456789   -> 12345678 (or 23456789)
aabcdbaa    -> c (or d)
[[]]        -> [[ (or ]])
a           -> (empty string)

사용자의 테스트 사례 제안 (만약 목록에없는 사례를 발견 한 경우 의견을 게시하십시오) :

aabaab      -> b    | Suggested by Zgarb, some returned "aa".

규칙

  • 인쇄 가능한 ASCII 문자 만 입력에 나타납니다 (줄 바꿈 없음, 단순하게 유지).
  • 별로 규칙지만, 주 <>, /\, (), []및 {}회문이 없습니다.

이것은 , 가장 작은 바이트 수의 승리입니다.


Adnan이 +100 현상금을 주장했습니다.


3
Tesf 사례 :aabaab
— Zgarb

14
“CMC”와 같은 그룹 내 전문 용어를 피하면 더 많은 방문자가 질문에 계속 액세스 할 수있게 될 것입니다. 이 장소).
— ShreevatsaR

되지는 [[]]회문?
— Carl

4
@Carl 그것은 하나처럼 보일지 모르지만, 문자를 바꾸면 얻을 수 ]][[있습니다. 즉 고려 aabb, 단지 다른 문자 같은 일이다.
— 코너 오브라이언

1
" (7/12가 수여 될 것입니다) "응?
— Outgolfer Erik

답변:


8

젤리 , 16 바이트

Ḣ;Ṫµ=Ṛ
0,0jŒṖÇÞṪ

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

작동 원리

0,0jŒṖÇÞṪ  Main link. Argument: s (string)

0,0j       Join [0, 0], separating by s. This prepends and appends a 0 to s.
    ŒṖ     Build all partitions of the resulting array.
      ÇÞ   Sort the partitions by the helper link.
           As a side effect, this will remove the first and last element of each
           partition. The 0's make sure that not removing any characters from s
           will still remove [0] from both sides.
        Ṫ  Tail; extract the last one.


Ḣ;Ṫµ=Ṛ     Helper link. Argument: A (array/partition)

Ḣ          Head; yield and remove the first chunk of A.
  Ṫ        Tail; yield and remove the last chunk of A.
 ;         Concatenate head and tail.
   µ=Ṛ     Compare the result, character by character, with its reverse.
           A palindrome of length l will yield an array of l 1's, while a
           non-palindrome of length l will yield an array with at least one 0 among
           the first l/2 Booleans. The lexicographically largest result is the one
           with the longest prefix of 1's, which corresponds to the longest
           palindrome among the outfixes.

10

J , 24 바이트

(0{::(-:|.)\.#&,<\)~i.@#

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

설명

(0{::(-:|.)\.#&,<\)~i.@#  Input: array of chars S
                       #  Length of S
                    i.@   Range, [0, 1, ..., len(S)-1]
(                 )~      Dyadic verb on range and S
           \.               For each outfix of S of size x in range
        |.                    Reverse
      -:                      Matches input (is palindrome)
                <\          Box each infix of S of size x in range
             #&,            Flatten each and copy the ones that match
 0{::                       Fetch the result and index 0 and return

(;&quote f)&>테스트 하네스 동사 로 선택하고 싶 습니까?
— 코너 오브라이언

7

Wolfram Language (Mathematica) , 53 51 바이트

바이트 수는 CP-1252 인코딩을 가정합니다.

±{a___,Shortest@b___,c___}/;PalindromeQ[a<>c]:={b}

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

단항 연산자 ±(또는 함수 PlusMinus)를 정의합니다 . 입력 및 출력은 문자 목록입니다. 테스트 스위트는 편의를 위해 실제 문자열과 실제 문자열 간의 변환을 수행합니다.


그렇다면 ReversePalindromeQ보다 원래의 것과 반대로 비교하는 것입니까? 나는 Mathematica를 모른다. 그래서 모른다.
— Magic Octopus Urn

좋은 대답이지만 문자열을 분할하고 문자 수로 다시 결합하는 것을 설명해서는 안됩니까? Characters@#/.{a___,Shortest@b___,c___}/;PalindromeQ[a<>c]:>b~~""&
— 켈리 로우더

@MagicOctopusUrn Reverse[x={a,c}]==x은 2 바이트 더 깁니다. 더 짧은 대안이 있는지 모르겠습니다.
— 마틴 엔더

@KellyLowder 문자 목록은 PPCG에서 유효한 문자열 표현입니다. Mathematica에서는 일반적으로 해당 표현을 사용하지 않지만 여전히 유효합니다. 메타 포스트를 파헤쳐 볼게요.
— Martin Ender

1
@KellyLowder 이것이 허용되는 정책 이라고 생각 합니다 . Mathematica에서 어색한 주된 이유는 Mathematica에 실제 문자 유형이 없기 때문에 문자가 단일 문자열이되기 때문입니다.
— Martin Ender


5

05AB1E , 18 바이트

ā<Œ¯¸«ʒRõsǝÂQ}éнèJ

05AB1E 인코딩을 사용합니다 . 온라인으로 사용해보십시오!


거기에 필터의 흥미로운 사용법 ... 우리는 "a without b"타입의 거래를 시도하고 있었지만, 두 개의 하위 문자열 인스턴스가 있다면 거짓 부정을 얻게됩니다. 이 롤이 보이기 때문에 우리가 너무 복잡하게 느낀 것 같습니다. 2 일 안에 100 현상금을드립니다.
— Magic Octopus Urn

ǝ그래도 천재였다.
— Magic Octopus Urn





2

프롤로그 , 271 바이트

p([_]).
p([X,X]).
p([X|Y]):-append([P,[X]],Y),p(P).

s(P,M,S,R,N):-p(P),append([M,S],N).
s(P,M,S,S,N):-p(S),append([P,M],N).
s(P,M,S,P,M):-append([P,S],X),p(X).

d(Y,P,N):-
    findall([A,B,C],(append([R,M,X],Y),s(R,M,X,B,C),length(B,A)),S),
    sort(1,@>,S,[[_,P,N]|_]).

어느 시점에서 나는 이것이 코드 골프 표준에 의해 거대해질 것이라는 것을 깨달았으므로 난독 화되지 않은 버전과의 유사성을 유지하기 위해 빈 공간을 몇 개 더 두었습니다. 그러나 나는 그것이 문제에 대한 다른 접근법이기 때문에 여전히 흥미로울 것이라고 생각합니다.

난독 화되지 않은 버전 :

palindrome([_]).
palindrome([X, X]).
palindrome([X | Xs]) :-
    append([Prefix, [X]], Xs),
    palindrome(Prefix).

palindrome_split(Prefix, Mid, Suffix, Prefix, N) :-
    palindrome(Prefix),
    append([Mid, Suffix], N).
palindrome_split(Prefix, Mid, Suffix, Suffix, N) :-
    palindrome(Suffix),
    append([Prefix, Mid], N).
palindrome_split(Prefix, Mid, Suffix, P, Mid) :-
    append([Prefix, Suffix], P),
    palindrome(P).

palindrome_downgrade(NP, P, N):-
    findall(
        [La, Pa, Na],
        (append([Prefix, Mid, Suffix], NP),
         palindrome_split(Prefix, Mid, Suffix, Pa, Na),
         length(Pa, La)),
        Palindromes),
    sort(1, @>, Palindromes, [[_, P, N] | _]).

2

C ++, 254 248 246 바이트

Zacharý 덕분에 -6 바이트 Toby Speight 덕분에 -2 바이트

#include<string>
#define S size()
#define T return
using s=std::string;int p(s t){for(int i=0;i<t.S;++i)if(t[i]!=t[t.S-i-1])T 0;T 1;}s d(s e){if(!p(e))for(int i,w=1;w<e.S;++w)for(i=0;i<=e.S-w;++i){s t=e;t.erase(i,w);if(p(t))T e.substr(i,w);}T"";}

그래서...

  • 나는 문자열 리터럴 (원시 문자열 리터럴을 정의하는 데 사용되는 접두어, 자세한 정보는 cppreference 참조 )에 대한 다른 효과를 T수행하기 때문에 매크로 정의 R""로 사용했습니다.T""
  • 전 처리기 정의는 같은 줄에있을 수 없으며 정의에서 이름과 내용 사이에 공백이 하나 이상 있어야합니다.
  • 2 가지 기능 : p(std::string)현이 회문인지 테스트합니다. 1이 경우을 캐스팅하고을 반환 true하고 그렇지 0않으면를 캐스팅합니다false
  • 이 알고리즘은 매번 1 요소를 지울 때 회문 인 경우 전체 문자열 테스트를 반복 한 다음 첫 번째 색인에서까지 요소 2 개를 지 웁니다 (문자열의 최대 크기까지 루프) the last index - number of erased char. 소거 된 부분이 회문 (palindrome) 인 것을 발견하면 돌아온다. 문자열을 통과 할 때 예를 들어, "aabcdbaa"매개 변수 등을 모두 c하고 d유효한 대답하지만,이 코드가 반환 c을 삭제하고 회문인지 테스트하기 때문에 삭제하는 경우 테스트하기 전에 제공 d및 테스트 경우의 회문
  • 테스트 할 코드는 다음과 같습니다.

    std::initializer_list<std::pair<std::string, std::string>> test{
        {"800233008","2"},
        { "racecarFOOL","FOOL" },
        { "abcdedcba","" },
        { "ngryL Myrgn","L " },
        { "123456789","12345678" },
        { "aabcdbaa","c" },
        { "[[]]","[[" },
        { "a","" },
        { "aabaab","b" }
    };
    
    for (const auto& a : test) {
        if (a.second != d(a.first)) {
            std::cout << "Error on : " << a.first << " - Answer : " << a.second  << " - Current : " << d(a.first) << '\n';
        }
    }

이것이 마지막 줄에서 작동합니까? using s=std::string;int p(s t){for(int i=0;i<t.S/2;++i)if(t[i]!=t[t.S-i-1])T 0;T 1;}s d(s e){if(!p(e))for(int i,w=1;w<e.S;++w)for(i=0;i<=e.S-w;++i){s t=e;t.erase(i,w);if(p(t))T e.substr(i,w);}T"";}
— Zacharý

/2생략 할 수 있습니까 ? 전체 길이에 걸쳐 반복하면 단순히 우리가 한 테스트가 반복되며, 이는 무해해야합니다. "다른 효과"의 의미를 확장하고 싶을 수도 있습니다 R""(즉, 원시 문자열 리터럴로 구문 분석 됨).
— Toby Speight

나는 이것을 수정하고 결과 를 내 자신 의 답변 으로 추가했습니다 .
— Toby Speight




1

자바 스크립트, 90 바이트

a=>a.map((_,p)=>a.map((_,q)=>k||(t=(b=[...a]).splice(q,p),k=''+b==b.reverse()&&t)),k=0)&&k

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



1

자바 스크립트 (ES6), 91 78 바이트

(s,i=0,j=0,S=[...s],b=S.splice(i,j))=>S+''==S.reverse()?b:f(s,s[++i]?i:!++j,j)

입력 및 출력은 문자 목록입니다.

회문이 발견 될 때까지 입력에서 더 크고 더 큰 슬라이스를 재귀 적으로 제거합니다.

단편:


1

TSQL (2016) 349B

가장 컴팩트하지만 간단한 솔루션은 아닙니다.

DECLARE @i VARCHAR(255)='racecarFOOL'
;WITH DAT(v,i,l)AS(SELECT value,(ROW_NUMBER()OVER(ORDER BY value))-1,LEN(@i)FROM STRING_SPLIT(REPLICATE(@i+';',LEN(@i)+1),';')WHERE value<>'')
SELECT TOP 1C,S
FROM(SELECT LEFT(D.v, D.i)+SUBSTRING(D.v,D.i+E.i+1,D.l)C,SUBSTRING(D.v,D.i+1,E.i)S
FROM DAT D CROSS APPLY DAT E)C
WHERE C=REVERSE(C)
ORDER BY LEN(C)DESC

@몇 바이트의 변수로 사용할 수 있습니다 . CTE에서는 where''=value)다른 것을 사용할 수 C있으며 결과 를 반환 할 필요가 없습니다 .
— MickyT

1

껍질 , 18 바이트

◄LfmS=↔†!⁰ṠM-Qŀ⁰Q⁰

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

설명

◄LfmS=↔†!⁰ṠM-Qŀ⁰Q⁰  Input is a string, say s="aab"
              ŀ⁰    Indices of s: x=[1,2,3]
             Q      Slices: [[],[1],[1,2],[2],[1,2,3],[2,3],[3]]
          ṠM-       Remove each from x: [[1,2,3],[2,3],[3],[1,3],[],[1],[1,2]]
       †!⁰          Index into s: ["aab","ab","b","ab","","a","aa"]
   mS=↔             Check which are palindromes: [0,0,1,0,1,1,1]
  f             Q⁰  Filter the slices of s by this list: ["aa","aab","ab","b"]
◄L                  Minimum on length: "b"


1

C ++, 189 186 176 167 바이트

HatsuPointerKun의 답변으로 시작하여 반전 된 문자열과 동등성을 간단히 비교하도록 테스트를 변경했습니다. 그런 다음 후보 문자열을 열거하는 방법을 변경했습니다. 그 후, 매크로는 한 번 또는 두 번만 사용되었으며 인라인하는 것이 더 짧았습니다.

#include<string>
using s=std::string;s d(s e){for(int i,w=0;;++w){s t=e.substr(w);for(i=-1;++i<=t.size();t[i]=e[i])if(t==s{t.rbegin(),t.rend()})return e.substr(i,w);}}

설명

동등한 가독 코드 :

std::string downgrade(std::string e)
{
    for (int w=0; ; ++w) {
        std::string t = e.substr(w);
        for (int i=0;  i<=t.size();  ++i) {
            if (t == std::string{t.rbegin(),t.rend()})
                // We made a palindrome by removing w chars beginning at i
                return e.substr(i,w);
            t[i] = e[i];  // next candidate
        }
    }
}

후보의 열거는 첫 번째 w문자가 생략 된 문자열을 초기화 한 다음 원본에서 연속 문자를 복사하여 간격을 이동하는 것으로 시작합니다. 예를 들어, 문자열 foobar및 w== 2 :

foobar
  ↓↓↓↓
  obar
foobar
↓
fbar
foobar
 ↓
foar
foobar
  ↓
foor
foobar
   ↓
foob

첫 번째 패스 ( w== 0)는 작동하지 않으므로 전체 문자열이 반복해서 간주됩니다. 골프는 효율성을 능가합니다! 이 루프의 마지막 반복은 과거의 마지막 인덱스에 액세스합니다. 나는 GCC로 그것을 벗어나는 것처럼 보이지만 엄밀히 말하면 그것은 정의되지 않은 행동입니다.

테스트 프로그램

HatsuPointerKun의 답변 에서 직접 상승 :

static const std::initializer_list<std::pair<std::string, std::string>> test{
    { "800233008", "2" },
    { "racecarFOOL", "FOOL" },
    { "abcdedcba", "" },
    { "ngryL Myrgn", "L " },
    { "123456789", "12345678" },
    { "aabcdbaa", "c" },
    { "[[]]", "[[" },
    { "a","" },
    { "aabaab", "b" }
};

#include <iostream>
int main()
{
    for (const auto& a : test) {
        if (a.second != d(a.first)) {
            std::cout << "Error on: " << a.first
                      << " - Expected: " << a.second
                      << " - Actual: " << d(a.first) << '\n';
        }
    }
}

0

REXX, 132 바이트

a=arg(1)
l=length(a)
do i=1 to l
  do j=0 to l-i+1
    b=delstr(a,i,j)
    if b=reverse(b) & m>j then do
      m=j
      s=substr(a,i,j)
      end
    end
  end
say s


0

C (gcc) , 307 바이트

#define T malloc(K)
P(S,i,y,z,k,u,L,K,V)char*S;{char*M,*R,*E;K=strlen(S);M=T;R=T;E=T;for(i=0;i<K;++i){for(y=0;y<=K-i;++y){strcpy(M,S);for(z=y;z<y+i;E[z-y]=M[z],++z);for(k=y;k+i<=K;M[k]=M[k+i],++k);V=strlen(M);strcpy(R,M);for(u=0;u<V/2;L=R[u],R[u]=R[V-u-1],R[V-u-1]=L,++u);if(!strcmp(M,R))puts(E),exit(0);}}}

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

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