最短の一意のサブリストを見つける


14

リストのリストが与えられた場合、正確に1つのリストの連続したサブリストである最短リストを見つけます。

例えば

[[1,2,3],
 [1,2,3,4],
 [2,4,5,6],
 [1,2,4,5,6]]

最短の連続サブリストは[3,4]、2番目のリストにのみ表示されるためです。

一意の連続したサブリストがない場合(これには少なくとも1つの重複エントリが必要です)、空のリストを出力します。ここに例があります

[[1,2,3],
 [1,2,3],
 [1,2]]

最小サイズの連続したサブリストが複数ある場合、それらのいずれかまたはすべてを含むリストを出力できます。たとえば、入力が

[[1,2,3],[2],[1],[3]]

あなたは、出力のいずれかの可能性[1,2][2,3]または[[1,2],[2,3]]。後者のオプションを選択した場合、ソリューションが1つしかない場合にシングルトンリストを出力できます。

出力は、他のリストに表示されない限り、同じリストで複数回発生する場合があります。例えば

[[1,2,1,2],[2,1]]

は、2つの異なる方法で最初のリストのサブリストであるにもかかわらず、最初のリストのサブリストであり、2番目のリストではない[1,2]ため[1,2]、出力する必要があります。

入力には、そのタイプが100を超える値、つまりブール値を持たない限り、任意のタイプを含むリストのリストを使用できます。

これはので、回答はバイト単位でスコアリングされ、バイト数は少ない方が良いでしょう。

テストケース

[[1,1]] : [1]
[[1],[1]] : []
[[1,1],[1]] : [1,1]

回答:


5

12 14 15バイト

ケース用に+3バイト [[1,1]]

Ṡḟȯ¬€Ṡ-uÖLṁȯtuQ

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

説明

          ṁ      -- map and concatenate
           ȯt    --   all but the first
             u   --   unique elements of
              Q  --   contiguous sublist
        ÖL       -- sort by length
Ṡḟ               -- find the first element satisfying this predicate
  ȯ¬€            --   not an element of
     Ṡ-          --   the list of sublists minus
       u         --   its unique elements

注:Ṡ f g x = f (g x) x上記の方法を使用して説明するのは困難です。


ラムダ付きの14バイト
-Zgarb

それは失敗のために[[1,1]]
H.PWiz

うーん、それを修正すると15バイト以上になります。しかたがない。
-Zgarb

4

Pyth、15バイト

halDs-M.p.:R)QY

テストスイート

まず、各入力リストのすべての部分文字列を生成し.:R)Qます。次に、これらの部分文字列グループのすべての可能な順序を生成します.p

今トリッキーな部分のために:-M。これにより、-各順序リストで関数が折り畳まれます。最初の部分文字列リストから開始し、他のすべてのリストのすべての占有者を除外します。

次に、結果が連結され、長さの順に並べられ、a []が追加されてから、結果リストの最初の要素がで抽出されhます。

空のリストを出力するのではなく、一意のサブリストがないとエラーが発生した場合、これは4バイト短くなります。


11バイトバージョンは何ですか?
リーキー修道女

@LeakyNun hlDs-M.p.:Rはおそらく彼が意味するものです。
FryAmTheEggman


2

ハスケル149の 128 126 113バイト

import Data.List
f l=[x|x<-l,sum[1|y<-l,y==x]<2]
h[]=[]
h(x:y)=x
i=h.f.sortOn length.(>>=tail.nub.(>>=tails).inits)

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

Wheat Wizard、H.PWiz、およびBruce Forteのおかげで21バイト節約されました。

H.PWizのおかげでさらに2バイト節約できました。

nimiのおかげで13バイト節約されました。

編集これは元の説明でした:

  • a リストに参加するためのショートカットです。

  • sすべての連続サブリスト(すべてtailsからすべてinits)を計算します。nub各要素の最初の出現のみを保持tailするため、サブリストから空のリストが削除されることに注意してください。

  • g サブリストの大きなリスト内のすべての指定リストからすべてのサブリストをマージし、長さでソートします。

  • f fは、大きなリストに1回だけ現れる要素のフィルターです

  • h の安全なバージョンです head

  • i のりです

