ความยาวของรอบสำหรับสับที่สมบูรณ์แบบของทุกขนาด


10

ท้าทาย

ในจำนวนรหัสที่สั้นที่สุด:

  1. คำนวณความยาวของวงจรการเปลี่ยนแปลงของการสลับที่สมบูรณ์แบบบนสำรับไพ่ทุกขนาดn (โดยที่n ≥ 2 และnเป็นคู่)
  2. เอาท์พุทตารางของทุกความยาวรอบ 2 ≤ n ≤ 1000 ( nแม้)

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

  • สับไพ่สำรับ 10 ใบ: [1,2,3,4,5,6,7,8,9,10] ↦ [1,6,2,7,3,8,4,9,5, 10]
  • สลับจากสำรับไพ่ 10 ใบ: [1,2,3,4,5,6,7,8,9,10] ↦ [6,1,7,2,8,3,9,4,10, 5]

ตัวอย่างกราฟิก

ที่นี่เราเห็นว่าการสับเปลี่ยนบนสำรับไพ่ 20 ใบมีความยาว 18 รอบ (นี่เป็นภาพประกอบเท่านั้นโซลูชันของคุณไม่จำเป็นต้องใช้วงจรการแสดงผลกราฟิก) เด็ค 52 การ์ดคลาสสิกในทางกลับกันมีความยาวรอบการสลับสับเปลี่ยนเพียง 8 ขั้นตอน (ไม่แสดง)

สลับสับเปลี่ยนสำรับไพ่ 20 ใบ

การสลับในสำรับไพ่ 20 ใบมีความยาววงรอบเพียง 6 ขั้นตอน

In-shuffle cycle สำหรับเด็ค 20 ใบ

ตัวอย่างตารางผลลัพธ์

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

2 1
4 2
6 4
8 3
10 6
12 10
14 12
16 4
18 8
20 18
22 6
24 11
26 20
28 18
30 28
32 5
34 10
36 12
38 36
40 12
...many lines omitted...
1000 36

คำถาม

  1. ดูเหมือนว่าจะมีการเชื่อมต่อใด ๆ ระหว่างอินพุตตัวเลขnและจำนวนรอบของมันเมื่อnคือพลังของ 2?
  2. แล้วเมื่อnไม่ใช่พลังของ 2 ล่ะ?
  3. สำรับไพ่ 1000 ใบมีจำนวนรอบการสับเปลี่ยนออกเพียง 36 ในขณะที่สำรับ 500 ใบมีจำนวนรอบสับเปลี่ยนออกเป็น 166 รอบเหตุใดจึงเป็นเช่นนี้
  4. อะไรคือจำนวนมากที่สุดที่คุณสามารถพบได้ซึ่งวัฏจักรนับcมีขนาดเล็กกว่าnอย่างมากมายหมายความว่าอัตราส่วนn / cถูกขยายให้ใหญ่สุด?


ใช่นั่นเป็นเรื่องเกี่ยวกับการแสดงผลลัพธ์มากกว่า คำถามนี้เกี่ยวกับการสร้างตารางสำหรับค่าใด ๆ ของn ; มันเป็นคณิตศาสตร์มากกว่าในธรรมชาติ
ทอดด์เลห์แมน

