Code-Golf: Permutasi


21

Tulis fungsi yang mengambil sebagai input satu set bilangan bulat (bisa berupa daftar, larik atau wadah lain dengan angka yang berbeda), dan menampilkan daftar semua permutasi.

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

Akan menyenangkan bisa dikalahkan dalam bahasa yang sama, tetapi implementasi dalam bahasa lain lebih dari diterima!

Jawaban:


10

Python - 76 karakter

Lebih panjang dari gnibbler, tetapi mengimplementasikan sesuatu dari awal.

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

Saya suka penggunaan pemahaman di sini. Ini benar-benar menyederhanakan kode yang saya posting banyak!
zxul767


9

J, 11 karakter

(i.@!@#A.[)

Pemakaian:

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

Penjelasan:

i.@!@# menggunakan tiga kata kerja untuk mengembalikan daftar dari 0 ke (! n) -1 di mana n adalah jumlah item dalam daftar yang diberikan.

[mengembalikan daftar itu sendiri. Dalam contoh yang ditunjukkan itu memberi 0 1 2 3 4 5 A. 1 3 5.

A.mengembalikan satu kemungkinan permutasi dari daftar kedua untuk setiap item dalam daftar pertama (jenis - penjelasan yang tepat diberikan di sini ).


Berikan tautan ke informasi tentang J?
Sparr

1
@Sparr Situs web J memiliki beberapa panduan bagus - Mempelajari J dan J untuk programmer C - dan sebuah halaman yang membahas kosa kata .
Gareth

8

Python - 55 karakter

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

Tidak persis apa yang saya harapkan orang akan menulis ... tapi itu berguna untuk mengetahui Python memiliki utilitas seperti itu di perpustakaan standar.
zxul767

4
@ zxul767: Mengapa menemukan kembali roda? Menggunakan perpustakaan standar akan terbukti sangat efisien ... (dan dalam hal ini membuat kode ringkas saat bermain golf ;-)
ChristopheD

8

Haskell, 44 43

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

Pada dasarnya sama dengan solusi ugoren, tetapi Haskell lebih baik dalam hal pemahaman daftar!


Tentu saja bisa juga

30

import Data.List
p=permutations


Pendekatan yang lebih efisien, yang tidak memerlukan perbandingan kesetaraan:

92

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

Sebagai akibatnya, yang ini juga berfungsi ketika ada elemen duplikat dalam daftar.


4
Bagian terbaik dari ini adalah bahwa solusi haskell 44 baris dengan pemahaman daftar lebih pendek daripada solusi python yang hanya menggunakan perpustakaan standar.
monadik

p=Data.List.permutations. Rasanya seperti selingkuh. Juga, Data.List.permutationstidak menampilkan permutasi dalam urutan leksikografis.
John Dvorak

1
Anda dapat menulis p[]=[[]]sebagai kasing sebagai gantinya, menghemat dua byte.
Lynn

@Mauris: benar! Saya entah bagaimana mengasumsikan bahwa daftar kosong akan memiliki permutasi nol menurut definisi, tetapi sejak 0! = 1 yang jelas tidak masuk akal. Memiliki kasing kosong jauh lebih baik.
Berhenti mengubah counterclockw

3

dalam Q (48)

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

Penggunaan sampel:

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}

misalnya f[[1,2,3]] keluaran ini .

tetapi menggunakan [].permutation rasanya seperti curang, jadi:

Ruby - 59 karakter

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

diuji dengan

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

Jika Anda ingin, Anda dapat demo kode Anda menggunakan situs seperti IdeOne: ideone.com/crvtD
Mr Llama

1
Mengapa menggunakan fitur bahasa bawaan curang?
Mark Thomas

@ Mark mungkin tidak curang, tapi juga tidak terlalu menyenangkan, untuk menulis fungsi yang hanya memanggil fungsi bawaan. Seperti misalnya: "tulis fungsi untuk mengurutkan array" ->f(array) { return array.sort(); }
jsvnm

2

Python - 58 karakter

Sedikit lebih pendek dari ugoren, dengan mengambil set sebagai input:

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

Fungsi P (n, a) mengembalikan pointer ke n! permutasi dari, dikemas satu demi satu dalam satu susunan raksasa.


1
Beberapa tips: <malloc.h> isn't needed (ignore the warnings). sizeof n` adalah 4 (portabilitas bagus, tetapi lebih pendek lebih baik). Gunakan parameter tambahan sebagai variabel (mis p(n,a,N,i).). int*p(..)int*a,o;. Menggunakan variabel global alih-alih parameter dan mengembalikan nilai sering membantu.
ugoren

@ugoren, terima kasih atas tipsnya. Sejauh ini, saya belum melihat cara mencukur karakter lebih lanjut menggunakan global. (Dan hei, fungsinya aman-seperti ini!)
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}

