Code-Golf: Permütasyonlar


21

Girdi olarak bir tamsayı kümesi alan (bir liste, dizi veya farklı numaralara sahip başka bir kapsayıcı olabilir) bir işlev yazın ve tüm permütasyonlarının listesini çıktılar.

Python (95 karakter) :

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

Aynı dilde dövülmek güzel olurdu, ancak diğer dillerdeki uygulamalar memnuniyetle karşılanacaktır!

Yanıtlar:


10

Python - 76 karakter

Gnibbler'den daha uzun, ama her şeyi sıfırdan uygular.

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

Burada kavrayışların kullanımını seviyorum. Gerçekten çok gönderdiğim kodu basitleştirir!
zxul767


9

J, 11 karakter

(i.@!@#A.[)

Kullanımı:

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

Açıklama:

i.@!@# bir listeyi 0 ile (! n) -1 arasında döndürmek için üç fiil kullanır; burada n, verilen listedeki öğe sayısıdır.

[listenin kendisini döndürür. Gösterilen örnekte veriyor 0 1 2 3 4 5 A. 1 3 5.

A.ilk listedeki her bir öğe için ikinci listenin olası bir permütasyonunu döndürür (tür - uygun açıklama burada verilmiştir ).


J hakkında bilgi için bir bağlantı sağlayın?
Sparr


8

Python - 55 karakter

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

İnsanların yazmasını umduğum tam olarak değil ... ama Python'un standart kütüphanede bu tür yardımcı programlara sahip olduğunu bilmek yararlıdır.
zxul767

4
@ zxul767: Tekerleği neden yeniden icat ettiniz? Standart kütüphane kullanma ... inanılmaz verimli kanıtlamak (ve bu durumda özlü kodu yapar ne zaman golf ;-)
ChristopheD

8

Haskell, 44 43

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

Aslında ugoren'in çözümü ile aynıdır, ancak Haskell liste kavrayışlarında daha iyidir!


Tabii ki de yapabilir

30

import Data.List
p=permutations


Eşitlik karşılaştırması gerektirmeyen daha verimli yaklaşım:

92

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

Sonuç olarak, bu listede de yinelenen öğeler olduğunda işe yarar.


4
Bunun en iyi yanı, liste kavrama sahip 44 satır haskell çözümünün sadece standart kütüphaneyi kullanan python çözümünden daha kısa olmasıdır.
monadic

p=Data.List.permutations. Yine de hile gibi geliyor. Ayrıca Data.List.permutationspermütasyonları sözlükbilimsel sırayla çıkarmaz.
John Dvorak

1
Bunun p[]=[[]]yerine, iki bayt kaydederek temel durum olarak yazabilirsiniz .
Lynn

@Mauris: doğru! Bir şekilde boş listenin tanım gereği sıfır permütasyona sahip olacağını varsaydım, ancak 0'dan beri! = 1 bu hiç mantıklı değil. Boş bir taban kasasına sahip olmak çok daha hoş.
saat yönünün tersine çevirmek için

3

Q olarak (48)

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

Örnek kullanım:

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

Ruby - 23 karakter

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

örneğin bunu f[[1,2,3]] çıktılar .

ama kullanmak [].permutationhile gibi geliyor, bu yüzden:

Ruby - 59 karakter

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

ile test edildi

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

İsterseniz, IdeOne gibi bir siteyi kullanarak kodunuzu demo olarak izleyebilirsiniz: ideone.com/crvtD
Bay Llama

1
Yerleşik dil özelliklerini kullanmak neden aldatıyor?
Mark Thomas

@ Mark, sadece yerleşik bir işlevi çağıran bir işlev yazmak için hile yapmıyor, ama çok eğlenceli değil. Örneğin: "bir diziyi sıralamak için bir işlev yazın" ->f(array) { return array.sort(); }
jsvnm

2

Python - 58 karakter

Girdi olarak set alarak ugoren'inkinden biraz daha kısa:

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

2

C 270 243 239 karakter

#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;}

P (n, a) fonksiyonu n'ye bir işaretçi döndürür! dev diziler halinde birbiri ardına paketlenmiş a.


1
Bazı ipuçları: <malloc.h> isn't needed (ignore the warnings). sizeof n` 4 (taşınabilirlik güzel, ancak daha kısa daha güzel). Değişken olarak ekstra parametreler kullanın (örn. p(n,a,N,i)). int*p(..)int*a,o;. Parametreler ve dönüş değerleri yerine global değişkenler kullanmak genellikle yardımcı olur.
ugoren

@ugoren, ipuçları için teşekkürler. Şimdiye kadar, globalleri kullanarak başka karakterlerin nasıl tıraş edileceğini görmedim. (Ve hey, işlev olduğu gibi iş parçacığı için güvenli!)
Michael Radford


1

JS - 154 146 karakter

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')döndüren bu .


1

R,

Permütasyonlardan bahsettiğimiz için R'de en az bir çözüm göstermeme izin verin:

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

1

Perl 188

Kütüphane rutini yok, özyineleme yok

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, kütüphaneden permütasyon olmadan :

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, tam yetiştirilmiş, tip güvenli yineleyici:

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 bayt

L.pb

Evet, Pyth bu meydan okuma yayınlandıktan sonra yaratıldı ve hepsi. Bu hala gerçekten harika. : D

Canlı demo.

Stdin'den okuma bir bayt daha kısadır:

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


Sanırım yaparak 8 bayt kazanabilirsiniz: js function p(s,a="",c="",i,z=[]){ bunun yerine js function p(s,a,c,i,z){if(!z)a=c="",z=[]
ColdK

Teşekkürler ColdK. Çalıştı ve şimdi 8 bayt daha kısa.
18:52


0

Python, 53 bayt

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

1
Bu temel olarak gönderilen başka bir cevabın kopyasıdır . Ben bağımsız onunla geldi varsayalım (ve daha iyi golf), ama yinelenen işaret değer olduğunu düşündüm.


0

K (oK) , 3 bayt

Çözüm

prm

Çevrimiçi deneyin!

Açıklama:

Aşağıdaki yerleşik 47 bayt işlevinin 3 baytlık bir yerleşik kısayolu :

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

... girdi olarak bir liste listesi aldığımızı biliyorsanız 23 bayta kısaltılabilir:

{$[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

Aksiyom, 160 bayt

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)

ungolfed

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

Bütün bunlar kütüphane üzerinde permütasyon veren bir kütüphane fonksiyonunu çağırır (sadece [1] üzerindeki permütasyonlar, [1,2] üzerindeki permütasyonlar, [1,2,3] vb. Üzerindeki permütasyonlar; endekslerin ve listelerin oluşturulması; Bunun, X tipi her Liste için iyi derlendiğini belirtmek gerekir.

(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

Axiom yorumlayıcısına bir bağlantınız var mı? Try It Online'a eklenmesini istiyorum ! , ilginç bir dile benziyor.
coinheringaahing Caird

0

Japt , 1 bayt

á

Japt tercümanı

Bu çarptı ve bir Japt cevabı yoktu, bu yüzden devam edip bir tane ekleyeceğimi düşündüm. ábir diziye uygulandığında ve bağımsız değişken olmadan "tüm permütasyonları al" için yerleşiktir. -RSonuç basılır sadece değiştirir nasıl tercüman link kullanılan bayrak.


0

APL (NARS), 39 karakter, 78 bayt

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

Ölçek:

  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 bayt s

œ

Giriş bir dizi / liste olmalıdır.

Açıklama:

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

Outgolfer Erik sayesinde bir bayt kurtardı


Girdiyi tek bir liste olarak alabilirsiniz, yeni satırlarla ayırmanıza gerek yoktur.
Outgolfer Erik

Teşekkür ederim! Şimdi bunu bir bayta kısaltabilirim!
MilkyWay90
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.