สร้างพาร์ติชันย่อยทั้งหมด


11

ให้ลิสต์ของจำนวนเต็มแบบไม่ว่างเปล่าให้เอาต์พุตทุก ๆ การแบ่งพาร์ติชั่นที่เป็นไปได้ของรายการที่แต่ละพาร์ติชั่นเป็นรายการย่อยที่ไม่ว่างเปล่า

ดังนั้นสำหรับรายการ[1, 2, 3, 4]ผลลัพธ์คือ:

[[1, 2, 3, 4]]
[[1, 2, 3], [4]]
[[1, 2], [3, 4]]
[[1, 2], [3], [4]]
[[1], [2, 3, 4]]
[[1], [2, 3], [4]]
[[1], [2], [3, 4]]
[[1], [2], [3], [4]]

ลำดับของรายการในผลลัพธ์ไม่สำคัญดังนั้น[[1, 2, 3, 4]]อาจเป็นครั้งแรกสุดท้ายหรือที่ใดก็ได้ คำสั่งขององค์ประกอบจะต้องถูกเก็บรักษาไว้

นี่คือรหัสกอล์ฟคำตอบที่สั้นที่สุดจึงชนะ


ที่เกี่ยวข้อง: รายการพาร์ทิชัน!


2
เราสามารถละเว้นสภาพแวดล้อม[...]ในรูปแบบผลลัพธ์ได้หรือไม่ (ตราบเท่าที่พาร์ทิชันแยกออกจากกันอย่างชัดเจนเช่นโดย linefeeds)
Martin Ender

รูปแบบอินพุตและเอาต์พุตมีความยืดหยุ่น แต่ควรมีรูปแบบที่คล้ายคลึงกัน ดังนั้นหากรายการอินพุตมีองค์ประกอบอยู่ในหนึ่งบรรทัดรายการผลลัพธ์ก็ควรเช่นกัน
mbomb007

นั่นไม่ใช่สิ่งที่ฉันหมายถึง ดูคำตอบของ Bash โดยจะใช้:เป็นตัวคั่นรายการ แต่ในการส่งออก, [...]พาร์ทิชันที่ตัวเองไม่ได้อยู่ในห่อคู่ที่เพิ่มขึ้นของ
Martin Ender

หรือถามแตกต่างกัน: ในรูปแบบตัวอย่างของคุณในการท้าทายฉันสามารถดรอปครั้งแรก[และครั้งสุดท้าย]จากแต่ละบรรทัดได้หรือไม่
Martin Ender

คำตอบ:



13

Retina , 27 19 ไบต์

จำนวนไบต์ถือว่าการเข้ารหัส ISO 8859-1

