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!

zxul767
la source

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[[]]
ugoren
la source
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 ).

Gareth
la source
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))
grignoteur
la source
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.

a cessé de tourner dans le sens antihoraire
la source
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
sinedcm
la source
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
jsvnm
la source
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[[]]
Jules Olléon
la source
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.

Michael Radford
la source
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
2

K, 30 octets

{x@v@&((#x;1)~^=:)'v:!(#x)##x}

Pas de builtins!

kirbyfan64sos
la source
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 .

JiminP
la source
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)
Paolo
la source
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]}}
ardnew
la source
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)
Utilisateur inconnu
la source
1

Python - 50 caractères

import itertools
list(itertools.permutations("123"))
Jared Burrows
la source
Pourquoi cela serait-il rétrogradé 5 ans plus tard?
Jared Burrows
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
kirbyfan64sos
la source
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>

marteau-de-loup
la source
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))
Oliver Ni
la source
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)
streetster
la source
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
RosLuP
la source
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é.

Kamil Drakari
la source
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 
RosLuP
la source
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

MilkyWay90
la source
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