かなり上品です!より良い解決策があるはずです...


2
ポイントフリー関数として記述されている場合、いくつかの関数が短くなる可能性があります。
ポストロックガーフハンター

1
またi=、ルールに従ってポイントフリー機能を割り当てる必要がないため、プログラムの最後でカウントする必要はありません。
ポストロックガーフハンター

2
あるfoldl1(++)だけconcat
H.PWiz

2
(length$filter(==x)l)短くすることができますlength(filter(==x)l)ように、あるいは短いsum[1|y<-l,y==x]
ポストロックGARFハンター

2
@ H.PWizは例外です[]が、>>=idさらに短くなります;)また、@ jferard:一度しか使用しないため、多くの関数(たとえばfgなど)をインライン化できます。
ბიმო

2

Java 8、251 + 19 = 270バイト

最小限のList<List>to からの非常にグロスなラムダListFunction<List<List<Integer>>, List<Integer>>ただしキャストするのが最善)。これは、1から最大リストのサイズまでチャンクの長さを反復するブルートフォースソリューションです。いずれの場合も、すべてのリストでその長さのすべてのチャンクを反復処理し、他のすべてのリストで同じサイズの各チャンクに対してそのようなチャンクをチェックします。

怖い、ガベージコレクター。

import java.util.*;

i->{int x,l=x=0,s,t;for(List z:i)x=Math.max(x,z.size());List r=i;while(l++<=x)for(List a:i)c:for(s=0;s<=a.size()-l;s++){for(List b:i)for(t=0;t<=b.size()-l;)if(b.subList(t,l+t++).equals(r=a.subList(s,s+l))&a!=b)continue c;return r;}return new Stack();}

ゴルフされていないラムダ

i -> {
    int
        x,
        l = x = 0,
        s, t
    ;
    for (List z : i)
        x = Math.max(x, z.size());
    List r = i;
    while (l++ <= x)
        for (List a : i)
            c: for (s = 0; s <= a.size() - l; s++) {
                for (List b : i)
                    for (t = 0; t <= b.size() - l; )
                        if (b.subList(t, l + t++).equals(r = a.subList(s, s + l)) & a != b)
                            continue c;
                return r;
            }
    return new Stack();
}

オンラインで試す

Java 8、289 + 45 = 334バイト

これは、ストリームを使用したより機能的なアプローチです。Stream一度出現する要素のみに減らす方法があれば、この解決策は上記の解決策を打ち負かしたでしょう。上記と同じタイプに割り当てます。

import java.util.*;import java.util.stream.*;

l->{List<List>o=l.stream().flatMap(a->IntStream.range(1,a.size()+1).boxed().flatMap(n->IntStream.range(0,a.size()-n+1).mapToObj(k->a.subList(k,k+n)))).collect(Collectors.toList());o.sort((a,b)->a.size()-b.size());for(List a:o)if(o.indexOf(a)==o.lastIndexOf(a))return a;return new Stack();}

ゴルフされていないラムダ

l -> {
    List<List> o = l.stream()
        .flatMap(a -> IntStream.range(1, a.size() + 1)
            .boxed()
            .flatMap(n -> IntStream.range(0, a.size() - n + 1)
                .mapToObj(k -> a.subList(k, k + n))
            )
        )
        .collect(Collectors.toList())
    ;
    o.sort((a, b) -> a.size() - b.size());
    for (List a : o)
        if (o.indexOf(a) == o.lastIndexOf(a))
            return a;
    return new Stack();
}

オンラインで試す


1

ゼリー、15バイト

Ẇ€Q€ẎɓċỊµÐf⁸LÐṂ

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

ジョナサン・アランのおかげで-3バイト


ċ1に置き換えることができますSか?

@ThePirateBay本当にありがとうございます。ただし、別のバージョンを作成しました。(ただし、同じバイト数になります)
-HyperNeutrino

あなたの新しいソリューションを印刷し[1, 2, 1]、入力のために[[1,2],[1,2,1],[2,1,1]]しながら、[1,1]短いです。

@ThePirateBay修正、ありがとう。
ハイパーニュートリノ

1
@JonathanAllanああ フープを数えられません。:P
ハイパーニュートリノ


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