最短の一意の部分文字列


29

入力

英数字の文字列s

出力

内の(連続した)サブストリングとして1回だけ出現する最短のストリングs。重複するオカレンスは個別としてカウントされます。同じ長さの候補が複数ある場合は、それらをすべて発生順に出力する必要があります。このチャレンジでは、空の文字n + 1列はlengthの文字列で何度も発生しますn

文字列を考えます

"asdfasdfd"

空の文字列は10回出現するため、一意の出現の候補ではありません。手紙のそれぞれ"a""s""d"、と"f"彼らはどちらかの候補ではないので、少なくとも2回出現します。サブストリング"fa""fd"は、この順序で1回だけ出現しますが、長さ2の他のすべてのサブストリングは2回出現します。したがって、正しい出力は

["fa","fd"]

ルール

関数と完全なプログラムの両方が許可されていますが、標準の抜け穴は許可されていません。出力の正確なフォーマットは、理由の範囲内で柔軟です。特に、空の文字列の出力を生成することはできませんが、エラーをスローすることはできません。最も低いバイトカウントが優先されます。

テストケース

"" -> [""]
"abcaa" -> ["b","c"]
"rererere" -> ["ererer"]
"asdfasdfd" -> ["fa","fd"]
"ffffhhhhfffffhhhhhfffhhh" -> ["hffff","fffff","hhhhh","hfffh"]
"asdfdfasddfdfaddsasadsasadsddsddfdsasdf" -> ["fas","fad","add","fds"]

リーダーボード

これが私が約束した言語別のリーダーボードです。

回答が表示されるようにするには、次のマークダウンテンプレートを使用して、見出しから回答を開始してください。

# Language Name, N bytes

N提出物のサイズはどこですか。スコアを改善する場合、古いスコアを打つことで見出しに残すことができます。例えば:

# Ruby, <s>104</s> <s>101</s> 96 bytes

<script src='https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js'></script><script>site = 'meta.codegolf',postID = 5314,isAnswer = true,QUESTION_ID = 45056;jQuery(function(){var u='https://api.stackexchange.com/2.2/';if(isAnswer)u+='answers/'+postID+'?order=asc&sort=creation&site='+site+'&filter=!GeEyUcJFJeRCD';else u+='questions/'+postID+'?order=asc&sort=creation&site='+site+'&filter=!GeEyUcJFJO6t)';jQuery.get(u,function(b){function d(s){return jQuery('<textarea>').html(s).text()};function r(l){return new RegExp('<pre class="snippet-code-'+l+'\\b[^>]*><code>([\\s\\S]*?)<\\/code><\/pre>')};b=b.items[0].body;var j=r('js').exec(b),c=r('css').exec(b),h=r('html').exec(b);if(c!==null)jQuery('head').append(jQuery('<style>').text(d(c[1])));if (h!==null)jQuery('body').append(d(h[1]));if(j!==null)jQuery('body').append(jQuery('<script>').text(d(j[1])))})})</script>


コンビナトリアル組み込み関数に制限はありますか?
マーティンエンダー

3
@MartinBüttnerこのチャレンジでは、すべてがうまくいきます。これで十分な答えが得られたら、言語別のリーダーボードを作成します。そのため、より設備の整っていない言語でも、意味のある競争ができます。
ズガルブ

私のコードゴルフリーダーボードスニペットを使用しますか?そうすれば、すべての編集を監視してリーダーボードを最新の状態に保つ必要がなくなります。あなたがそうするなら、私はあなたのためにそれを追加することができます、そして、私はそれらがヘッダー形式と一致するように答えを通過するでしょう。
マーティンエンダー

@MartinBüttnerありがとう、ありがとう!
ズガルブ

出来た!何か機能しない場合は教えてください。(将来の課題のために自由に再利用してください。)
マーティンエンダー

回答:


3

Pyth、27 26バイト

&zhfTmf!/>zhxzYYm<>zkdUzUz

ここで試してみてください。

オンラインコンパイラのバグのため、空の文字列の場合はコマンドラインバージョンでのみ正しく機能することに注意してください。

