生成所有子列表分区


11

给定一个非空的整数列表,输出列表的每个可能分区,其中每个分区都是一个非空子列表。

因此,对于列表[1, 2, 3, 4],结果为:

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

列表在输出中的顺序无关紧要,因此[[1, 2, 3, 4]]可以是第一个,最后一个或任何位置。元素的顺序必须保留。

这是代码高尔夫球,所以最短的答案会获胜。


相关:对列表进行分区!


2
我们可以[...]在输出格式中省略周围吗?(只要分隔区清楚地分开,例如通过换行符。)
Martin Ender

输入和输出格式很灵活,但应该相似。因此,如果输入列表的一行中有其元素,则输出列表也应如此。
mbomb007 '17

我不是那个意思 看看Bash的答案。它:用作列表分隔符,但在输出中,分区本身不包装在另外一对中[...]
马丁·恩德

或者,以不同的方式问:以您挑战中的示例格式,我可以从每一行中删除第一行[和最后]一行吗?
马丁·恩德

Answers:



13

视网膜27 19字节

字节数假定为ISO 8859-1编码。

+1%`,
;$'¶$`];[
;
,

在线尝试!

说明

当然,这使用字符串处理来计算所有分区。基本思想是,我们可以通过分别确定,是否要在此处拆分列表来生成所有分区。在Retina中,可以通过,依次匹配每个对象并使用提供两种可能输出的替换方法来完成这种工作。

输入充当基本情况:所有元素仍在单个列表中的分区。

+1%`,
;$'¶$`];[

现在我们在每一行()上重复(+)匹配第一个(1)逗号(,%(将该行作为单独的字符串进行处理,这与$'和``$ 1` 有关'')有关。

该逗号被替换为:

;   A semicolon. This is just a stand-in for the comma, so we know we've already
    processed it and it won't be substituted again by the next iteration.
$'  Everything after the match. This completes the first (unchanged) version of
    the current line.
¶   A linefeed. Since the next iteration will scan for all lines again, this doubles
    the number of strings we're working with.
$`  Everything before the match. This completes the second (split) version of
    the current line.
];[ A semicolon around which we split the list.

请记住,匹配之前和匹配之后的所有内容仍然保留在字符串中,因此完整的结果实际上是$`;$'¶$`];[$'在解释为什么我们按该顺序插入后缀和前缀的原因。

一旦所有逗号都消失,此循环将停止。

;
,

最后,再次用逗号替换分号以匹配输入格式。


10

纯净重击,28岁

eval echo [${1//:/{:,]:[\}}]

在此,列表用冒号分隔,并包含在方括号中。例如在问题中,输入列表将为1:2:3:4,输出为:

[1:2:3:4] [1:2:3]:[4] [1:2]:[3:4] [1:2]:[3]:[4] [1]:[2:3:4] [1]:[2:3]:[4] [1]:[2]:[3:4] [1]:[2]:[3]:[4]

在线尝试

  • ${1//:/REPLACEMENT}代替了冒号$1{:,]:[\}
  • 这会产生支撑扩展,例如 [1{:,]:[}2{:,]:[}3{:,]:[}4]
  • 评估(和仔细的\转义)使撑杆膨胀最后发生,并得到所需的结果。

如果有必要完全匹配给定的[[ , , ...]]格式,那么我们可以这样做:

纯净重击,47岁

eval printf '%s\\n' ${1//, /{\\,\\ ,]\\,\\ [\}}

在线尝试


6

Pyth,2个字节

./

带输入[1, 2, 3, 4](例如)。

说明./是分区运算符。它将输入列表的所有划分返回不相交的子列表。输入被隐式馈送到程序。

在线测试!


6

05AB1E,5个字节

Œæʒ˜Q

在线尝试!

Œæʒ˜Q  Main link. Argument l
Π     Get all sublists of l
 æ     Powerset of those lists
  ʒ˜Q  Filter: Keep the lists that when flattened equal the input

1
哇,这是一个非常简洁的答案!
阿德南

1
@Adnan谢谢,我也对此感到满意。虽然一切都不过效率:)
kalsowerus

当还没有内置对象时,很好的答案,我+1!就要离开这个对任何人来到这里,在未来,但现在05AB1E拥有2个字节内置让所有分区:在线试玩。
凯文·克鲁伊森

4

Python 3中82个 72 66字节

f=lambda l:[k+[l[i:]]for i in range(len(l))for k in f(l[:i])]or[l]

在线尝试!

-5个字节,感谢@JonathanAllan


哦,我,我不能^ V再次:(其实我试过这样的事情并没有工作,我一定是出了问题的地方。
乔纳森·艾伦

1
...在这种情况下又损失了5个
Jonathan Allan

1
@JonathanAllan非常感谢!我可以通过重用保存另一个字节l到底
OVS

该解决方案已经存在这里。发布问题后,我在TNB中发了@feersum消息,这样他就有机会发布问题。
mbomb007 '17

我并不是说您应该撤消它,只是意味着您要击败他。当然,这是您的选择。
mbomb007 '17

4

Haskell59 55 49字节

p[x]=[[[x]]]
p(x:r)=do a:b<-p r;[(x:a):b,[x]:a:b]

在线尝试!

递归解决方案。用法示例:p [1,2,3]return [[[1,2,3]],[[1,2],[3]],[[1],[2,3]],[[1],[2],[3]]]

-6个字节感谢xnor


1
您可以使用do表示法将第二行写得更短:(do a:b<-p r;[(x:a):b,[x]:a:b]这会更改列表的顺序)。
xnor18年

1
此外,<*>它确实可以满足您的要求[\(a:b)->(x:a):b,([x]:)]<*>p r,尽管它的时间比do因为第一个lambda似乎需要模式匹配的时间还要长。
xnor18年

3

J,42个字节

<@(</."1)~<:@#_&(][:;<@(,~"{~0 1+>./)"1)0:

通过为长度为1的分区子列表创建键并迭代到输入列表的长度来生成所有子列表分区。然后通过从键中选择来形成每个分区子列表。

例如,这是为长度为4的列表创建密钥的过程。

例

在线尝试!



2

Brachylog,2个字节

~c

在线尝试!

通过作为生成器生成输出的函数提交。(TIO链接包含额外的代码,可以将其放入完整的程序中,以进行测试。)

顺便说一句,尽管从技术上讲不是内置函数,但在Brachylog中是如此常用,以至于a)它可能应该以单字节表示,并且b)c内置函数可以采用参数对其输入进行断言(而对于大多数内置函数,则为参数)谈论如何产生输出)。

说明

~c
~     Find a value with the following properties:
 c      concatenating its elements produces {the input}

2

APL,26个字节

{⊂∘⍵¨1,¨↓⍉(X⍴2)⊤⍳2*X←⍴1↓⍵}

测试:

      {⊂∘⍵¨1,¨↓⍉(X⍴2)⊤⍳2*X←⍴1↓⍵} 1 2 3 4
┌─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┐
│┌─────┬─┐│┌───┬───┐│┌───┬─┬─┐│┌─┬─────┐│┌─┬───┬─┐│┌─┬─┬───┐│┌─┬─┬─┬─┐│┌───────┐│
││1 2 3│4│││1 2│3 4│││1 2│3│4│││1│2 3 4│││1│2 3│4│││1│2│3 4│││1│2│3│4│││1 2 3 4││
│└─────┴─┘│└───┴───┘│└───┴─┴─┘│└─┴─────┘│└─┴───┴─┘│└─┴─┴───┘│└─┴─┴─┴─┘│└───────┘│
└─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┘

说明:

  • X←⍴1↓⍵X(输入列表)第一个元素删除的长度
  • ⍳2*X:数字[1..2 ^ X]
  • (X⍴2)⊤:这些数字的以2为基的表示形式,并带有X位置(即X本身将环绕到0)。
  • ↓⍉:旋转矩阵并沿线将其拆分(结果是矩阵,其列沿数字),给出位向量数组
  • 1,¨:在每个位向量前添加1。
  • ⊂∘⍵¨:对于每个位向量,在每个1处拆分。


1

Python,90个字节

被ovs打败了(做了一些我认为我已经尝试过的工作:p)

def f(a):r=[[a]];i=len(a)-1;exec("for s in f(a[:i]):s+=[a[i:]];r+=[s]\ni-=1\n"*i);return r

一个递归函数,该函数从输入的切片构建分区列表,当切片的长度为1时到达尾部。

在线尝试!

所述exec保存的4个字节通过while在或3 for环(下图),因为这意味着只有两个\n做得相当不是压痕两级,允许整个功能是在一行(而切片的顺序并不重要)。

def f(a):
 r=[[a]]
 for i in range(1,len(a)):
  for s in f(a[:i]):s+=[a[i:]];r+=[s]
 return r


1

Haskell,59个字节

x#[]=[[[x]]]
x#(a:b)=[(x:a):b,[x]:a:b]
foldr((=<<).(#))[[]]

1

红宝石62 57字节

->l{(0..2**l.size).map{|x|l.chunk{1&x/=2}.map &:last}|[]}

在线尝试!

这个怎么运作:

  • 分区的数量为2 ^(n-1):我迭代该范围内的二进制数,将零和一的组作为初始列表的子集进行映射。
  • 我没有摆弄范围,而是将其加倍,并在末尾丢弃重复项。现在,我还可以舍弃第一个二进制数字,并使块函数更短。

0

JavaScript(ES6),87个字节

([e,...a],b=[],c=[e],d=[...b,c])=>1/a[0]?[...f(a,b,[...c,a[0]]),...f(a,d,[a[0]])]:[d]

说明:b是以前的子列表的列表,c是当前的子列表(从数组的第一个元素开始,因为它必须在第一个子列表中),d而是所有子列表的列表。然后,递归处理其余的数组元素。在每种情况下,都有两个选项:将下一个元素追加到当前子列表中,或者将当前子列表完成,然后将下一个元素启动新的子列表。然后将递归结果连接在一起。当数组用尽时,所有子列表的列表就是结果。


0

APL(NARS)38个字符,76个字节

{k←↑⍴⍵⋄x←11 1‼k k⋄y←⍵⋄∪{x[⍵;]⊂y}¨⍳↑⍴x}

这使用了Nars函数11 1 butkk但非常慢,无法用于9个元素的arg数组...

  P3←{k←↑⍴⍵⋄x←11 1‼k k⋄y←⍵⋄∪{x[⍵;]⊂y}¨⍳↑⍴x}

  ⍴∘P3¨{1..⍵}¨⍳8
1  2  4  8  16  32  64  128 
  P3 'abcd'
abcd    abc d    ab cd    a bcd    ab c d    a bc d    a b cd    a b c d

以下是不使用内置函数的函数:

r←h w;k;i
   r←⊂,⊂w⋄k←↑⍴w⋄i←1⋄→B
A: r←r,(⊂⊂,i↑w),¨h i↓w⋄i+←1
B: →A×⍳i<k

  h 'abcd'
abcd    a bcd    a b cd    a b c d    a bc d    ab cd    ab c d    abc d
  ⍴∘h¨{1..⍵}¨⍳8
2  4  8  16  32  64  128 

我们将结果的类型分别为:

  o h ,1
┌──────┐
│┌1───┐│
││┌1─┐││
│││ 1│││
││└~─┘2│
│└∊───┘3
└∊─────┘
  o h 1 2
┌2───────────────────┐
│┌1─────┐ ┌2────────┐│
││┌2───┐│ │┌1─┐ ┌1─┐││
│││ 1 2││ ││ 1│ │ 2│││
││└~───┘2 │└~─┘ └~─┘2│
│└∊─────┘ └∊────────┘3
└∊───────────────────┘

我不知道它是如何工作的,只是试探性的尝试...

可能我出错了;这两个函数都将构建列表的分区,而不管输入是什么,而不仅仅是1 2 ... n。


0

公理,251字节

C==>concat;A==>List Any;px(a:A):A==(k:=#a;r:=copy[a];k<=1=>r;i:=1;repeat(i>=k=>break;x:=a.(1..i);y:=a.((i+1)..k);z:=px(y);t:=[x,z.1];for j in 2..#z repeat(w:=(z.j)::A;m:=#w;v:=[x];for q in 1..m repeat v:=C(v,w.q);t:=C(t,[v]));r:=C(r,copy t);i:=i+1);r)

如果有人发现更好的东西...测试并测试:

pp(a:List Any):List Any==
  k:=#a;r:=copy[a];k<=1=>r;i:=1
  repeat
    i>=k=>break
    x:=a.(1..i);y:=a.((i+1)..k);z:=pp(y);
    t:=[x,z.1]
    for j in 2..#z repeat
           w:=(z.j)::List Any
           m:=#w; v:=[x]
           for q in 1..m repeat 
                       v:=concat(v,w.q);
           t:=concat(t,[v])
    r:=concat(r,copy t);
    i:=i+1
  r

(7) -> px []
 (7)  [[]]
                                                           Type: List Any
(8) -> px [1]
 (8)  [[1]]
                                                           Type: List Any
(9) -> px [1,2]
 (9)  [[1,2],[[1],[2]]]
                                                           Type: List Any
(10) -> px [1,2,3]
 (10)  [[1,2,3],[[1],[2,3]],[[1],[2],[3]],[[1,2],[3]]]
                                                           Type: List Any
(11) -> px [1,2,3,4,5,6]
 (11)
[[1,2,3,4,5,6], [[1],[2,3,4,5,6]], [[1],[2],[3,4,5,6]],
 [[1],[2],[3],[4,5,6]], [[1],[2],[3],[4],[5,6]], [[1],[2],[3],[4],[5],[6]],
 [[1],[2],[3],[4,5],[6]], [[1],[2],[3,4],[5,6]], [[1],[2],[3,4],[5],[6]],
 [[1],[2],[3,4,5],[6]], [[1],[2,3],[4,5,6]], [[1],[2,3],[4],[5,6]],
 [[1],[2,3],[4],[5],[6]], [[1],[2,3],[4,5],[6]], [[1],[2,3,4],[5,6]],
 [[1],[2,3,4],[5],[6]], [[1],[2,3,4,5],[6]], [[1,2],[3,4,5,6]],
 [[1,2],[3],[4,5,6]], [[1,2],[3],[4],[5,6]], [[1,2],[3],[4],[5],[6]],
 [[1,2],[3],[4,5],[6]], [[1,2],[3,4],[5,6]], [[1,2],[3,4],[5],[6]],
 [[1,2],[3,4,5],[6]], [[1,2,3],[4,5,6]], [[1,2,3],[4],[5,6]],
 [[1,2,3],[4],[5],[6]], [[1,2,3],[4,5],[6]], [[1,2,3,4],[5,6]],
 [[1,2,3,4],[5],[6]], [[1,2,3,4,5],[6]]]
                                                           Type: List Any
(12) -> [[i,#px i] for i in [[],[1],[1,2],[1,2,3],[1,2,3,4],[1,2,3,4,5,6]] ]
 (12)
[[[],1],[[1],1],[[1,2],2],[[1,2,3],4],[[1,2,3,4],8],[[1,2,3,4,5,6],32]]
                                                      Type: List List Any
(13) -> [#px(i) for i in [[],[1],[1,2],[1,2,3],[1,2,3,4],[1,2,3,4,5,6]] ]
 (13)  [1,1,2,4,8,32]
                                            Type: List NonNegativeInteger

如果空间太大,请说出来,然后删除示例...

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.