Générer toutes les partitions sous-liste


11

Étant donné une liste d'entiers non vide, affichez chaque partitionnement possible de la liste où chaque partition est une sous-liste non vide.

Donc, pour la liste, [1, 2, 3, 4]le résultat est:

[[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]]

L'ordre des listes dans la sortie n'a pas d'importance, il [[1, 2, 3, 4]]peut donc être le premier, le dernier ou n'importe où. L'ordre des éléments doit être préservé.

C'est le code-golf, donc la réponse la plus courte l'emporte.


Connexes: partitionnez une liste!


2
Pouvons-nous omettre l'environnement [...]dans le format de sortie? (Tant que les partitions sont clairement séparées, par exemple par des sauts de ligne.)
Martin Ender

Les formats d'entrée et de sortie sont flexibles, mais ils devraient être similaires. Donc, si la liste d'entrée a ses éléments sur une seule ligne, les listes de sortie devraient également l'être.
mbomb007

Ce n'est pas ce que je veux dire. Jetez un œil à la réponse Bash. Il utilise :comme séparateur de liste mais dans la sortie, les partitions elles-mêmes ne sont pas enveloppées dans une paire supplémentaire de [...].
Martin Ender

Ou, demandé différemment: dans votre exemple de format dans le défi, puis-je supprimer le premier [et le dernier ]de chaque ligne?
Martin Ender

Réponses:



13

Rétine , 27 19 octets

Le nombre d'octets suppose un codage ISO 8859-1.

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

Essayez-le en ligne!

Explication

Bien sûr, cela calcule toutes les partitions à l'aide du traitement de chaîne. L'idée de base est que nous pouvons générer toutes les partitions en décidant pour chacune ,individuellement si nous voulons ou non y diviser la liste. Ce genre de choses peut être fait dans Retina en faisant correspondre chacune ,à son tour et en utilisant un remplacement qui donne les deux sorties possibles.

L'entrée agit comme le cas de base: la partition où tous les éléments sont toujours dans une seule liste.

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