また、オンラインコンパイラの入力として改行を指定することにより、バグを解決できます。

説明:

                                   z = input(), implicit.
&z                                 Prints empty string if input is empty.
  hfT                              Take the first non-empty list from
     m                  Uz         A list of list of substrings of z, divided by length
                m<>zkdUz           with some shorter strings repeated later, to no effect.
      f                            Where the substrings are filtered on
       !/      Y                   There being 0 occurrences of the substring in
         >z                        The slice of z
           hxzY                    from the character after the first character
                                   of the first occurrence of the substring in z
                                   to the end of z.

空の文字列を入力すると失敗します。
オプティマイザー

@Optimizerそれは、実際にはオンラインコンパイラのバグだと思います。コマンドラインバージョンで動作します。実際、zオンラインで入力が失敗することはないため、インタープリターのバグです。
isaacg

EOFを与えませんか?
オプティマイザー

@Optimizer Pythは、改行で終了する入力を予期しますが、これが間違っている可能性があります。
isaacg

それで、空の文字列を渡すことさえできませんか?
オプティマイザー

13

Python 3、124 123 111 96バイト

f=lambda s,n=1:[x for x in[s[i:i+n]for i in range(len(s)+1)]if s.find(x)==s.rfind(x)]or f(s,n+1)

左からの最初の出現が右からの最初の出現と同じになるような文字列を探します。+1中には、range空の文字列の場合に対処することです。

重複するマッチ.count()をカウントする Pythonのみがある場合、これはかなり短くなります。


6

Mathematica、95 94 79バイト

Cases[Tally@StringCases[#,___,Overlaps->All],{s_,1}:>s]~MinimalBy~StringLength&

StringCases可能性のあるすべての部分文字列を取得し、複数回出現する部分文字列TallyCases除外しMinimalByて、最も短い部分文字列を見つけます。


&コードの最後に余分なものはありませんか?
デビッドG.ストーク

少年、あなたは速い!
デビッドG.ストーク

4

GolfScript、44バイト

:S;-1:x{;S,x):x-),{S>x<}%:^1/{^\/,2=},.!}do`

入力を標準入力の文字列として受け取り、二重配列構文で出力します[["b"] ["c"]]オンラインデモ

解剖

:S;          # Store input in S and pop it
-1:x         # Store -1 in x
{            # do-while loop
  ;          #   Pop x the first time and [] every subsequent time
  S,x):x-),  #   Increment x and build an array [0 1 ... len(S)-x]
  {S>x<}%    #   Map that array to [substr(S,0,x) substr(S,1,x) ...]
  :^         #   Store in ^ (to avoid the token coalescing with the next char)
  1/         #   Split by length 1 to iterate over 1-elt arrays rather than strings
  {^\/,2=},  #   Filter to arrays which occur exactly once as a subarray of ^
  .!         #   Duplicate and test emptiness
}do          # end do-while loop: loop if the filtered array is empty
`            # Stringify for output

これは、空の文字列に特別なケースが必要ないように調整されています(上記のリンクされたオンラインデモにテストケースとして含めました)。


3

CJam、52 43 40バイト

]]q:Q,,{)Q,1$-),f{Q><}:R{R\a/,2=},}%{}=p

入力は引用符なしの文字列です

説明

]]                                       "For empty string input case";
  q:Q                                    "Read the input and store in Q";
     ,,                                  "Take length of input and 0 to length array";
       {                          }%     "Map the above array on this code block";
        )Q                               "Increment the number in the current iteration, L";
         Q,1$                            "Take input's length and copy the above number";
             -)                          "Get upper limit of next loop to get substrings";
               ,f{   }                   "Get 0 to above number array and for each";
                  Q><                    "Get the L length substring at Ith index where";
                                         "I loops from 0 to Q, - L + 1";
                      :R                 "Store this list of substring of length L in R";
                        {R\a/,2=},       "Filter to get unique substrings";
                                    {}=  "Get the first non empty substring array";
                                         "This leaves nothing on stack if all are empty";
                                       p "Print the top stack element. At this point, its";
                                         "Either the first non empty substring array or";
                                         "the ]] i.e. [""] which we added initially";

