회문으로 다운 그레이드


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문자가 생략 된 문자열을 초기화 한 다음 원본에서 연속 문자를 복사하여 간격을 이동하는 것으로 시작합니다. 예를 들어, 문자열 foobarw== 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.