代码高尔夫:排列


21

编写一个函数,该函数接受一组整数(可以是列表,数组或任何其他具有不同数字的容器)作为输入,并输出所有其排列的列表。

Python(95个字符)

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

用相同的语言击败真是太好了,但是其他语言的实现实在值得欢迎!

Answers:


10

Python-76个字符

比g子手更长,但从头开始实现。

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

我喜欢这里理解的用法。它确实简化了我发布的代码!
zxul767'3


9

J,11个字符

(i.@!@#A.[)

用法:

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

说明:

i.@!@# 使用三个动词返回从0到(!n)-1的列表,其中n是给定列表中的项数。

[返回列表本身。在给出的示例中0 1 2 3 4 5 A. 1 3 5

A.返回第一个列表中每个项目的第二个列表的可能排列(种类-在给出了适当的解释)。


提供指向有关J?的信息的链接。
Sparr 2012年

1
@Sparr J网站上有一些很好的指南- 学习C语言的JJ知识 -以及一个涵盖词汇表的页面
Gareth 2012年

8

Python-55个字符

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

不完全是我希望人们写的东西……但是了解Python在标准库中有这样的实用程序很有用。
zxul767'3

4
@ zxul767:为什么要重新发明轮子?使用标准库将被证明是非常有效的...(在这种情况下,打高尔夫球时简明扼要的代码;-)
ChristopheD

8

哈斯克尔,44 43

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

本质上与ugoren的解决方案相同,但Haskell的列表理解能力更好!


当然也可以

30

import Data.List
p=permutations


更有效的方法,不需要相等比较:

92

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

作为结果,当列表中有重复的元素时,此选项也适用。


4
最好的部分是列表理解的44行haskell解决方案比仅使用标准库的python解决方案要短。
monadic 2012年

p=Data.List.permutations。不过,这感觉就像在作弊。同样,Data.List.permutations不按字典顺序输出排列。
约翰·德沃夏克

1
您可以改写p[]=[[]]为基本情况,节省两个字节。
林恩

@毛里斯:对!我以某种方式假定该空列表根据定义将具有零排列,但是从0开始!= 1显然没有任何意义。有一个空的基本情况会更好。
停止转动逆时针

3

在Q中(48)

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

用法示例:

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

红宝石-23个字符

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

例如f[[1,2,3]] 输出this

但是使用[].permutation感觉就像在作弊,所以:

红宝石-59个字符

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

经过测试

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

如果需要,您可以使用IdeOne这样的网站进行代码演示:ideone.com/crvtD
Llama先生

1
为什么使用内置语言功能会作弊?
马克·托马斯

@Mark编写一个仅调用内置函数的函数可能不会欺骗,但也不会很有趣。例如:“编写对数组进行排序的函数”->f(array) { return array.sort(); }
jsvnm

2

Python-58个字符

通过输入一个集合,比ugoren的略短:

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

2

C, 270 243 239个字符

#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)返回一个指向n!的指针!一个排列的排列,一个接一个地排列在一起。


1
一些技巧:<malloc.h> isn't needed (ignore the warnings). sizeof n`为4(可移植性很好,但更短则更好)。使用额外的参数作为变量(例如p(n,a,N,i))。int*p(..)int*a,o;。使用全局变量代替参数和返回值通常会有所帮助。
ugoren 2012年

@ugoren,感谢您的提示。到目前为止,我还没有看到如何使用全局变量剃除更多的字符。(嘿,该函数本身就是线程安全的!)
Michael Radford 2012年


1

JS- 154 146个字符

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}

测试:f([1,2,3,4,5]).map(function(a){return a.join('')}).join('\n')返回此值


1

[R

由于我们正在谈论置换,因此让我在R中显示至少一个解决方案:

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

1

Perl 188

没有库例程,没有递归

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,快捷,肮脏,没有库的排列

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,完整的类型安全迭代器:

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个字节

L.pb

是的,Pyth是在发布所有挑战之后创建的。这仍然很酷。:D

现场演示。

从stdin读取要短一个字节:

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


我认为您可以通过执行以下操作获得8个字节:js function p(s,a="",c="",i,z=[]){ 而不是 js function p(s,a,c,i,z){if(!z)a=c="",z=[]
ColdK

谢谢ColdK。它有效,现在缩短了8个字节。
wolfhammer '18


0

Python,53个字节

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

1
这基本上是另一个提交的答案的副本。我认为您是独立提出的(您打得更好),但是我认为值得指出重复的事物。


0

K(oK),3个字节

prm

在线尝试!

说明:

这是3个字节的内置快捷方式,用于以下内置 47字节的功能:

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

...如果我们知道要获取一个int列表作为输入,则可以缩短为23个字节:

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

公理,160字节

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)

不打高尔夫球

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

所有这些都调用一个库函数,该函数给出索引的置换(仅整数作为[1]的置换,[1,2]的置换,[1,2,3]的置换等)。因此,获取这些集合就足够了索引并建立列表;必须注意,这似乎对每个X类型的List都适用

(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解释器的链接?我希望将其添加到“ 在线试用”中!,它看起来像是一种有趣的语言。
Caird coinheringaahing

0

Japt,1个字节

á

Japt口译员

这碰到了,没有Japt的答案,所以我想我会继续添加一个。á当应用于数组且不带任何参数时,它是“获取所有排列”的内置函数。-R解释器链接中使用的标志仅修改结果的打印方式。


0

APL(NARS),39个字符,78个字节

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

测试:

  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字节s

œ

输入必须是数组/列表。

说明:

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

感谢Outgolfer的Erik节省了一个字节


您可以将输入作为单个列表,而不必将其用换行符分隔。
暴民埃里克(Erik the Outgolfer)'18年

谢谢!我现在可以将其缩短为一个字节!
MilkyWay90 '18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.