例:

asdfdfasddfdfaddsasadsasadsddsddfdsasdf

出力

["fas" "fad" "add" "fds"]

こちらからオンラインでお試しください


3

Scala、120バイト

readLine.inits.flatMap(_.tails).toList.groupBy(l=>l).filter(x=>x._2.length<2).map(_._1).groupBy(_.length).minBy(_._1)._2

少なくともツイートに収まる140から始めました。

(                                        // added for comments
 readLine                                // input
.inits.flatMap(_.tails).toList           // get all substrings of that string
.groupBy(l=>l).filter(x=>x._2.length<2)  // remove substrings that occur more than once
.map(_._1).groupBy(_.length)             // take the substring and group by length
.minBy(_._1)._2                          // take the list of shortest substrings
)

私は疑問に思う?なぜ単に(_)アイデンティティとしてではなく機能しないのl=>lですか?
誇りに思っているhaskeller

私も疑問に思う。どういうわけかlist.groupBy(_)、と同じx => list.groupBy(x)です。私は彼らがそのようにそれを実装した理由がわかりません。
ドミニクミュラー

3

JavaScript(ES6)、109 110

入力文字列は英数字なので、indexOfの代わりに検索を編集します。ありがとう@IsmaelMiguel

再帰関数。長さ1から始まり、上に行く部分文字列を探します。

F=(s,n=1,r)=>
s?[...s].map((a,i)=>~s.indexOf(a=s.substr(i,n),s.search(a)+1)?r:r=[...r||[],a])&&r||F(s,n+1):[s]

非ゴルフと説明

 F = function(s, n=1) { // start with length 1
   var i, a, p, r;
   if (s == "") // special case for empty input string
     return [s];
   for (i = 0; i < s.length; i++) 
   // for each possibile substring of length n
   // (should stop at s.length-n+1 but going beyond is harmless)
   // Golfed: "[...s].map((a,i)" ... using i, a is overwrittem
   {
     a = s.substr(i, n); // substring at position i
     p = s.search(a); // p is the first position of substring found, can be i or less
     p = s.indexOf(a, p + 1) // p is now the position of a second instance of substring, or -1 if not found
     if (~p) // ~p is 0 if p is -1
     {
       ; // found more than once, do nothing
     }
     else
     {
       r = r || []; // if r is undefined, then it becomes an empty array
       r.push(a); // save substring 
       // Golfed: "r=[...r||[],a]"
     }
   }
   if (r) // if found some substring, saved in r
   {
     return r;
   }
   return F(s, n+1) // recursive retry for a bigger length
 }

FireFox / FireBugコンソールで テストする

;["", "abcaa", "rererere", "asdfasdfd", "ffffhhhhfffffhhhhhfffhhh", 
 "asdfdfasddfdfaddsasadsasadsddsddfdsasdf"]
.forEach(x=>console.log(x,F(x)))

出力

 [""]
abcaa ["b", "c"]
rererere ["ererer"]
asdfasdfd ["fa", "fd"]
ffffhhhhfffffhhhhhfffhhh ["hffff", "fffff", "hhhhh", "hfffh"]
asdfdfasddfdfaddsasadsasadsddsddfdsasdf ["fas", "fad", "add", "fds"]

.search代わりに使用し、.indexOf2バイトを節約します。
イスマエルミゲル

@IsmaelMiguelいいえ。1)検索にオフセットパラメータがないため2)検索に正規表現が必要であり、。* []などの特殊文字で失敗する
-edc65

1
しかし、最初は(でs.indexOf(a)+1)安全に置き換えることができます。それは火曜日ですが、それらの文字では動作しませんが、心配する必要はありません!OPの引用: " Input: An alphanumeric string s."
イスマエルミゲル

@IsmaelMiguel右、ありがとう。「英数字」制約を逃した
-edc65

