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!

zxul767
sumber

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

Gareth
sumber
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))
gnibbler
sumber
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.

berhenti mengubah counterclockwis
sumber
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
sinedcm
sumber
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
jsvnm
sumber
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[[]]
Jules Olléon
sumber
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.

Michael Radford
sumber
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
2

K, 30 byte

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

Tidak ada builtin!

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

JiminP
sumber
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)
Paolo
sumber
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]}}
ardnew
sumber
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)
Pengguna tidak diketahui
sumber
1

Python - 50 karakter

import itertools
list(itertools.permutations("123"))
Jared Burrows
sumber
Mengapa ini akan diturunkan 5 tahun kemudian?
Jared Burrows
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
kirbyfan64sos
sumber
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>

wolfhammer
sumber
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
1

Brachylog , 2 byte

pᵘ

Cobalah online!

 ᵘ    Find every unique
p     permutation of the input.
String yang tidak terkait
sumber
0

Python, 53 byte

from itertools import*;lambda x:list(permutations(x))
Oliver Ni
sumber
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

Jelly , 2 byte

Œ!

Cobalah online!

Yay untuk builtin!

caird coinheringaahing
sumber
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)
streetster
sumber
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
RosLuP
sumber
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.

Kamil Drakari
sumber
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 
RosLuP
sumber
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

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