ฉันสับสนที่นั่นด้วยรอบ 6/8 ในการสาธิตในขณะที่ดี :) (ฉันคิดว่าการเลียนแบบของฉันผิด ในที่สุดฉันก็ดูภาพและเห็นว่ามันเป็นวงจร 6 ดังนั้นฉันแก้ไขมัน ตลก
ภูมิใจ haskeller

@proud haskeller - อ่าใช่แล้วขอบคุณ!
ทอดด์เลห์แมน

1
นี่คือลำดับA002326
orlp

คำตอบ:


6

Haskell, 47 46 44 (สลับกัน)

[[i|i<-[1..],mod(2^i)n<2]!!0|n<-[3,5..1001]]

ก่อให้เกิดพื้นฐานอยู่ที่นี้เป็นคำสั่งของ 2 n+1ในกลุ่มคูณของโมดูลัส


1
คุณสามารถลบl=- การแสดงออกของตัวเองก็เพียงพอแล้ว นั่นเป็นโปรแกรมที่ถูกต้องเมื่อทำงานบนบรรทัดคำสั่งแบบโต้ตอบ
orlp


2

Pyth, 22 ไบต์

V500,JyhNl{.u.iFc2NJUJ

ลองมันออนไลน์: สาธิต แทนที่ 500 ด้วยจำนวนที่น้อยกว่าหากช้าเกินไป

คำอธิบาย:

V500                     for N in [0, 1, ..., 499]:
      yhN                   (N + 1) * 2
     J                      assign to J
           .u      JUJ      apply the following expression J times
                            to N, starting with N = [0, 1, ..., J - 1],
                            and return all intermediate results:
                c2N            split N into 2 halfs
             .iF               and interleave them
         l{                 remove duplicates and give length
    ,                       make a pair and print

1
มันช่างบ้าคลั่งที่โซลูชัน pyth ที่ทำงานจริงของการสับและการนับเด็คเพียงครึ่งเดียวตราบเท่าที่โซลูชัน haskell ซึ่งใช้สูตรง่าย ๆ ทำนายผลได้ทันที
Falco

@Falco ฉันรู้ถูกต้อง
ภูมิใจ Haskeller

1
@Falco จริง ๆ แล้วฉันพยายามทำ pyth portof คำตอบของฉัน แต่ฉันไม่สามารถคิดวิธีการทำ ดังนั้นฉันจึงลงเอยด้วยการเล่นกับ pyth เป็นเวลาครึ่งชั่วโมง
ภูมิใจ haskeller

ดีใจที่คุณไม่ลอง <> <
Falco

2

Mathematica, 53 (in-shuffle)

Grid[{2#,MultiplicativeOrder[2,2#+1]}&/@Range[1,500]]

หรือไม่ใช่ระยะห่างที่เป็นปรปักษ์กัน

Grid[{2 #, MultiplicativeOrder[2, 2 # + 1]} & /@ Range[1, 501]]

เอาท์พุท:

   2    2
   4    4
   6    3
   8    6
  10   10
  12   12
  14    4
  16    8
  18   18
  20    6
 (* digits, digits, bo bidgits, banana fana, ... *)
  498  166
  500  166
 (* skip a bit, brother ...  *)
  998   36
 1000   60

ทุกรายการในคอลัมน์ทั้งสองนั้นอยู่กึ่งกลางแนวนอนในคอลัมน์ของพวกเขา แต่ฉันไม่มีช่องว่างเศษส่วน&#8194;... &#8202;ที่นี่เพื่อทำซ้ำ

ข้อสังเกต:

  • Out-shuffle เป็นการสลับแบบบนสำรับไพ่สองใบที่เล็กกว่า (โปรดทราบว่าไพ่ใบแรกและใบสุดท้ายอยู่ในตำแหน่งคงที่ตลอดการสาธิตแบบสุ่ม) ดังนั้นตัวเลือกทั้งสองจะนำไปสู่รายการเอาท์พุทที่คล้ายกัน - คอลัมน์ที่สองจะถูกเลื่อนไปหนึ่งแถว เกี่ยวกับคำใบ้ "พลังแห่งสอง" การ in-shuffle ของพลังสองชั้นมีรูปแบบ{2^n - 2, n}, {2^n, 2n}. (จับคู่แบบสุ่มออก2^nด้วยn)
  • สังเกตในตัวอย่างแบบสุ่มว่าระยะทาง2จากปลายด้านที่ใกล้ที่สุดของสำรับเป็นสองเท่าในแต่ละขั้นตอน {2, 4, 8, 15 = -5, -10, -20}. อันที่จริงนี่เป็นจริงสำหรับทุกบัตร ดังนั้นเราจึงจำเป็นต้องรู้ว่าพลังของ2ความสอดคล้องกับ1mod n+1ที่nเป็นจำนวนบัตร (โปรดทราบว่าในตัวอย่างการ์ดในคอลัมน์สุดท้ายคอลัมน์-1จะถูกเพิ่มเป็นสองเท่าของคอลัมน์ถัดไป-2ซึ่งหมายความว่า0สอดคล้องกับการ์ดมากกว่าหนึ่งการ์ดมากกว่าที่อยู่ในสำรับดังนั้น "mod n+1") ดังนั้น MultiplicativeOrder [] ฟังก์ชั่นเป็นวิธีที่จะไป (ใน Mathematica)
  • โดยค่าเริ่มต้นเราจะลองใช้ TableForm [] แทน Grid [] แต่ผลลัพธ์จะคล้ายกัน

ผลลัพธ์ตัวอย่างของคุณดูเหมือนผิด
ภูมิใจ Haskeller

@proudhaskeller: สำหรับแบบสุ่มหรือแบบสุ่ม? ทั้งที่ได้รับอนุญาต (และตามที่ระบุไว้ตัวหนึ่งเป็นเพียงการเลื่อนหนึ่งแถวในคอลัมน์ด้านขวาของอีกด้านหนึ่ง)
Eric Towers

พวกเขาทั้งคู่ดูเหมือนจะไม่พอดี ค้นหาผลลัพธ์ตัวอย่างในคำถาม บางทีตัวอย่างผลลัพธ์ของคุณผิดและรหัสจริงนั้นถูกต้องและตัวอย่างเพิ่งล้าสมัยฉันไม่รู้ แต่ดูเหมือนจะไม่พอดี
ภูมิใจ haskeller

proudhaskeller: ฉันดูเหมือนจะพิมพ์ผลลัพธ์ตัวอย่างที่ "8" และงัดเข้าและออกอย่างน้อยหนึ่งครั้ง การแก้ไข ขอบคุณที่อดทน :-)
Eric Towers

0

C, 86 (หรือ 84)

คะแนนไม่รวมช่องว่างที่ไม่จำเป็นซึ่งรวมถึงความชัดเจน

i,j,n;
main(){
  for(;n<1002;printf("%d %d\n",n,j),n+=2)
    for(i=n,j=1;i=i*2%(n+1),i-n;)j++;
}

นี่เป็นการสลับแบบสุ่มซึ่งเป็นสิ่งที่คนอื่น ๆ ชี้ให้เห็นเป็นเพียงการสับเปลี่ยนโดยนำการ์ดที่อยู่นิ่งที่ปลายทั้งสองด้านออก

เป็นแหลมออกโดยคนอื่น ๆ ในในการสับเปลี่ยนตำแหน่งของบัตรแต่ละคู่แต่ละครั้ง n+1แต่คราวนี้จะต้องดำเนินการแบบโมดูโล ฉันชอบคิดว่าตำแหน่งของการ์ดพิเศษนั้นอยู่ในตำแหน่งศูนย์ทางด้านซ้ายของตาราง (คุณสามารถคิดได้ว่านี่คือการถือไพ่ทั้งสองที่อยู่นิ่งจากการสับเปลี่ยนด้วย) เห็นได้ชัดว่าตำแหน่งของการ์ดจะต้องเป็นค่าบวกเสมอดังนั้นตำแหน่งศูนย์จะยังคงว่างเปล่าสำหรับกรณี in-shuffle

รหัส initialises ค่าของi nจากนั้นมันจะคูณด้วย 2 ใช้โมเดอร์ผลลัพธ์(n+1)และตรวจสอบว่าiได้กลับสู่ค่าเริ่มต้น ( i-nเป็นศูนย์หรือไม่) มันเพิ่มขึ้นjสำหรับการวนซ้ำแต่ละครั้งยกเว้นครั้งสุดท้าย (ดังนั้นจำเป็นต้องเริ่มต้นjที่ 1)

โดยหลักการแล้วiอาจมีค่าใด ๆ ในช่วงได้1..nตราบใดที่การเปรียบเทียบที่จุดสิ้นสุดถูกตรวจสอบว่ามันมีความสัมพันธ์กับจำนวนเดียวกัน เหตุผลในการเลือกnคือเพื่อให้แน่ใจว่าโปรแกรมใช้กับเคสn==0ได้ ปัญหาคือว่าโมดูโลหมายเลขใด ๆ(0+1)เป็นศูนย์ดังนั้นลูปไม่เคยถูกยกเลิกในกรณีนี้หากiถูกกำหนดค่าเริ่มต้นให้เป็นค่าคงที่เช่น 1

ตัวอย่างคำถามประกอบด้วยกรณีที่เทียบเท่าn==2สำหรับการสลับเพลงดังนั้นจึงตีความได้ว่าจำเป็นต้องใช้เคสนี้ ถ้ามันไม่ได้เป็นสองไบต์n,จะถูกบันทึกไว้โดยเริ่มต้นi1, jค่าเช่นเดียวกับ

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