สับกี่เท่า


18

Riffle shuffle คือ shuffle แบบหนึ่งที่แบ่งเด็คออกเป็นสองพาร์ติชั่นและพาร์ติชั่นจะรวมกันเพื่อสร้างเด็คสับแบบใหม่

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

การสลับแบบสุ่มแต่ละอันนั้นสามารถถูกมองว่าเป็นการเปลี่ยนแปลงไพ่สำรับดั้งเดิม ตัวอย่างเช่นการเปลี่ยนแปลง

1,2,3 -> 1,3,2

เป็นการสลับแบบ riffle ถ้าคุณแยกดาดฟ้าเช่นนั้น

1, 2 | 3

เราเห็นว่าการ์ดทุกใบใน1,3,2นั้นมีลำดับที่เหมือนกันกับการ์ดอื่น ๆ ในพาร์ติชั่น ยังคงเป็นหลังจากที่21

ในทางกลับกันการเรียงสับเปลี่ยนต่อไปนี้ไม่ใช่การสลับแบบ riffle

1,2,3 -> 3,2,1

เราสามารถเห็นสิ่งนี้ได้เพราะพาร์ติชั่นทั้งสอง (ไม่สำคัญ)

1, 2 | 3
1 | 2, 3 

มีคู่ของการ์ดที่ไม่รักษาลำดับญาติของพวกเขา ในพาร์ติชันแรก1และ2เปลี่ยนลำดับของพวกเขาในขณะที่พาร์ติชันที่สอง2และ3เปลี่ยนลำดับของพวกเขา

อย่างไรก็ตามเราจะเห็นว่า3, 2, 1สามารถทำได้โดยการเขียนสอง riffle shuffles

1, 3, 2 + 2, 3, 1 = 3, 2, 1

ในความเป็นจริงความจริงง่ายๆที่จะพิสูจน์คือการเรียงสับเปลี่ยนใด ๆ ที่สามารถทำให้ฉันรวมจำนวนสับเปลี่ยนสับเปลี่ยน riffle จำนวนหนึ่ง

งาน

งานของคุณคือการสร้างโปรแกรมหรือฟังก์ชั่นที่ใช้การเปลี่ยนรูป (ขนาดN ) เป็นอินพุทและเอาท์พุทจำนวนสับเปลี่ยนสับเปลี่ยนแบบ riffle จำนวนน้อยที่สุด (ขนาดN ) ที่สามารถรวมกันเป็นรูปแบบของการเปลี่ยนแปลงอินพุต คุณไม่จำเป็นต้องเอาท์พุฟ ruffle shuffles ด้วยตัวเอง

นี่คือดังนั้นคำตอบจะได้คะแนนเป็นไบต์ด้วยจำนวนไบต์ที่น้อยกว่าจะดีกว่า

คุณสามารถส่งออก 1 หรือ 0 สำหรับการเปลี่ยนแปลงตัวตน

กรณีทดสอบ

1,3,2 -> 1
3,2,1 -> 2
3,1,2,4 -> 1
2,3,4,1 -> 1
4,3,2,1 -> 2

3
ดังนั้นเราจะเห็นอัลกอริทึม RiffleSort เร็ว ๆ นี้หรือไม่
mbomb007

ไม่ควร4,3,2,1จะเป็น2? ก่อนอื่นเราแบ่งตรงกลางและได้กำไร3,1,4,2จากนั้นเราแยกกลางอีกครั้งและใช้การเรียงสับเปลี่ยนแบบเดียวกัน
Halvard Hummel

@ HalvardHummel นั่นถูกต้องแล้ว ฉันจะต้องพบปัญหาเกี่ยวกับการใช้งานอ้างอิงของฉัน
ตัวช่วยสร้างข้าวสาลี

คำตอบ:


2

Python 3 , 255 ไบต์

ตรวจสอบ riffles ที่เป็นไปได้ทั้งหมดจนถึงความยาวของรายการ (ต้องการจำนวนสูงสุด) ดังนั้นจึงช้ามากสำหรับอินพุตที่ใหญ่ขึ้น อาจจะเล่นกอล์ฟสักหน่อย

lambda x:f(range(1,len(x)+1),x)
f=lambda x,y,i=0:x==y and i or i<len(x)and min(f(q,y,i+1)for a in range(1,len(x))for q in g(x[:a],x[a:]))or i
g=lambda x,y:(x or y)and[[v]+q for v in x[:1]for q in g(x[1:],y)]+[[v]+q for v in y[:1]for q in g(x,y[1:])]or[[]]

ลองออนไลน์!


2

ทำความสะอาด , 206 ... 185 ไบต์

import StdEnv
f=flatten
$a b#[c:d]=b
|a>[]#[u:v]=a
=[a++b,b++a:f[[[u,c:e],[c,u:e]]\\e<- $v d]]=[b]
@l#i=length l
=hd[n\\n<-[0..],e<-iter n(f o map(uncurry$o splitAt(i/2)))[[1..i]]|l==e]

ลองออนไลน์!

สร้างผลลัพธ์ที่เป็นไปได้ทุกครั้งของการสับเปลี่ยนnและตรวจสอบว่ารายการนั้นเป็นสมาชิกหรือไม่
ในขณะที่นี่เป็นวิธีที่ไม่มีประสิทธิภาพอย่างน่ากลัวในการแก้ปัญหารหัสนี้ช้าโดยเฉพาะอย่างยิ่งเนื่องจากการใช้รายการความเข้าใจแทนองค์ประกอบที่ จำกัด การลดกราฟเบื้องต้นอย่างมากและผลลัพธ์ในการแสดงที่น่าประทับใจของตัวเก็บขยะของ Clean

Ungolfed:

import StdEnv
shuffle [] l
    = [l]
shuffle [a: b] [c: d]
    = [[a: b]++[c: d], [c: d]++[a: b]: flatten [
        [[a, c: e], [c, a: e]]
        \\ e <- shuffle b d
        ]]
numReq l
    = until cond ((+)1) 0
where
    cond n 
        = let
            mapper
                = map (uncurry shuffle o splitAt (length l/2))
            options
                = iter n (removeDup o flatten o mapper) [[1..length l]]
        in isMember l options

ลองออนไลน์!

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