Code-Golf: Permutations


21

Écrivez une fonction qui prend en entrée un ensemble d'entiers (peut être une liste, un tableau ou tout autre conteneur avec des nombres distincts), et génère la liste de toutes ses permutations.

Python (95 caractères) :

p=lambda s:s and sum(map(lambda e:map(lambda p:[e]+p,p(filter(lambda x:x!=e,s))),s),[]) or [[]]

Ce serait bien d'être battu dans la même langue, mais les implémentations dans d'autres langues sont plus que bienvenues!

Réponses:


10

Python - 76 caractères

Plus long que gnibbler, mais implémente les choses à partir de zéro.

p=lambda x:x and[[a]+b for a in x for b in p([c for c in x if c!=a])]or[[]]

J'aime l'utilisation des compréhensions ici. Cela simplifie vraiment le code que j'ai beaucoup posté!
zxul767


9

J, 11 caractères

(i.@!@#A.[)

Usage:

   (i.@!@#A.[) 1 3 5
1 3 5
1 5 3
3 1 5
3 5 1
5 1 3
5 3 1

Explication:

i.@!@# utilise trois verbes pour renvoyer une liste de 0 à (! n) -1 où n est le nombre d'éléments dans la liste donnée.

[renvoie la liste elle-même. Dans l'exemple illustré qui donne 0 1 2 3 4 5 A. 1 3 5.

A.renvoie une permutation possible de la deuxième liste pour chaque élément de la première liste (sorte de - l'explication appropriée est donnée ici ).


Fournir un lien vers des informations sur J?
Sparr

1
@Sparr Le site Web J contient quelques bons guides - Apprentissage des programmeurs J et J pour C - et une page couvrant le vocabulaire .
Gareth

8

Python - 55 caractères

from itertools import*
p=lambda x:list(permutations(x))

Pas exactement ce que j'espérais que les gens écriraient ... mais il est utile de savoir que Python a de tels utilitaires dans la bibliothèque standard.
zxul767

4
@ zxul767: Pourquoi réinventer la roue? L'utilisation de la bibliothèque standard s'avérera incroyablement efficace ... (et dans ce cas, rend le code concis lors du golf ;-)
ChristopheD

8

Haskell, 44 43

p[]=[[]]
p l=[e:r|e<-l,r<-p$filter(/=e)l]

Essentiellement la même que la solution d'Ugoren, mais Haskell est meilleur dans la compréhension des listes!


Bien sûr, cela peut aussi faire

30

import Data.List
p=permutations


Une approche plus efficace, qui ne nécessite pas de comparaison d'égalité:

92

import Data.List
p[]=[[]]
p l=(\(l,(e:r))->map(e:)$p(l++r))=<<(init$zip(inits l)(tails l))

Par conséquent, celui-ci fonctionne également lorsqu'il y a des éléments en double dans la liste.


4
La meilleure partie de cela est que la solution haskell de 44 lignes avec la compréhension de la liste est plus courte que la solution python qui utilise simplement la bibliothèque standard.
monadique

p=Data.List.permutations. Cela ressemble à de la triche, cependant. De plus, Data.List.permutationsne produit pas les permutations dans l'ordre lexicographique.
John Dvorak

1
Vous pouvez écrire p[]=[[]]comme cas de base à la place, en économisant deux octets.
Lynn

@Mauris: c'est vrai! J'ai en quelque sorte supposé que la liste vide aurait par définition zéro permutations, mais depuis 0! = 1 qui n'a clairement aucun sens. Avoir un cas de base vide est beaucoup plus agréable.
cessé de tourner dans le sens inverse des aiguilles d'une montre du

3

en Q (48)

g:{$[x=1;y;raze .z.s[x-1;y]{x,/:y except x}\:y]}

Exemple d'utilisation:

q)g[3;1 2 3]
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1

2

Rubis - 23 caractères

f=->x{p *x.permutation}

par exemple, f[[1,2,3]] émet ceci .

mais utiliser [].permutation, c'est comme tricher, donc:

Rubis - 59 caractères

f=->a{a.size<2?[a]:a.flat_map{|x|f[(a-x=[x])].map{|y|x+y}}}

testé avec

100.times.all?{arr=(1..99).to_a.sample(rand(5)); arr.permutation.to_a==f[arr]}
=> true

Si vous le souhaitez, vous pouvez faire la démonstration de votre code en utilisant un site comme IdeOne: ideone.com/crvtD
M. Llama

1
Pourquoi l'utilisation de fonctionnalités de langage intégrées serait-elle de la triche?
Mark Thomas

@Mark ne triche peut-être pas, mais n'est pas très amusant non plus, pour écrire une fonction qui appelle simplement une fonction intégrée. Comme par exemple: "écrire une fonction pour trier un tableau" ->f(array) { return array.sort(); }
jsvnm

2

Python - 58 caractères

Légèrement plus court que celui d'Ugoren, en prenant un ensemble en entrée:

p=lambda x:x and[[y]+l for y in x for l in p(x-{y})]or[[]]

2

C, 270 243 239 caractères

#define S t=*a;*a=a[i];a[i]=t;
#define R o=p(n,r-1,a+1,o,r-2,0)
int*p(n,r,a,o,i,t)int*a,*o;{if(!r)for(;n;--n)*o++=*--a;else{R;for(;i;--i){S R;S}}return o;}
P(n,a)int*a;{int N=1,i=n;for(;i;N*=i--);return p(n,n,a,malloc(N*n*8),n-1,0)-N*n;}

La fonction P (n, a) renvoie un pointeur sur le n! permutations d'un, emballés les uns après les autres dans un tableau géant.


1
Quelques conseils: <malloc.h> isn't needed (ignore the warnings). sizeof n` est 4 (la portabilité est agréable, mais plus courte est plus agréable). Utilisez des paramètres supplémentaires comme variables (par exemple p(n,a,N,i)). int*p(..)int*a,o;. L'utilisation de variables globales au lieu de paramètres et de valeurs de retour est souvent utile.
ugoren

@ugoren, merci pour les conseils. Jusqu'à présent, je n'ai pas vu comment raser d'autres personnages en utilisant des globaux. (Et bon, la fonction est thread-safe comme ça!)
Michael Radford


1

JS - 154 146 caractères

function f(x){var a=[],m;(m=x.length)>1?f(x.slice(1)).map(function(y){for(l=m;l--;a.push(y.slice(0,l).concat(x[0],y.slice(l))));}):a=[x];return a}

Test: f([1,2,3,4,5]).map(function(a){return a.join('')}).join('\n')renvoie ceci .


1

R

Puisque nous parlons de permutations, permettez-moi de montrer au moins une solution dans R:

library(gtools);v=c(3,4,5);permutations(length(v),length(v),v)

1

Perl 188

Pas de routines de bibliothèque, pas de récursivité

sub p{$l=(@_=sort split'',shift)-1;while(print@_){$k=$j=$l;--$k while($_[$k-1]cmp$_[$k])>=0;$k||last;--$j while($_[$k-1]cmp$_[$j])>=0;@_[$j,$k-1]=@_[$k-1,$j];@_[$k..$l]=reverse@_[$k..$l]}}

1

Scala 30:

def p(s:Seq[_])=s.permutations 

Scala 195, quick'n'dirty, sans permutations de la bibliothèque:

def c(x:Int,t:List[_]):List[_]={val l=t.size
val o=x%l
if(l>1){val r=c(x/l,t.tail)
r.take(o):::(t.head::r.drop(o))}else
t}
def p(y:List[_])=(0 to(1 to y.size).product).foreach(z=>println(c(z,y)))

val y=List(0,1,2,3)
p(y)

Scala 293, itérateur sûr de type adulte:

class P[A](val l:Seq[A])extends Iterator[Seq[A]]{
var c=0
val s=(1 to l.size).product
def g(c:Int,t:List[A]):List[A]={
val n=t.size
val o=c%n
if(n>1){val r=g(c/n,t.tail)
r.take(o):::(t.head::r.drop(o))
}else
t}
def hasNext=c!=s
def next={c+=1
g(c-1,l.toList)}
}
for(e<-new P("golf"))println(e)


1

Pyth, 4 octets

L.pb

Oui, Pyth a été créé après la publication de ce défi et tout. C'est encore vraiment cool. :RÉ

Démo en direct.

La lecture depuis stdin est un octet plus court:

.pQ

1

Javascript 143 136 134 123

function p(s,a="",c="",i,z=[]){a+=c,i=s.length
!i?z.push(a):0
for(;i--;s.splice(i,0,c))p(s,a,c=s.splice(i,1),0,z);return z}

var perms = p([1,2,3]);

document.getElementById('output').innerHTML = perms.join("\n");
<pre id="output"></pre>


Je pense que vous pourriez gagner 8 octets en faisant: js function p(s,a="",c="",i,z=[]){ au lieu de js function p(s,a,c,i,z){if(!z)a=c="",z=[]
ColdK

Merci ColdK. Cela a fonctionné et est maintenant 8 octets plus court.
Wolfhammer


0

Python, 53 octets

from itertools import*;lambda x:list(permutations(x))

1
Il s'agit essentiellement d'un doublon d' une autre réponse soumise . Je suppose que vous l'avez trouvé indépendamment (et vous l'avez mieux joué au golf), mais j'ai pensé qu'il valait la peine de signaler le doublon.


0

K (oK) , 3 octets

Solution

prm

Essayez-le en ligne!

Explication:

Il s'agit d'un raccourci intégré de 3 octets vers la fonction intégrée de 47 octets suivante:

{[x]{[x]$[x;,/x ,''o'x ^/:x;,x]}@$[-8>@x;!x;x]}

... qui peut être raccourci à 23 octets si nous savons que nous obtenons une liste d'entiers en entrée:

{$[x;,/x,''o'x^/:x;,x]} / golfed built in
{                     } / lambda function with implicit input x
 $[ ;             ;  ]  / if[condition;true;false]
   x                    / if x is not null...
             x^/:x      / x except (^) each-right (/:) x; create length-x combinations
           o'           / call self (o) with each of these
       x,''             / x concatenated with each-each of these results (this is kinda magic to me)
     ,/                 / flatten list
                    ,x  / otherwise enlist x (enlisted empty list)

0

Axiome, 160 octets

p(a)==(#a=0=>[[]];r:=[[a.1]];r:=delete(r,1);n:=#a;m:=factorial n;m>1.E7=>r;b:=permutations n;for j in 1..m repeat(x:=b.j;r:=concat([a.(x.i)for i in 1..n],r));r)

non golfé

--Permutation of a
pmt(a)==
     #a=0=>[[]]
     r:=[[a.1]]; r:=delete(r,1) -- r has the type List List typeof(a)
     n:=#a
     m:=factorial n
     m>1.E7=>r
     b:=permutations(n)         --one built in for permutation indices 
     for j in 1..m repeat
        x:=b.j
        r:=concat([a.(x.i) for i in 1..n],r)
     r

Tout cela appelle une fonction de bibliothèque qui donne une permutation sur l'index (uniquement des entiers comme permutation comme permutations sur [1], permutations sur [1,2], permutations sur [1,2,3] etc.). des indices et construire les listes; Il faut noter que cela semble être bien compilé pour chaque liste de type X

(4) -> p([1,2,3])
   Compiling function p with type List PositiveInteger -> List List
      PositiveInteger
   (4)  [[1,2,3],[1,3,2],[3,1,2],[2,1,3],[2,3,1],[3,2,1]]
                                          Type: List List PositiveInteger
(5) -> p([x^2,y*x,y^2])
   Compiling function p with type List Polynomial Integer -> List List
      Polynomial Integer
   (5)
      2      2    2  2        2  2            2  2        2  2    2      2
   [[x ,x y,y ],[x ,y ,x y],[y ,x ,x y],[x y,x ,y ],[x y,y ,x ],[y ,x y,x ]]
                                       Type: List List Polynomial Integer
(6) -> p([sin(x),log(y)])
   Compiling function p with type List Expression Integer -> List List
      Expression Integer
   (6)  [[sin(x),log(y)],[log(y),sin(x)]]
                                       Type: List List Expression Integer
(7) -> m:=p("abc")::List List Character
   Compiling function p with type String -> Any
   (7)  [[a,b,c],[a,c,b],[c,a,b],[b,a,c],[b,c,a],[c,b,a]]
                                                Type: List List Character
(8) -> [concat(map(x+->x::String, m.j))  for j in 1..#m]
   (8)  ["abc","acb","cab","bac","bca","cba"]
                                                        Type: List String

Avez-vous un lien vers l'interprète Axiom? J'adorerais l'ajouter à Try It Online! , cela ressemble à une langue intéressante.
caird coinheringaahing

0

Japt , 1 octet

á

Interprète Japt

Cela a été heurté et n'a pas eu de réponse Japt, alors j'ai pensé que j'irais de l'avant et j'en ajouterais une. álorsqu'il est appliqué à un tableau et sans aucun argument, c'est la fonction intégrée pour "obtenir toutes les permutations". L' -Rindicateur utilisé dans le lien interprète modifie uniquement la façon dont le résultat est imprimé.


0

APL (NARS), 39 caractères, 78 octets

{1≥k←≢w←,⍵:⊂w⋄↑,/{w[⍵],¨q w[a∼⍵]}¨a←⍳k}

tester:

  q←{1≥k←≢w←,⍵:⊂w⋄↑,/{w[⍵],¨q w[a∼⍵]}¨a←⍳k}
  q 1 2 3
1 2 3  1 3 2  2 1 3  2 3 1  3 1 2  3 2 1 
  q 'abcd'
abcd abdc acbd acdb adbc adcb bacd badc bcad bcda bdac bdca cabd cadb cbad cbda cdab cdba dabc dacb dbac dbca dcab dcba 

0

05AB1E - 2 1 octet s

œ

L'entrée doit être un tableau / liste.

Explication:

œ //Takes all the permutations of the elements in the top of the stack (the input is a list, so it would work)

Un octet enregistré grâce à Erik l'Outgolfer


Vous pouvez prendre la saisie comme une seule liste, pas besoin de la séparer par des retours à la ligne.
Erik the Outgolfer

Je vous remercie! Je peux maintenant raccourcir cela à un octet!
MilkyWay90
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.