1
@IsmaelMiguel方法が見つかりませんでした...真実か偽りが必要で、配列(空の[]でも)はjavascriptの真実の値です
-edc65

3

Java、168 176 233

これは非常に基本的なネストされたループの例です。

void n(String s){for(int l=0,i=0,t=s.length(),q=0;l++<t&q<1;i=0)for(String b;i<=t-l;)if(s.indexOf(b=s.substring(i,i+++l),s.indexOf(b)+1)<0){System.out.println(b);q++;}}

それとも少し読みやすく:

void t(String s){
    for(int l=0,i=0,t=s.length(),q=0;l++<t&q<1;i=0)
        for(String b;i<=t-l;)
            if(s.indexOf(b=s.substring(i,i++ +l),s.indexOf(b)+1)<0){
                System.out.println(b);
                q++;
            }
}

あなたは、読みやすさ、分割したい場合は+++、それはだかどうかを示すために、アップ+ ++または++ +役立つだろう...そして、あなたはいくつかのより多くのバイトを保存したい場合は、初期化によってそれを行うための方法があるかもしれないq=1、交換q++q=t、および交換l++<t&q<1のようなものでt>l+=q。おそらく、1つまたは2つの他のオフセットを調整して機能させる必要があります。
ピーターテイラー

@Peterまあ、読みやすいということは、主に「水平にスクロールする必要がない」という意味でしたが、を明確にしました+++。私はそれを微調整しようとしましたが(特にq、それはやや無駄に感じます)、まだしっかりしたものを見つけていません。
ジオビット

@PeterTaylor Javaの字句規則により、+++常にに解決され++ +ます。
-FUZxxl

@FUZxxl、私はほとんどのJavaユーザーでさえそれを知っているとは思わず、このサイトにはJavaを知らない人がたくさんいます。
ピーターテイラー

1
lastIndexOfの代わりにoffsetでindexOfを使用すると、1バイトをカットする必要があります(私のJavaScriptの答えを参照)
edc65

3

ハスケル、169 162 155 153 151 138 120 115

import Data.List
l=length
q k=filter$(==)k.l
p y=q(minimum.map l$y)$y
f x=p$concat$q 1$group$sort$(tails x>>=inits)

使用するには:

f "asdfdfasddfdfaddsasadsasadsddsddfdsasdf"

与えるもの:

["add","fad","fas","fds"]

ところで 私は自分のコードの最後の行が嫌いです(の繰り返しh y)。誰もそれを取り除くためのヒントですか?


1
あなたはどう定義しますかg y=q(minimum.(map l)$y)$y(括弧はmap l本当に必要ですか?)、そしてf=g.concat.q 1.group.sort.concatMap inits.tails
FUZxxl

1
>>=代わりに使用するとconcatMap、つまりf x=p$concat$q 1$group$sort$(tails x>>=inits)2バイト節約されます。Data.Ordインポートする理由
nimi

1
の括弧qは不要です。なぜなら、s inのfilter$(==)k.l最後$と空白の前にを書くことができるからです。インポート後にセミコロンを削除することもできます(実際には不要なようです)。ypData.Ord
ズガルブ

Leksahコンパイラは$、非スペースの後に続くものを受け入れません。数バイト削りますが、言語仕様に含まれていますか?
RobAu

1
GHCはそれを受け入れます。
ズガルブ

3

J、61 58 44 42 40 38 37バイト