+1%`,
;$'¶$`];[
;
,

ลองออนไลน์!

คำอธิบาย

แน่นอนว่านี่คำนวณพาร์ติชันทั้งหมดโดยใช้การประมวลผลสตริง แนวคิดพื้นฐานคือเราสามารถสร้างพาร์ติชันทั้งหมดได้โดยการตัดสินใจ,ว่าจะแยกทีละรายการหรือไม่ ชนิดของสิ่งนี้สามารถทำได้ใน Retina โดยการจับคู่แต่ละรายการ,และใช้การแทนที่ซึ่งจะให้ผลลัพธ์ที่เป็นไปได้ทั้งสอง

อินพุตทำหน้าที่เป็นตัวพิมพ์ใหญ่: พาร์ติชันที่องค์ประกอบทั้งหมดยังคงอยู่ในรายการเดียว

+1%`,
;$'¶$`];[

ตอนนี้เราซ้ำ ( +) จับคู่1เครื่องหมายจุลภาคแรก ( ) ,ในแต่ละบรรทัด ( %) (ถือว่าบรรทัดนั้นเป็นสตริงแยกต่างหากซึ่งเกี่ยวข้องกับ$'และ `` $ 1 'ในการทดแทน)

เครื่องหมายจุลภาคนั้นถูกแทนที่ด้วย:

;   A semicolon. This is just a stand-in for the comma, so we know we've already
    processed it and it won't be substituted again by the next iteration.
$'  Everything after the match. This completes the first (unchanged) version of
    the current line.
¶   A linefeed. Since the next iteration will scan for all lines again, this doubles
    the number of strings we're working with.
$`  Everything before the match. This completes the second (split) version of
    the current line.
];[ A semicolon around which we split the list.

โปรดจำไว้ว่าทุกสิ่งที่อยู่ด้านหน้าของการแข่งขันและหลังจากการแข่งขันยังคงอยู่ในสตริงอยู่แล้วดังนั้นผลเต็มรูปแบบจึงเป็นจริง$`;$'¶$`];[$'ซึ่งอธิบายว่าทำไมเราจึงใส่คำต่อท้ายและคำนำหน้าในลำดับนั้น

การวนซ้ำนี้จะหยุดเมื่อเครื่องหมายจุลภาคทั้งหมดหายไป

;
,

ในที่สุดให้แทนที่เครื่องหมายอัฒภาคด้วยเครื่องหมายจุลภาคอีกครั้งเพื่อให้ตรงกับรูปแบบการป้อนข้อมูล


10

Pure Bash, 28

eval echo [${1//:/{:,]:[\}}]

รายการจะถูกคั่นด้วยโคลอนและอยู่ในวงเล็บเหลี่ยม ตัวอย่างเช่นในคำถามรายการอินพุตจะเป็น1:2:3:4และเอาต์พุตคือ:

[1:2:3:4] [1:2:3]:[4] [1:2]:[3:4] [1:2]:[3]:[4] [1]:[2:3:4] [1]:[2:3]:[4] [1]:[2]:[3:4] [1]:[2]:[3]:[4]

ลองมันออนไลน์

  • ${1//:/REPLACEMENT}แทนที่โคลอน$1ด้วย{:,]:[\}
  • สิ่งนี้สร้างการขยายรั้งเช่น [1{:,]:[}2{:,]:[}3{:,]:[}4]
  • eval (และการ\หลบหนีอย่างระมัดระวัง) ทำให้การขยายรั้งเกิดขึ้นครั้งสุดท้ายและให้ผลลัพธ์ที่ต้องการ

หากจำเป็นต้องตรงกับ[[ , , ...]]รูปแบบที่กำหนดเราสามารถทำได้ดังนี้:

Pure Bash, 47

eval printf '%s\\n' ${1//, /{\\,\\ ,]\\,\\ [\}}

ลองมันออนไลน์


6

Pyth , 2 ไบต์

./

พร้อมอินพุต[1, 2, 3, 4](ตัวอย่าง)

คำอธิบาย : ./เป็นตัวดำเนินการพาร์ติชัน มันจะส่งกลับทุกแผนกของรายการอินพุตให้เป็นรายการย่อยที่ไม่เข้าร่วม อินพุตจะถูกป้อนเข้าโปรแกรมโดยปริยาย

ทดสอบออนไลน์!


6

05AB1E , 5 ไบต์

Œæʒ˜Q

ลองออนไลน์!

Œæʒ˜Q  Main link. Argument l
Œ      Get all sublists of l
 æ     Powerset of those lists
  ʒ˜Q  Filter: Keep the lists that when flattened equal the input

1
ว้าวนี่เป็นคำตอบที่เรียบร้อยมาก !
Adnan

1
@ ขอบคุณมากฉันมีความสุขมากกับมัน แม้ว่ามันจะเป็นทุกอย่าง แต่มีประสิทธิภาพ :)
kalsowerus

คำตอบที่ดีเมื่อยังไม่มีตัวในตัว +1 จากฉัน! เพียงแค่ปล่อยให้คนอื่นมาที่นี่ในอนาคต แต่ตอนนี้ 05AB1E มีขนาด 2 ไบต์เพื่อรับพาร์ติชันทั้งหมด:: ลองออนไลน์
Kevin Cruijssen

4

Python 3 , 82 72 66 ไบต์

f=lambda l:[k+[l[i:]]for i in range(len(l))for k in f(l[:i])]or[l]

ลองออนไลน์!

-5 ไบต์ขอบคุณ @JonathanAllan


โอ้ฉันไม่สามารถ ^ V อีกครั้ง :( จริงผมพยายามบางอย่างเช่นนี้และมันไม่ได้ทำงานผมคงจะหายไปที่ไหนสักแห่งที่ไม่ถูกต้อง.
โจนาธานอัลลัน


1
@Janathan ทุกคนขอบคุณมาก! ฉันจะสามารถประหยัดไบต์อื่นโดยการนำlในที่สุด
OVS

โซลูชันนี้มีอยู่ที่นี่แล้ว ฉันส่งข้อความ @feersum ใน TNB หลังจากโพสต์คำถามเพื่อให้เขามีโอกาสโพสต์
mbomb007

ฉันไม่ได้หมายความว่าคุณควรยกเลิกมันฉันแค่ตั้งใจให้คุณเอาชนะเขา มันเป็นทางเลือกของคุณแน่นอน
mbomb007

4

Haskell , 59 55 49 ไบต์

p[x]=[[[x]]]
p(x:r)=do a:b<-p r;[(x:a):b,[x]:a:b]

ลองออนไลน์!

โซลูชันแบบเรียกซ้ำ ตัวอย่างการใช้งาน: ผลตอบแทนp [1,2,3][[[1,2,3]],[[1,2],[3]],[[1],[2,3]],[[1],[2],[3]]]

-6 ไบต์ขอบคุณxnor !


1
คุณสามารถเขียนบรรทัดที่สองให้สั้นลงโดยใช้สัญลักษณ์: do a:b<-p r;[(x:a):b,[x]:a:b](นี่จะเปลี่ยนลำดับของรายการ)
xnor

1
นอกจากนี้<*>ทำสิ่งที่คุณต้องการอย่าง[\(a:b)->(x:a):b,([x]:)]<*>p rแน่นอนแม้ว่าจะนานกว่าdoเพราะแลมบ์ดาแรกดูเหมือนจะต้องมีการจับคู่รูปแบบ
xnor

3

J , 42 ไบต์

<@(</."1)~<:@#_&(][:;<@(,~"{~0 1+>./)"1)0:

สร้างพาร์ติชันย่อยของรายการทั้งหมดโดยการสร้างคีย์สำหรับรายการย่อยของพาร์ติชันที่มีความยาว 1 และวนซ้ำตามความยาวของรายการอินพุต แต่ละรายการในพาร์ติชั่นย่อยจะเกิดขึ้นโดยการเลือกจากปุ่ม

ตัวอย่างเช่นนี่คือกระบวนการสร้างคีย์สำหรับรายการความยาว 4 รายการ

ตัวอย่าง

ลองออนไลน์!



2

Brachylog 2 ไบต์

~c

ลองออนไลน์!

การส่งฟังก์ชั่นที่สร้างผลลัพธ์ผ่านการทำหน้าที่เป็นเครื่องกำเนิดไฟฟ้า (ลิงก์ TIO มีรหัสพิเศษเพื่อทำให้เป็นโปรแกรมเต็มรูปแบบเพื่อจุดประสงค์ในการทดสอบ)

บังเอิญแม้ว่าจะไม่ใช่เทคนิคในตัว builtin นี่เป็นเรื่องธรรมดาที่ใช้กันใน Brachylog ว่า) มันอาจจะสมควรเป็นตัวแทนไบต์เดียวและ b) cbuiltin สามารถใช้พารามิเตอร์เพื่อให้การยืนยันเกี่ยวกับการป้อนข้อมูลของพารามิเตอร์(ในขณะที่ส่วนใหญ่ builtins พารามิเตอร์ พูดคุยเกี่ยวกับวิธีการผลิตผลลัพธ์ )

คำอธิบาย

~c
~     Find a value with the following properties:
 c      concatenating its elements produces {the input}

2

APL, 26 ไบต์

{⊂∘⍵¨1,¨↓⍉(X⍴2)⊤⍳2*X←⍴1↓⍵}

ทดสอบ:

      {⊂∘⍵¨1,¨↓⍉(X⍴2)⊤⍳2*X←⍴1↓⍵} 1 2 3 4
┌─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┐
│┌─────┬─┐│┌───┬───┐│┌───┬─┬─┐│┌─┬─────┐│┌─┬───┬─┐│┌─┬─┬───┐│┌─┬─┬─┬─┐│┌───────┐│
││1 2 3│4│││1 2│3 4│││1 2│3│4│││1│2 3 4│││1│2 3│4│││1│2│3 4│││1│2│3│4│││1 2 3 4││
│└─────┴─┘│└───┴───┘│└───┴─┴─┘│└─┴─────┘│└─┴───┴─┘│└─┴─┴───┘│└─┴─┴─┴─┘│└───────┘│
└─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┘

คำอธิบาย:

  • X←⍴1↓⍵: Xคือความยาวของ(รายการอินพุต) โดยที่องค์ประกอบแรกหายไป
  • ⍳2*X: ตัวเลข [1..2 ^ X]
  • (X⍴2)⊤: การแสดงฐาน 2 ของตัวเลขเหล่านั้นพร้อมXตำแหน่ง (เช่นXตัวมันเองจะล้อมรอบไป0)
  • ↓⍉: หมุนเมทริกซ์และแยกตามเส้น ( ให้ผลลัพธ์เป็นเมทริกซ์ที่มีตัวเลขตามแนวคอลัมน์) ทำให้อาร์เรย์ของเวกเตอร์บิต
  • 1,¨: เติมเวกเตอร์ 1 บิตต่อหนึ่งบิต
  • ⊂∘⍵¨: สำหรับเวกเตอร์แต่ละบิตให้แบ่งที่ 1


1

Python 90 ไบต์

outgolfed โดย ovs (ทำสิ่งที่ฉันคิดว่าฉันพยายามทำงาน: p)

def f(a):r=[[a]];i=len(a)-1;exec("for s in f(a[:i]):s+=[a[i:]];r+=[s]\ni-=1\n"*i);return r

ฟังก์ชั่นวนซ้ำซึ่งสร้างรายการของพาร์ติชันจากชิ้นส่วนของอินพุตพร้อมกับหางถึงเมื่อชิ้นส่วนมีความยาว 1

ลองออนไลน์!

การexecบันทึก 4 ไบต์บน a whileหรือ 3 เหนือforลูป (ด้านล่าง) เนื่องจากมันหมายถึงเพียงสอง\ns มากกว่าสองระดับของการเยื้องทำให้ฟังก์ชันทั้งหมดอยู่ในหนึ่งบรรทัด (ในขณะที่ลำดับการแบ่งไม่สำคัญ)

def f(a):
 r=[[a]]
 for i in range(1,len(a)):
  for s in f(a[:i]):s+=[a[i:]];r+=[s]
 return r



1

Ruby , 62 57 ไบต์

->l{(0..2**l.size).map{|x|l.chunk{1&x/=2}.map &:last}|[]}

ลองออนไลน์!

มันทำงานอย่างไร:

  • จำนวนพาร์ติชันคือ 2 ^ (n-1): ฉันวนซ้ำเลขฐานสองในช่วงนั้นนำกลุ่มของศูนย์และคนและแมปพวกเขาเป็นส่วนย่อยของรายการเริ่มต้น
  • แทนที่จะทำให้เล่นด้วยช่วงฉันทำให้มันสองครั้งและทิ้งซ้ำในตอนท้าย ตอนนี้ฉันยังสามารถทิ้งเลขฐานสองแรกและทำให้ฟังก์ชั่นอันสั้น

0

JavaScript (ES6), 87 ไบต์

([e,...a],b=[],c=[e],d=[...b,c])=>1/a[0]?[...f(a,b,[...c,a[0]]),...f(a,d,[a[0]])]:[d]

คำอธิบาย: bเป็นรายการของรายการย่อยก่อนหน้าcคือรายการย่อยปัจจุบัน (ซึ่งเริ่มต้นเป็นองค์ประกอบแรกของอาร์เรย์เนื่องจากรายการนั้นต้องอยู่ในรายการย่อยแรก) ในขณะdที่รายการของรายการย่อยทั้งหมด ส่วนที่เหลือขององค์ประกอบอาร์เรย์จะถูกประมวลผลซ้ำ ในแต่ละกรณีมีสองตัวเลือก: องค์ประกอบถัดไปจะถูกผนวกเข้ากับรายการย่อยปัจจุบันหรือรายการย่อยปัจจุบันเสร็จสมบูรณ์และองค์ประกอบถัดไปจะเริ่มรายการย่อยใหม่ ผลลัพธ์ที่เกิดซ้ำจะถูกรวมเข้าด้วยกัน เมื่ออาร์เรย์หมดลงรายการของรายการย่อยทั้งหมดจะเป็นผลลัพธ์


0

APL (NARS) 38 ถ่าน 76 ไบต์

{k←↑⍴⍵⋄x←11 1‼k k⋄y←⍵⋄∪{x[⍵;]⊂y}¨⍳↑⍴x}

ใช้ฟังก์ชัน Nars 11 1‼ kk แต่ช้ามากใช้ไม่ได้สำหรับอาเรย์ของ 9 องค์ประกอบแล้ว ...

  P3←{k←↑⍴⍵⋄x←11 1‼k k⋄y←⍵⋄∪{x[⍵;]⊂y}¨⍳↑⍴x}

  ⍴∘P3¨{1..⍵}¨⍳8
1  2  4  8  16  32  64  128 
  P3 'abcd'
abcd    abc d    ab cd    a bcd    ab c d    a bc d    a b cd    a b c d

นี่คือฟังก์ชั่นที่ไม่ได้ใช้ในตัว:

r←h w;k;i
   r←⊂,⊂w⋄k←↑⍴w⋄i←1⋄→B
A: r←r,(⊂⊂,i↑w),¨h i↓w⋄i+←1
B: →A×⍳i<k

  h 'abcd'
abcd    a bcd    a b cd    a b c d    a bc d    ab cd    ab c d    abc d
  ⍴∘h¨{1..⍵}¨⍳8
2  4  8  16  32  64  128 

เราเห็นผลลัพธ์แต่ละประเภท:

  o h ,1
┌──────┐
│┌1───┐│
││┌1─┐││
│││ 1│││
││└~─┘2│
│└∊───┘3
└∊─────┘
  o h 1 2
┌2───────────────────┐
│┌1─────┐ ┌2────────┐│
││┌2───┐│ │┌1─┐ ┌1─┐││
│││ 1 2││ ││ 1│ │ 2│││
││└~───┘2 │└~─┘ └~─┘2│
│└∊─────┘ └∊────────┘3
└∊───────────────────┘

ฉันไม่รู้ว่ามันทำงานได้อย่างไรมันเป็นเพียงแค่การลองแบบศึกษาพฤติกรรม ...

เป็นไปได้ที่ฉันทำผิดพลาด ทั้งฟังก์ชั่นสร้างพาร์ทิชันของรายการอะไรก็ตามที่ป้อนเข้าและไม่เพียง 1 2 ... n


0

ความจริง 251 ไบต์

C==>concat;A==>List Any;px(a:A):A==(k:=#a;r:=copy[a];k<=1=>r;i:=1;repeat(i>=k=>break;x:=a.(1..i);y:=a.((i+1)..k);z:=px(y);t:=[x,z.1];for j in 2..#z repeat(w:=(z.j)::A;m:=#w;v:=[x];for q in 1..m repeat v:=C(v,w.q);t:=C(t,[v]));r:=C(r,copy t);i:=i+1);r)

หากใครบางคนพบสิ่งที่ดีกว่า ... ungof และทดสอบ:

pp(a:List Any):List Any==
  k:=#a;r:=copy[a];k<=1=>r;i:=1
  repeat
    i>=k=>break
    x:=a.(1..i);y:=a.((i+1)..k);z:=pp(y);
    t:=[x,z.1]
    for j in 2..#z repeat
           w:=(z.j)::List Any
           m:=#w; v:=[x]
           for q in 1..m repeat 
                       v:=concat(v,w.q);
           t:=concat(t,[v])
    r:=concat(r,copy t);
    i:=i+1
  r

(7) -> px []
 (7)  [[]]
                                                           Type: List Any
(8) -> px [1]
 (8)  [[1]]
                                                           Type: List Any
(9) -> px [1,2]
 (9)  [[1,2],[[1],[2]]]
                                                           Type: List Any
(10) -> px [1,2,3]
 (10)  [[1,2,3],[[1],[2,3]],[[1],[2],[3]],[[1,2],[3]]]
                                                           Type: List Any
(11) -> px [1,2,3,4,5,6]
 (11)
[[1,2,3,4,5,6], [[1],[2,3,4,5,6]], [[1],[2],[3,4,5,6]],
 [[1],[2],[3],[4,5,6]], [[1],[2],[3],[4],[5,6]], [[1],[2],[3],[4],[5],[6]],
 [[1],[2],[3],[4,5],[6]], [[1],[2],[3,4],[5,6]], [[1],[2],[3,4],[5],[6]],
 [[1],[2],[3,4,5],[6]], [[1],[2,3],[4,5,6]], [[1],[2,3],[4],[5,6]],
 [[1],[2,3],[4],[5],[6]], [[1],[2,3],[4,5],[6]], [[1],[2,3,4],[5,6]],
 [[1],[2,3,4],[5],[6]], [[1],[2,3,4,5],[6]], [[1,2],[3,4,5,6]],
 [[1,2],[3],[4,5,6]], [[1,2],[3],[4],[5,6]], [[1,2],[3],[4],[5],[6]],
 [[1,2],[3],[4,5],[6]], [[1,2],[3,4],[5,6]], [[1,2],[3,4],[5],[6]],
 [[1,2],[3,4,5],[6]], [[1,2,3],[4,5,6]], [[1,2,3],[4],[5,6]],
 [[1,2,3],[4],[5],[6]], [[1,2,3],[4,5],[6]], [[1,2,3,4],[5,6]],
 [[1,2,3,4],[5],[6]], [[1,2,3,4,5],[6]]]
                                                           Type: List Any
(12) -> [[i,#px i] for i in [[],[1],[1,2],[1,2,3],[1,2,3,4],[1,2,3,4,5,6]] ]
 (12)
[[[],1],[[1],1],[[1,2],2],[[1,2,3],4],[[1,2,3,4],8],[[1,2,3,4,5,6],32]]
                                                      Type: List List Any
(13) -> [#px(i) for i in [[],[1],[1,2],[1,2,3],[1,2,3,4],[1,2,3,4,5,6]] ]
 (13)  [1,1,2,4,8,32]
                                            Type: List NonNegativeInteger

หากนี่เป็นพื้นที่มากเกินไปบอกว่าฉันลบตัวอย่าง ...

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