パリンドロームへのダウングレード


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文字のみが表示されます(改行はありません、シンプルにしてください)。
  • そうでもないルールが、ノート<>/\()[]および{}回文ではありません。

これは、最小バイト数が勝ちます。


アドナンは+100の賞金を獲得しました


3
Tesfの場合:aabaab
Zgarb

14
「CMC」などのグループ内の専門用語を避ければ、より多くの訪問者が質問にアクセスできるようになると思います(見上げると、「チャットミニチャレンジ」の略語と思われます。このサイト)。
シュリーバツァー

[[]]回文ではありませんか?
カール

4
@Carlこれは1つのように見えるかもしれませんが、文字を逆にするとが得られ]][[ます。それaabbは同じことであり、キャラクターが異なるだけだと考えてください。
コナーオブライエン

1
(7/12が授与されます
エリックアウトゴルファー

回答:


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言語(Mathematica)53 51バイト

バイトカウントはCP-1252エンコードを前提としています。

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

オンラインでお試しください!

単項演算子±(または関数PlusMinus)を定義します。入力と出力は文字のリストです。テストスイートは、便宜上、実際の文字列との間で変換を行います。


されReverse、その後PalindromeQよりも短く、元にその逆を比較しますか?私はMathematicaを知らないので分かりません。
魔法のタコUr

良い答えですが、文字列の分割とそれらを文字カウントで結合することを説明すべきではありませんか? Characters@#/.{a___,Shortest@b___,c___}/;PalindromeQ[a<>c]:>b~~""&
ケリーロウダー

@MagicOctopusUrn Reverse[x={a,c}]==xは2バイト長くなります。もっと短い選択肢があるかどうかはわかりません。
マーティンエンダー

@KellyLowder文字のリストは、PPCG上の文字列の有効な表現です。Mathematicaでは通常はその表現を使用しませんが、少し厄介ですが、それでも有効です。メタ投稿を掘り下げます。
マーティンエンダー

1
@KellyLowder これは受け入れられているポリシーだと思います。Mathematicaで扱いにくい主な理由は、Mathematicaに実際の文字タイプがないため、文字がシングルトン文字列になることです。
マーティンエンダー


5

05AB1E、18バイト

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

05AB1Eエンコードを使用します。オンラインでお試しください!


フィルターの興味深い使用法...「aなしb」タイプの取引を行おうとしていましたが、サブストリングのインスタンスが2つある場合、偽陰性が発生しました。この笑を見ると、私たちはそれを過度に複雑にしていたように感じます。いいえ、2日間で100バウンティを差し上げます。
魔法のタコUr

ǝしかし、真剣に天才でした。
魔法のタコUr


3

Python 2、116バイト

def f(i):R=range(len(i)+1);print min([i[y:k+1]for y in R for k in R if(i[:y]+i[k+1:])[::-1]==i[:y]+i[k+1:]],key=len)

オンラインでお試しください!

Halvard Hummelの助けを借りて、数バイトを節約しました!



@HalvardHummelありがたいことに、私もそれを変更する予定でしたが、最後の2時間はインターネットに接続できませんでした。
ミスターXcoder



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"";}

そう...

  • Tがマクロ定義として使用したのは、R""文字列リテラルに別の効果を与えるためです(生の文字列リテラルを定義するために使用される接頭辞です、詳細についてはcppreferenceを参照してください)T""
  • プリプロセッサ定義を同じ行に置くことはできません。また、定義内の名前とコンテンツの間に少なくとも1つのスペースが必要です。
  • 2つの機能:p(std::string)文字列が回文であるかどうかをテストします。それは、それを返すの場合1にキャストtrue他に、それは返し0にキャストfalse
  • アルゴリズムは、1要素ごとに消去するときにパリンドロームであるかどうかをテストする文字列全体をループし、最初のインデックスから2要素を削除するテストを行います(文字列の最大サイズまでループします)the last index - number of erased char。一部を消去するとパリンドロームであることが判明した場合、リターンします。例えば、文字列を渡す"aabcdbaa"パラメータとして、両方cd有効な回答ですが、このコードは返されますが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"";}
ザカリー

/2省略できますか?全体に渡って反復することは、私たちが行ったテストを単に繰り返すだけで、無害です。「その他の効果」の意味を拡張したい場合がありますR""(つまり、生の文字列リテラルとして解析されます)。
トビー・スペイト

これを変更し、結果を自分の答えとして追加しました。
トビー・スペイト




1

JavaScript、90バイト

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

オンラインでお試しください!



1

JavaScript(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)では別のCTEに使用でき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の答えから始めました。テストを変更して、単純に等価性と逆ストリングを比較しました。次に、候補文字列の列挙方法を変更しました。これに続いて、マクロはそれぞれ1回または2回だけ使用され、インライン化する方が短くなりました。

#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の場合)はノーオペレーションであるため、完全な文字列は繰り返し考慮されます。それは大丈夫です-ゴルフは効率よりも優れています!このループの最後の反復は、最後の1つ前のインデックスにアクセスします。私はGCCでそれをうまく処理しているようですが、厳密には、それはUndefined Behaviourです。

テストプログラム

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.