Maintenant, nous faisons correspondre à plusieurs reprises ( +) la première 1virgule ( ,), sur chaque ligne ( %) (en traitant cette ligne comme une chaîne distincte, qui est pertinente pour $'et `` $ 1 `dans la substitution).

Cette virgule est remplacée par:

;   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.

N'oubliez pas que tout ce qui se trouve devant le match et après le match reste de toute façon dans la chaîne, donc le résultat complet est en fait $`;$'¶$`];[$'ce qui explique pourquoi nous insérons le suffixe et le préfixe dans cet ordre.

Cette boucle s'arrête une fois que toutes les virgules ont disparu.

;
,

Enfin, remplacez à nouveau les points-virgules par des virgules pour correspondre au format d'entrée.


10

Pure Bash, 28

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

Ici, les listes sont séparées par deux-points et contenues entre crochets. Par exemple, dans la question, la liste d'entrée serait 1:2:3:4et la sortie est:

[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]

Essayez-le en ligne .

  • ${1//:/REPLACEMENT} remplace les deux points dans $1 par{:,]:[\}
  • Cela génère une expansion d'accolade comme [1{:,]:[}2{:,]:[}3{:,]:[}4]
  • L'eval (et les \échappements prudents ) provoquent l'expansion de l'accolade en dernier et donnent le résultat souhaité.

S'il est nécessaire de faire correspondre exactement la donnée [[ , , ...]] format , nous pouvons le faire à la place:

Pure Bash, 47

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

Essayez-le en ligne .


6

Pyth , 2 octets

./

Avec entrée [1, 2, 3, 4](par exemple).

Explication : ./est l'opérateur de partition. Il renvoie toutes les divisions de la liste d'entrée en sous-listes disjointes. L'entrée est implicitement envoyée au programme.

Testez-le en ligne!


6

05AB1E , 5 octets

Œæʒ˜Q

Essayez-le en ligne!

Œæʒ˜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
Wow, c'est une réponse très soignée!
Adnan

1
@Adnan merci, j'en suis aussi très content. Bien qu'il soit tout sauf efficace :)
kalsowerus

Belle réponse quand il n'y avait pas encore de fonction intégrée, +1 de ma part! Laissant cela à quiconque viendra ici à l'avenir, mais 05AB1E a maintenant un intégré de 2 octets pour obtenir toutes les partitions :: Essayez-le en ligne.
Kevin Cruijssen

4

Python 3 , 82 72 66 octets

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

Essayez-le en ligne!

-5 octets grâce à @JonathanAllan


Oh mon Dieu, je ne peux plus ^ v :( J'ai en fait essayé quelque chose comme ça et ça n'a pas fonctionné, j'ai dû me tromper quelque part.
Jonathan Allan

1
... auquel cas lop off 5 more
Jonathan Allan

1
@JonathanAllan merci beaucoup! Je pourrais économiser un autre octet en réutilisant lfinalement
ovs

Cette solution existe déjà ici . J'ai envoyé un message à @feersum dans TNB après avoir posté la question, afin qu'il ait la possibilité de la poster.
mbomb007

Je ne voulais pas dire que vous devriez le défaire, je voulais juste dire que vous l'avez battu. C'est votre choix, bien sûr.
mbomb007

4

Haskell , 59 55 49 octets

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

Essayez-le en ligne!

Solution récursive. Exemple d'utilisation: p [1,2,3]retours [[[1,2,3]],[[1,2],[3]],[[1],[2,3]],[[1],[2],[3]]].

-6 octets grâce à xnor !


1
Vous pouvez écrire la deuxième ligne plus courte avec la notation do: do a:b<-p r;[(x:a):b,[x]:a:b](cela change l'ordre des listes).
xnor

1
En outre, <*>fait exactement ce que vous voulez [\(a:b)->(x:a):b,([x]:)]<*>p r, bien qu'il soit plus long que doparce que le premier lambda semble avoir besoin d'une correspondance de modèle.
xnor

3

J , 42 octets

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

Génère toutes les partitions de sous-liste en créant les clés des sous-listes de partition de longueur 1 et en itérant sur la longueur de la liste d'entrée. Chaque sous-liste de partition est ensuite formée en sélectionnant parmi les clés.

Par exemple, voici le processus de création des clés pour une liste de longueur 4.

Exemple

Essayez-le en ligne!



2

Brachylog , 2 octets

~c

Essayez-le en ligne!

Soumission de fonction qui produit une sortie en agissant comme un générateur. (Le lien TIO contient du code supplémentaire pour en faire un programme complet, à des fins de test.)

Soit dit en passant, bien qu'il ne s'agisse pas techniquement d'une fonction intégrée, elle est si couramment utilisée dans Brachylog que a) elle mérite probablement une représentation sur un octet, et b) la fonction cintégrée peut prendre un paramètre pour faire des affirmations sur son entrée (alors qu'avec la plupart des fonctions intégrées, un paramètre parle de la façon de produire la sortie ).

Explication

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

2

APL, 26 octets

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

Tester:

      {⊂∘⍵¨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││
│└─────┴─┘│└───┴───┘│└───┴─┴─┘│└─┴─────┘│└─┴───┴─┘│└─┴─┴───┘│└─┴─┴─┴─┘│└───────┘│
└─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┘

Explication:

  • X←⍴1↓⍵: Xest la longueur de (la liste d'entrée) avec son premier élément supprimé
  • ⍳2*X: les nombres [1..2 ^ X]
  • (X⍴2)⊤: représentation en base 2 de ces nombres, avec des Xpositions (c'est X-à- dire que lui - même s'enroulera autour de 0).
  • ↓⍉: faire pivoter la matrice et la diviser le long des lignes ( donne comme résultat une matrice avec les nombres le long des colonnes), donnant un tableau de vecteurs de bits
  • 1,¨: ajoute un 1 à chaque vecteur de bits.
  • ⊂∘⍵¨: pour chaque vecteur de bits, divisé à chaque 1.


1

Python , 90 octets

déjoué par les ovules (faisant quelque chose que je pensais avoir essayé de travailler: 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

Une fonction récursive qui construit la liste des partitions à partir des tranches de l'entrée avec la queue atteinte lorsque les tranches sont de longueur 1.

Essayez-le en ligne!

Le execsauvegarde 4 octets sur une whileou 3 sur une forboucle (ci-dessous) car cela signifie seulement deux \ns plutôt que deux niveaux d'indentation, permettant à la fonction entière d'être sur une seule ligne (alors que l'ordre de découpage n'a pas d'importance).

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 octets

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

1

Rubis , 62 57 octets

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

Essayez-le en ligne!

Comment ça fonctionne:

  • Le nombre de partitions est 2 ^ (n-1): j'itère sur les nombres binaires dans cette plage, je prends les groupes de zéros et de uns et les mappe comme sous-ensembles de la liste initiale.
  • Au lieu de jouer avec la plage, je la double et jette les doublons à la fin. Maintenant, je peux également supprimer le premier chiffre binaire et raccourcir la fonction de segment.

0

JavaScript (ES6), 87 octets

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

Explication: best la liste des sous-listes précédentes, cest la sous-liste actuelle, (qui commence comme le premier élément du tableau, car cela doit être dans la première sous-liste) tandis que dest la liste de toutes les sous-listes. Les autres éléments du tableau sont ensuite traités de manière récursive. Dans chaque cas, il existe deux options: soit l'élément suivant est ajouté à la sous-liste actuelle, soit la sous-liste actuelle est terminée et l'élément suivant commence une nouvelle sous-liste. Les résultats récursifs sont ensuite concaténés ensemble. Lorsque le tableau est épuisé, la liste de liste de toutes les sous-listes est le résultat.


0

APL (NARS) 38 caractères, 76 octets

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

ceci utilise la fonction Nars 11 1‼ kk mais est très lent, inutilisable pour le tableau arg de 9 éléments déjà ...

  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

ci-dessous est la fonction qui n'utilise pas le intégré:

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 

on voit le type de chaque résultat:

  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
└∊───────────────────┘

Je ne sais pas comment ça marche, ce n'est qu'un essai heuristique ...

Possible, je fais une erreur; les deux fonctions construisent les partitions de la liste quelle que soit l'entrée et pas seulement 1 2 ... n.


0

Axiome, 251 octets

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)

Si quelqu'un trouve quelque chose de mieux ... ungof et test:

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

Si c'est trop d'espace dis ça et j'enlève des exemples ...

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.