Tes: f([1,2,3,4,5]).map(function(a){return a.join('')}).join('\n')mengembalikan ini .


1

R

Karena kita berbicara tentang permutasi, izinkan saya menunjukkan setidaknya satu solusi di R:

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

1

Perl 188

Tidak ada rutinitas perpustakaan, tidak ada rekursi

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, tanpa permutasi dari perpustakaan:

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, dewasa, jenis iterator aman:

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 byte

L.pb

Ya, Pyth dibuat setelah tantangan ini diposting dan semuanya. Ini masih sangat keren. : D

Demo langsung.

Membaca dari stdin lebih pendek satu byte:

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


Saya pikir Anda bisa mendapatkan 8 byte dengan melakukan: js function p(s,a="",c="",i,z=[]){ alih-alih js function p(s,a,c,i,z){if(!z)a=c="",z=[]
ColdK

Terima kasih ColdK. Ini berhasil dan sekarang 8 byte lebih pendek.
wolfhammer


0

Python, 53 byte

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

1
Ini pada dasarnya adalah duplikat dari jawaban lain yang dikirimkan . Saya berasumsi Anda datang dengan itu secara mandiri (dan Anda bermain golf lebih baik), tapi saya pikir itu layak menunjukkan duplikat.


0

K (oK) , 3 byte

Larutan

prm

Cobalah online!

Penjelasan:

Ini adalah 3 byte built-in pintas ke berikut built-in 47 fungsi byte:

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

... yang dapat disingkat menjadi 23 byte jika kita tahu kita mendapatkan daftar int sebagai input:

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

Aksioma, 160 byte

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

Semua ini memanggil satu fungsi perpustakaan yang memberikan permutasi pada indeks (hanya integer sebagai permutasi sebagai permutasi pada [1], permutasi pada [1,2], permutasi pada [1,2,3] dll). Jadi cukup dapatkan set ini indeks dan membangun daftar; Kita harus mencatat bahwa ini tampaknya dikompilasi dengan baik untuk setiap Daftar tipe 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

Apakah Anda memiliki tautan ke juru bahasa Axiom? Saya ingin menambahkannya ke Try It Online! , sepertinya bahasa yang menarik.
caird coinheringaahing

0

Japt , 1 byte

á

Japt penerjemah

Ini terbentur dan tidak memiliki jawaban Japt, jadi saya pikir saya akan melanjutkan dan menambahkan satu. áketika diterapkan ke array dan tanpa argumen apa pun adalah builtin untuk "dapatkan semua permutasi". The -Rbendera yang digunakan di link interpreter hanya memodifikasi bagaimana hasilnya dicetak.


0

APL (NARS), 39 karakter, 78 byte

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

uji:

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

œ

Input harus berupa array / daftar.

Penjelasan:

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

Menyimpan satu byte berkat Erik the Outgolfer


Anda dapat mengambil input sebagai daftar tunggal, tidak perlu memisahkannya dengan baris baru.
Erik the Outgolfer

Terima kasih! Saya sekarang dapat mempersingkat ini menjadi satu byte!
MilkyWay90
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.