รหัส - กอล์ฟ: การเรียงสับเปลี่ยน


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

มันคงจะดีถ้าถูกทุบในภาษาเดียวกัน แต่การใช้งานในภาษาอื่นนั้นยินดีต้อนรับ!

คำตอบ:


10

Python - 76 ตัวอักษร

นานกว่า gnibbler แต่ดำเนินการตั้งแต่เริ่มต้น

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


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

1
@Sparr เว็บไซต์ Jมีคู่ของคำแนะนำที่ดี - การเรียนรู้ JและJ สำหรับโปรแกรมเมอร์ C - และหน้าครอบคลุมคำศัพท์
Gareth

8

Python - 55 ตัวอักษร

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

ไม่ใช่สิ่งที่ฉันหวังว่าคนทั่วไปจะเขียน ... แต่มันมีประโยชน์ที่จะรู้ว่า Python มีโปรแกรมอรรถประโยชน์ดังกล่าวในไลบรารีมาตรฐาน
zxul767

4
@ zxul767: ทำไมต้องคิดค้นล้อใหม่ การใช้ไลบรารี่มาตรฐานจะพิสูจน์ได้ว่ามีประสิทธิภาพอย่างไม่น่าเชื่อ ... (และในกรณีนี้จะทำให้รหัสสั้นกระชับเมื่อเล่นกอล์ฟ ;-)
ChristopheD

8

Haskell, 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))

ในฐานะที่เป็น consequece สิ่งนี้ก็ใช้ได้เช่นกันเมื่อมีองค์ประกอบที่ซ้ำกันในรายการ


4
ส่วนที่ดีที่สุดของสิ่งนี้คือโซลูชัน 44 บรรทัดมีเคลล์ที่มีรายการความเข้าใจสั้นกว่าโซลูชันไพ ธ อนที่เพิ่งใช้ไลบรารีมาตรฐาน
monadic

p=Data.List.permutations. มันให้ความรู้สึกเหมือนการโกง นอกจากนี้Data.List.permutationsจะไม่ส่งออกพีชคณิตตามลำดับพจนานุกรม
John Dvorak

1
คุณสามารถเขียนp[]=[[]]เป็นกรณีฐานแทนการบันทึกสองไบต์
Lynn

@Mauris: ถูกต้อง! ฉันคิดว่ารายการว่างจะมีการเรียงสับเปลี่ยนเป็นศูนย์ตามคำนิยาม แต่ตั้งแต่ 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

Ruby - 23 ตัวอักษร

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

ตัวอย่างเช่นผลนี้f[[1,2,3]]

แต่การใช้[].permutationรู้สึกเหมือนโกงดังนั้น:

Ruby - 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
Mr. Llama

1
เหตุใดการใช้คุณสมบัติภาษาในตัวจึงเป็นการโกง?
มาร์คโทมัส

@ Mark อาจจะไม่โกง แต่ก็ไม่สนุกเหมือนกันถ้าจะเขียนฟังก์ชั่นที่เพิ่งเรียกฟังก์ชั่นในตัว เช่น: "เขียนฟังก์ชั่นเพื่อจัดเรียงอาร์เรย์" ->f(array) { return array.sort(); }
jsvnm

2

Python - 58 ตัวอักษร

สั้นกว่าของ ugoren เล็กน้อยโดยใช้ set เป็น input:

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

2

ค, 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! พีชคณิตของ a, อัดแน่นไปด้วยกันในอาเรย์ยักษ์ตัวหนึ่ง


1
คำแนะนำ: ขนาดของ<malloc.h> isn't needed (ignore the warnings). n` คือ 4 (การพกพาดี แต่สั้นกว่าคือดีกว่า) ใช้พารามิเตอร์พิเศษเป็นตัวแปร (เช่นp(n,a,N,i)) int*p(..)int*a,o;. การใช้ตัวแปรโกลบอลแทนพารามิเตอร์และค่าส่งคืนมักจะช่วยได้
ugoren

@ugoren ขอบคุณสำหรับเคล็ดลับ จนถึงตอนนี้ฉันยังไม่เห็นวิธีการโกนตัวละครอื่น ๆ โดยใช้ globals (และเดี๋ยวก่อนฟังก์ชั่นนี้จะปลอดภัยเหมือนด้าย!)
Michael Radford


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

สกาลา 30:

def p(s:Seq[_])=s.permutations 

Scala 195, quick'n'dirty โดยไม่มีการเปลี่ยนลำดับจากห้องสมุด:

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, ปลูกเต็มที่, พิมพ์ iterator ที่ปลอดภัย:

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


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

... ซึ่งสามารถย่อให้เหลือ 23 ไบต์หากเรารู้ว่าเราได้รับรายการ ints เป็นอินพุต:

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

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

ทั้งหมดนี้เรียกฟังก์ชั่นห้องสมุดหนึ่งที่ให้การเปลี่ยนแปลงดัชนี (เฉพาะจำนวนเต็มเป็นการเปลี่ยนแปลงเป็นพีชคณิตใน [1], พีชคณิตใน [1,2], พีชคณิตใน [1,2,3] ฯลฯ ) ดังนั้นก็เพียงพอที่จะได้รับชุดเหล่านี้ ของดัชนีและสร้างรายการ; หนึ่งจะต้องทราบว่าสิ่งนี้ดูเหมือนว่าจะรวบรวมที่ดีสำหรับทุกรายการประเภท 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

คุณมีลิงค์ไปยังล่าม Axiom หรือไม่? ฉันชอบที่จะเพิ่มเข้าไปในTry It Online! ดูเหมือนว่าภาษาที่น่าสนใจ
caird coinheringaahing

0

Japt 1 ไบต์

á

ล่าม Japt

สิ่งนี้ชนและไม่มีคำตอบของ Japt ดังนั้นฉันจึงคิดว่าฉันจะดำเนินการต่อและเพิ่มอีกหนึ่งข้อ áเมื่อนำไปใช้กับอาร์เรย์และไม่มีข้อโต้แย้งใด ๆ เป็น builtin สำหรับ "รับเงินทั้งหมด" การ-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)

บันทึกเป็นไบต์ด้วย Erik the Outgolfer


คุณสามารถรับข้อมูลเป็นรายการเดียวโดยไม่จำเป็นต้องแยกเป็นรายการใหม่
Erik the Outgolfer

ขอขอบคุณ! ตอนนี้ฉันสามารถย่อให้เหลือหนึ่งไบต์!
MilkyWay90
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.