查找最短的唯一子列表


14

给定一个列表列表,找到最短列表,它是一个列表的连续子列表。

例如,如果我们有

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

最短的连续子列表将是[3,4]因为它仅出现在第二个列表中。

如果没有唯一的连续子列表(这需要至少一个重复的条目),则输出一个空列表。这是一个例子

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

如果有多个最小大小的连续子列表,则可以输出其中任何一个或包含所有子列表的列表。例如,如果输入是

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

你可以输出两种[1,2][2,3][[1,2],[2,3]]。如果选择执行后一种选项,则可能在只有一个解决方案的情况下输出单例列表。

只要在其他列表中没有出现,输出就可能在同一列表中出现多次。例如

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

应该输出,[1,2]因为它[1,2]是第一个列表的子列表,但不是第二个列表的子列表,即使它是以两种不同的方式是第一个列表的子列表。

您可以将包含任何类型的列表的列表作为输入,只要该类型具有100个以上的可能值即可,即没有布尔值。

这是因此答案将以字节计分,而字节数越少越好。

测试用例

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

Answers:


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使用上面的方法很难解释。


带lambda的14个字节
Zgarb

失败[[1,1]]
H.PWiz

嗯,并进行修复,使其超过15个字节。那好吧。
Zgarb

4

Pyth,15个字节

halDs-M.p.:R)QY

测试套件

首先,我们使用生成每个输入列表的所有子字符串.:R)Q。然后,我们生成这些子字符串组的所有可能的排序.p

现在,棘手的部分是:-M。这会将-功能折叠到每个订购列表上。它从第一个子字符串列表开始,然后过滤掉所有其他列表的所有占用者。

然后,将结果连接起来,按长度排序,添加a [],然后用提取结果列表的第一个元素h

如果我可以在没有唯一子列表的情况下出错而不是输出一个空列表,那么它将少4个字节。


您的11字节版本是什么?
Leaky Nun

@LeakyNun hlDs-M.p.:R可能就是他的意思。
FryAmTheEggman


2

Haskell中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,节省了两个字节。

感谢nimi,节省了13个字节。

编辑这是原始的解释:

  • a 是加入列表的快捷方式。

  • s计算所有连续子列表(全部tails来自inits)。请注意,nub仅保留每个元素的第一次出现,因此tail将从子列表中删除空列表。

  • g 将所有给定列表中的所有子列表合并到一个较大的子列表中,并按长度对其进行排序。

  • f f是对仅在大列表中出现一次的元素的过滤器

  • h 是的安全版本 head

  • i 是胶水

相当优雅!应该有更好的解决方案...


2
如果将这些函数编写为无点函数,则看起来可能会短一些。
发布Rock Garf Hunter,

1
您也不必i=在程序末尾计数,因为不需要根据我们的规则分配无点功能。
发布Rock Garf Hunter,

2
foldl1(++)concat
H.PWiz

2
(length$filter(==x)l)可能更短,length(filter(==x)l)甚至更短sum[1|y<-l,y==x]
Rock Rock Garf Hunter发布

2
@ H.PWiz除外[],但>>=id更短;)@jferard:因为仅使用一次fg所以您可以内联许多功能(例如,等)。
ბიმო

2

Java 8,251 + 19 = 270字节

一个非常总值拉姆达从,微创,List<List>List(最好丢给Function<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个字节,感谢Jonathan Allan


可以ċ1代替S吗?

@ThePirateBay的确可以,谢谢。我做了一个不同的版本。(尽管它将带到相同的字节数)
HyperNeutrino

新的解决方案打印[1, 2, 1]输入[[1,2],[1,2,1],[2,1,1]][1,1]较短。

@ThePirateBay固定,谢谢。
HyperNeutrino

1
@JonathanAllan哦,嗯。我无法数天。:P
HyperNeutrino


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.