Code-Golf: Hoán vị


21

Viết hàm lấy đầu vào là một bộ số nguyên (có thể là danh sách, mảng hoặc bất kỳ vùng chứa nào khác có số riêng biệt) và đưa ra danh sách tất cả các hoán vị của nó.

Python (95 ký tự) :

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

Thật tuyệt khi được đánh trong cùng một ngôn ngữ, nhưng việc triển khai bằng các ngôn ngữ khác được chào đón nhiều hơn!

Câu trả lời:


10

Python - 76 ký tự

Dài hơn gnibbler's, nhưng thực hiện mọi thứ từ đầu.

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

Tôi thích cách sử dụng hiểu ở đây. Nó thực sự đơn giản hóa mã tôi đã đăng rất nhiều!
zxul767


9

J, 11 ký tự

(i.@!@#A.[)

Sử dụng:

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

Giải trình:

i.@!@# sử dụng ba động từ để trả về một danh sách từ 0 đến (! n) -1 trong đó n là số mục trong danh sách đã cho.

[trả về danh sách Trong ví dụ cho thấy rằng cho 0 1 2 3 4 5 A. 1 3 5.

A.trả về một hoán vị có thể có của danh sách thứ hai cho mỗi mục trong danh sách đầu tiên (loại - giải thích thích hợp được đưa ra ở đây ).


Cung cấp một liên kết đến thông tin về J?
Sparr

1
@Sparr Trang web J có một vài hướng dẫn tốt - Học JJ cho lập trình viên C - và một trang bao gồm từ vựng .
Gareth

8

Python - 55 ký tự

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

Không chính xác những gì tôi đã hy vọng mọi người sẽ viết ... nhưng thật hữu ích khi biết Python có các tiện ích như vậy trong thư viện chuẩn.
zxul767

4
@ zxul767: Tại sao phải phát minh lại bánh xe? Sử dụng thư viện chuẩn sẽ chứng minh hiệu quả đáng kinh ngạc ... (và trong trường hợp này tạo ra mã ngắn gọn khi chơi golf ;-)
ChristopheD

8

Haskell, 44 43

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

Về cơ bản giống như giải pháp của ugoren, nhưng Haskell tốt hơn trong việc hiểu danh sách!


Tất nhiên, nó cũng có thể làm

30

import Data.List
p=permutations


Cách tiếp cận hiệu quả hơn, không yêu cầu so sánh bình đẳng:

92

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

Kết quả là, cái này cũng hoạt động khi có các yếu tố trùng lặp trong danh sách.


4
Phần tốt nhất của điều này là giải pháp haskell 44 dòng với khả năng hiểu danh sách ngắn hơn giải pháp python chỉ sử dụng thư viện chuẩn.
monadic

p=Data.List.permutations. Nó cảm thấy như gian lận, mặc dù. Ngoài ra, Data.List.permutationskhông xuất ra các hoán vị theo thứ tự từ điển.
John Dvorak

1
Bạn có thể viết p[]=[[]]như một trường hợp cơ bản thay vào đó, tiết kiệm hai byte.
Lynn

@Mauris: đúng rồi! Tôi bằng cách nào đó giả định rằng danh sách trống sẽ có hoán vị bằng 0 theo định nghĩa, nhưng kể từ 0! = 1 rõ ràng không có ý nghĩa gì. Có một trường hợp cơ sở trống là đẹp hơn nhiều.
đã ngừng quay ngược chiều

3

trong Q (48)

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

Sử dụng mẫu:

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 ký tự

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

ví dụ f[[1,2,3]] đầu ra này .

nhưng sử dụng [].permutationcảm thấy như gian lận, vì vậy:

Ruby - 59 ký tự

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

thử nghiệm với

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

Nếu bạn muốn, bạn có thể giới thiệu mã của mình bằng cách sử dụng một trang web như IdeOne: ideone.com/crvtD
Ông Llama

1
Tại sao sử dụng các tính năng ngôn ngữ tích hợp sẽ gian lận?
Đánh dấu Thomas

@Mark có thể không gian lận, nhưng cũng không thú vị lắm, để viết một hàm chỉ gọi một hàm tích hợp. Ví dụ như: "viết một hàm để sắp xếp một mảng" ->f(array) { return array.sort(); }
jsvnm

2

Python - 58 ký tự

Hơi ngắn hơn so với ugoren, bằng cách lấy một bộ làm đầu vào:

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

2

C, 270 243 239 ký tự

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

Hàm P (n, a) trả về một con trỏ tới n! hoán vị của a, đóng gói cái khác trong một mảng khổng lồ.


1
Một số mẹo: <malloc.h> isn't needed (ignore the warnings). sizeof n` là 4 (tính di động là tốt, nhưng ngắn hơn là đẹp hơn). Sử dụng các tham số phụ như các biến (ví dụ p(n,a,N,i)). int*p(..)int*a,o;. Sử dụng các biến toàn cục thay vì tham số và trả về giá trị thường giúp.
ugoren

@ugoren, cảm ơn vì lời khuyên. Cho đến nay, tôi chưa thấy làm thế nào để cạo bất kỳ nhân vật nào nữa bằng cách sử dụng toàn cầu. (Và này, chức năng này là an toàn cho chủ đề!)
Michael Radford


1

JS - 154 146 ký tự

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}

Kiểm tra: f([1,2,3,4,5]).map(function(a){return a.join('')}).join('\n')trả về cái này .


1

R

Vì chúng ta đang nói về hoán vị, cho phép tôi chỉ ra ít nhất một giải pháp trong R:

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

1

Perl 188

Không có thói quen thư viện, không có đệ quy

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'denty, không có hoán vị từ thư viện:

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, phát triển đầy đủ, loại lặp an toàn:

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

Bình thường, 4 byte

L.pb

Vâng, Pyth đã được tạo ra sau khi thử thách này được đăng và tất cả. Điều này vẫn thực sự mát mẻ. : D

Bản thử trực tiếp.

Đọc từ stdin là một byte ngắn hơn:

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


Tôi nghĩ bạn có thể đạt được 8 byte bằng cách thực hiện: js function p(s,a="",c="",i,z=[]){ thay vì js function p(s,a,c,i,z){if(!z)a=c="",z=[]
ColdK

Cảm ơn ColdK. Nó hoạt động và bây giờ ngắn hơn 8 byte.
sói


0

Python, 53 byte

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

1
Đây về cơ bản là một bản sao của một câu trả lời khác . Tôi cho rằng bạn đã nghĩ ra nó một cách độc lập (và bạn chơi golf tốt hơn), nhưng tôi nghĩ rằng nó đáng để chỉ ra bản sao.


0

K (oK) , 3 byte

Dung dịch

prm

Hãy thử trực tuyến!

Giải trình:

Đó là một 3 byte built-in phím tắt để sau tích hợp 47 chức năng byte:

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

... có thể rút ngắn xuống còn 23 byte nếu chúng ta biết chúng ta đang lấy danh sách ints làm đầu vào:

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

Tiên đề, 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)

vô dụng

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

Tất cả điều này gọi một hàm thư viện cho phép hoán vị trên chỉ mục (chỉ các số nguyên là hoán vị như hoán vị trên [1], hoán vị trên [1,2], hoán vị trên [1,2,3], v.v. của các chỉ số và xây dựng danh sách; Người ta phải lưu ý rằng điều này dường như được biên dịch tốt cho mọi Danh sách loại 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

Bạn có một liên kết đến thông dịch viên Axiom? Tôi muốn được thêm nó vào Dùng thử trực tuyến! , nó trông giống như một ngôn ngữ thú vị.
caird coinheringaahing

0

Japt , 1 byte

á

Thông dịch viên Japt

Điều này đã bị lỗi và không có câu trả lời của Japt, vì vậy tôi đoán rằng tôi sẽ tiếp tục và thêm một câu trả lời. ákhi được áp dụng cho một mảng và không có bất kỳ đối số nào là nội dung của "lấy tất cả các hoán vị". Các -Rcờ được sử dụng trong các liên kết thông dịch viên chỉ đổi như thế nào kết quả được in ra.


0

APL (NARS), 39 ký tự, 78 byte

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

kiểm tra:

  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

œ

Đầu vào phải là một mảng / danh sách.

Giải trình:

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

Đã lưu một byte nhờ Erik the Outgolfer


Bạn có thể lấy đầu vào dưới dạng một danh sách, không cần phải phân tách nó bằng dòng mới.
Erik the Outgolfer

Cảm ơn bạn! Bây giờ tôi có thể rút ngắn điều này xuống còn một byte!
MilkyWay90
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.