[:>@{.@(#~#@>)#\<@(~.#~1=#/.~)@(]\)]

以下は、ソリューションの個々のコンポーネントに分割されたバージョンです。

unqs =. ~. #~ 1 = #/.~               NB. uniques; items that appear exactly once
allsbsq =. #\ <@unqs@(]\) ]        NB. all unique subsequences
shrtsbsq =. [: >@{.@(#~ #@>) allsbsq NB. shortest unique subsequence
  • x #/. yxで発生する頻度の異なる要素ごとに計算しyます。これをとして使用するとy #/. yyそのカウントの個別の要素ごとにを取得します。例えば、a #/. aのためのa =. 1 2 2 3 4 4利回り1 2 1 2
  • 1 = yのどのアイテムがyに等しいかをチェックします1。たとえば、1 = a #/. ayields 1 0 1 0
  • u~は単動詞の再帰uです。これは、u~ yと同じy u yです。したがって、はと#/.~ y同じ#/.~ yです。二項動詞に適用されると、u~受動態 ですu。つまり、はとx u~ y同じy u xです。これらは、私が明示的に言及していない他の多くの場所で使用されています。
  • ~. yは、重複部分が削除されたベクトルのnubですy。たとえば、~. ayields 1 2 3 4
  • x # yコピー)は、を含むyインデックスの項目から選択しxます1
  • したがって、(1 = y #/. y) # (~. y)それらの要素のベクトルを作成し、それらの要素はy一度しか現れません。暗黙の記法では、この動詞は次のように書かれてい~. #~ 1 = #/.~ます。unqs説明の残りの部分でこのフレーズを呼び出しましょう。
  • x ]\ ylength のベクトルのすべてのインフィックスのx by 1 + y - x配列を作成します。例えば、利回りyx3 ]\ 'asdfasdfd

    asd
    sdf
    dfa
    fas
    asd
    sdf
    dfd
    
  • # yあるタリーy、の要素の数です、y

  • u\ yuプレフィックスに適用されますy。ちなみに、#\ yからの整数のベクトルを作成1#yます。
  • < yy箱に入れます。これは、配列を不規則にすることはできず、異なる長さの接尾辞の配列を計算するために必要です。ボックス配列はスカラーとしてカウントされます。
  • このように、(i. # y) <@:unqs@(]\) yベクトル生成#y長さの四角で囲んだ配列K(全て0≤ためのK < #yの挿入辞)Y正確に一度起こります。この動詞の暗黙の形式は、i.@# <@unqs@(]\) ]または名前をi.@# <@(~. #~ 1 = #/.~)@(]\) ]使用しない場合unqsです。allsbsqこの説明の残りの部分では、このフレーズを呼び出しましょう。たとえば、次のallsbsq 'asdfasdfd'結果が得られます。

    ┌┬─┬──┬───┬────┬─────┬──────┬───────┬────────┐
    ││ │fa│dfa│sdfa│asdfa│asdfas│asdfasd│asdfasdf│
    ││ │fd│fas│dfas│sdfas│sdfasd│sdfasdf│sdfasdfd│
    ││ │  │dfd│fasd│dfasd│dfasdf│dfasdfd│        │
    ││ │  │   │sdfd│fasdf│fasdfd│       │        │
    ││ │  │   │    │asdfd│      │       │        │
    └┴─┴──┴───┴────┴─────┴──────┴───────┴────────┘
    
  • (#@> y) # yボックス化された配列のベクトルから、y空でない配列を取得します。

  • {. yvectorの最初の要素を取りますy
  • > yからボックスを削除しますy
  • したがって、> {. (#@> y) # yボックス化された配列のベクトルから、ボックス化されていない最初の空でない配列を生成しますy。このフレーズは>@{.@(#~ #@>)暗黙の記法で書かれています。
  • 最後に[: >@{.@(#~ #@>) allsbsq、前のフレーズallsbsqを組み合わせて、問題の解決策を作成します。スペースを含む完全なフレーズを次に示します。

    [: >@{.@(#~ #@>) i.@# <@(~. #~ 1 = #/.~)@(]\) ]
    

2

Haskell、135バイト

import Data.List
f ""=[""]
f g=map(snd)$head$groupBy(\a b->fst a==fst b)$sort[(length y,y)|[y]<-group$sort[x|x@(_:_)<-tails g>>=inits]]

2

PHP、171 152 134 125

function f($s){while(!$a&&++$i<strlen($s))for($j=0;$b=substr($s,$j++,$i);)strpos($s,$b)==strrpos($s,$b)&&($a[]=$b);return$a;}

http://3v4l.org/RaWTN


を明示的に定義する必要はありません$j=0。先に、ありますsubstr($s,$j++,$i)。を定義せずに$j、これを書き換えてsubstr($s,0+$j++,$i)2バイト節約できます。何故ですか?さて、初めて、に$jなりますnull。そして、あなたは実質的ににnull移行しますがsubstr、それはうまくいくとは思いません。を使用0+$j++すると、がに変換さnull0ます。必要ないことがわかった場合は、それなしで先に進み、$j=0パーツを削除してください。
イスマエルミゲル

それを試してみました。PHPには強力なスコープがないため機能しません。したがって$jwhile()ループの反復ごとにクリアおよび再初期化されません。したがって、最初はnullであるため(呼び出し0によって変換され$j++ます)、外側のループの将来の反復では、以前の値のままになります。それはリセットほど初期化ではありません。提案をありがとう:
スティーブン

ここで141バイトの長さのソリューションを提供します:function f($s){$l=strlen($s);while(!$a&&++$i<$l)for($j=0;$j<$l;)($b=substr($s,$j++,$i))&(strpos($s,$b)==strrpos($s,$b)&&($a[]=$b));return$a;}変更:すべてを削除し、1箇所ではなく||1ビット単位&AND)を使用し&&$j<$l&&[...]部品を外側に移動してfor(2バイトを節約)、不要な括弧を削除しました。
イスマエルミゲル

1
あなたのための1つの134バイトの長さの贈り物:function f($s){$l=strlen($s);while(!$a&&++$i<$l)for($j=0;$j<$l;)strpos($s,$b=substr($s,$j++,$i))==strrpos($s,$b)&&($a[]=$b);return$a;}前のコードに加えられた変更:にそれ$b=substr($s,$j++,$i)strpos($s,$b)作りstrpos($s,$b=substr($s,$j++,$i))、より不必要な括弧を削除し、不要なを削除しました&
イスマエルミゲル

1
もう少し細かく管理しsubstr($s,$j++,$i)ます:-) は、文字列の長さ""$j達すると戻ります。falseその後、割り当てはループ条件付きブレークとしても機能します。その後、$l残りの使用は1つだけなので、同様に統合できます。
スティーブン

2

Groovy(Oracle実装のJava正規表現)、124

c={m=it=~/(?=(.*?)(?=(.*))(?<=^(?!.*\1(?!\2$)).*))/;o=m.collect({it[1]});o.findAll({it.size()==o.min({it.size()}).size()});}

Groovy 2.4 + Oracle JRE 1.7でテスト済み。上記のコードが機能するバグは修正されていないため、Java 6からJava 8で正規表現が機能するはずです。以前のバージョンでは、Java 6で修正された後読みバグがJava 5にあるため、わかりません。

正規表現は、入力文字列のすべての位置で、他に重複する部分文字列を持たない最短の文字列を見つけます。外部のコードがフィルタリングを処理します。

(?=(.*?)(?=(.*))(?<=^(?!.*\1(?!\2$)).*))
  • 文字列は重複する可能性があるため、全体を先読みで囲みます (?=...)ます。
  • (.*?) 最短部分文字列から検索
  • (?=(.*)) 文字列の残りをキャプチャして、現在の位置をマークします。
  • (?<=^(?!.*\1(?!\2$)).*)は、可変長の後読みのエミュレーションです。これは(?<=.*)、長さチェックに合格することを可能にする実装バグを利用します。
  • (?!.*\1(?!\2$))他の場所で同じ部分文字列が見つからないことを確認するだけです。の(?!\2$)ストリングが一致した元の位置を拒否する。

    外側のルックアラウンド構成の制限は、ネストされたルックアラウンド構成には適用されません。したがって、ネストされたネガティブ先読みは、(?!.*\1(?!\2$))実際には後読みの右境界までだけでなく、文字列全体をチェックします。


2

Rebol、136バイト

f: func[s][repeat n length? b: copy s[unless empty? x: collect[forall s[unless find next find b t: copy/part s n t[keep t]]][return x]]]

ゴルフをしていない:

f: func [s] [
    repeat n length? b: copy s [
        unless empty? x: collect [
            forall s [
                unless find next find b t: copy/part s n t [keep t]
            ]
        ][return x]
    ]
]

使用例:

>> f ""       
== none

>> f "abcaa"
== ["b" "c"]

>> f "rererere"
== ["ererer"]

>> f "asdfasdfd"
== ["fa" "fd"]

>> f "ffffhhhhfffffhhhhhfffhhh"
== ["hffff" "fffff" "hhhhh" "hfffh"]

>> f "asdfdfasddfdfaddsasadsasadsddsddfdsasdf"
== ["fas" "fad" "add" "fds"]


NB。コードの核心は、そのfind部分がどのように機能するかだと思います。これが説明に役立つことを願っています...

>> find "asdfasdfd" "df"
== "dfasdfd"

>> next find "asdfasdfd" "df"
== "fasdfd"

>> find next find "asdfasdfd" "df" "df"
== "dfd"

>> ;; so above shows that "df" is present more than once - so not unique
>> ;; whereas below returns NONE because "fa" found only once - ie. bingo!

>> find next find "asdfasdfd" "fa" "fa"
== none

1

ハスケル、119

f s=[r|n<-[1..length s],l<-[map(take n)$take(length s-n+1)$iterate(drop 1)s],r<-[[j|j<-l,[j]==[r|r<-l,r==j]]],r/=[]]!!0

q = lengthどこかに置いて、qいくつかのバイトを
削り取る

1

Brachylog、10バイト

sᶠ≡ᵍ~gˢlᵍt

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

sᶠ            The list of every substring of the input
  ≡ᵍ          grouped by identity,
    ~gˢ       with length-1 groups converted to their elements and other groups discarded,
       lᵍ     and grouped by their length,
         t    has the output as its last group.

そのグループによる値ではない天然にソートし、代わりに、各値の最初の発生によってグループを注文、すべての長さの最初の発生が降順です。一意性フィルタリングがこれを台無しにできないことを100%確信していませんが、これがまだ失敗するテストケースを考え出していません。


1

05AB1E、10 バイト

Œʒ¢}é.γg}н

空の文字列に対しては何も出力しません。

オンラインそれを試してみたり、すべてのテストケースを確認してください

説明:

Π          # Get all substrings of the (implicit) input-String
 ʒ          # Filter it by:
  ¢         #  Count how many times the current substring occurs in the (implicit) input-String
            #  (only 1 is truthy in 05AB1E, so the filter will leave unique substrings)
          # After the filter: sort the remaining substrings by length
     g}   # Then group them by length as well
         н  # And only leave the first group containing the shortest substrings
            # (which is output implicitly as result)

これは、05AB1Eの1真理値としてのみ利用可能であり、他のすべては偽物として利用されます。最短の一意の部分文字列は、可能なすべての入力文字列に対して常に1回だけ発生することが保証されています。(同じ文字(つまりaaaaa)のみを含む入力文字列の場合、部分文字列としての入力文字列自体は1回だけ出現するため、結果は["aaaaa"]。繰り返しパターン(つまり"abcabc")の入力文字列の場合、 1回(["abca","abcab","abcabc","bca","bcab","bcabc","ca","cab","cabc"])発生するため、結果は["ca"]。)


0

Python 2、150

import re
a=input()
r=range
l=len(a)
d=0
for i in r(l):
 if d:break
 for j in r(l-i):
  k=a[j:i+j+1]
  if len(re.findall("(?="+k+")",a))<2:d=1;print k

灰色の領域、印刷する必要""がありますが、何も印刷しません。
ジャクベ

1
@ジャクベ「出力の正確なフォーマットは柔軟です」
-KSFT

しかし、出力はまったくありません。
ジャクベ

2
@Jakube出力は、本来のはずの空の文字列です。引用符がありません。
KSFT

1
@Jakube空の文字列はとにかく特殊なケースなので、これを許可します。
ズガルブ

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.