Scrambles Cube ของ Rubik


21

งานของคุณคือการสร้างลำดับการเคลื่อนที่แบบสุ่มซึ่งสามารถใช้ในการช่วงชิง Cube ของ Rubik ช่วงชิงดังกล่าวประกอบด้วยการเคลื่อนไหว 25 ครั้ง ย้ายแต่ละประกอบด้วยตัวอักษรตามด้วยหนึ่งคำต่อท้ายUDRLFB'2

สัญกรณ์นี้เรียกว่าสัญกรณ์ Singmaster UDRLFBแสดงถึงหนึ่งใน 6 ใบหน้าและคำต่อท้ายที่'2เป็นตัวเลือกแสดงถึงมุมเลี้ยว ข้อมูลนี้ไม่จำเป็นต้องใช้ในการแก้ปัญหา

เพื่อให้มั่นใจว่าสัญญาณรบกวนนั้นมีคุณภาพดีต้องใช้กฎสองข้อต่อไปนี้:

  • การเคลื่อนที่สองครั้งติดต่อกันจะต้องไม่มีตัวอักษรเดียวกัน นี้ห้ามการเคลื่อนไหวต่อเนื่องUU, DD, RR, LL, FFและBBและการรวมกันของพวกเขาทั้งหมดโดยใช้ตัวเลือกต่อท้ายเหมือนหรือU2UU'U'

    คู่การย้ายเหล่านี้ถูกแบนเนื่องจากสามารถลดการเคลื่อนไหวเป็น 1 หรือ 0 ได้อย่างง่ายดาย U2Uมีผลเช่นเดียวกับU', ผลเช่นเดียวกับR'R

  • การเคลื่อนไหวติดต่อกันสามครั้งจะต้องไม่อยู่ในกลุ่มตัวอักษรเดียวกัน กลุ่มตัวอักษรที่อยู่UD, และRL FBกฎนี้ยังห้ามการเคลื่อนไหวต่อเนื่องUDU, DUD, RLR, LRL, FBF, BFBและการรวมกันของพวกเขาทั้งหมดโดยใช้ตัวเลือกต่อท้ายเช่นU2DU, หรือRL'RB2FB'

    กลุ่มจัดเรียงใบหน้าตามแกนการเคลื่อนไหว UและDอยู่ในกลุ่มเดียวกันเพราะทั้งคู่หันไปรอบแกนเดียวกัน ดังนั้นการUเคลื่อนไหวจะไม่ส่งผลต่อชิ้นส่วนของDใบหน้าและการDเคลื่อนไหวจะไม่ส่งผลกระทบต่อชิ้นส่วนของUใบหน้า ดังนั้นสองย้ายสามารถแลกเปลี่ยนUDUมีผลเช่นเดียวกับและนี้สามารถลดลงได้UUDU2D

ท้าทาย

เขียนสคริปต์หรือฟังก์ชั่นที่สร้างช่วงชิงสุ่ม ไม่มีอินพุต สคริปต์ / ฟังก์ชั่นจะต้องพิมพ์ 25 การเคลื่อนไหวโดยไม่มีการแยกหรือคั่นด้วยช่องว่างหนึ่งช่องหรือส่งคืนสตริงผู้ติดต่อ

โปรแกรมของคุณจะต้องสามารถสร้างช่วงชิงได้ทุกครั้งซึ่งเป็นไปตามกฎด้านบน แน่นอนว่าสมมติว่าตัวสร้างตัวเลขสุ่มนั้นสุ่มจริงและไม่หลอกแบบสุ่ม

นี่คือรหัสกอล์ฟ รหัสที่สั้นที่สุด (นับเป็นไบต์ ) ชนะ

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

การเรียกใช้สคริปต์ / ฟังก์ชั่น 3 ครั้งควรพิมพ์ / คืนสิ่งที่ชอบ:

R'B2R2F2R2FB'R2DR2ULFB2RB'U2B'FL'BR'U'RB'
U'DBR'B2U'B'U'RUF'B'RDR2U'B'LR'B'F2D2UF2L'
BR2F'B'R'D'R'U2B'F2D2R'F2D'F'D2R2B'L2R'UB'R2L'D

หากคุณแยกการเคลื่อนไหวด้วยช่องว่างแต่ละรายการ:

R2 L' F2 U2 D' R2 L2 F L' D2 U R B D' U2 L B2 L U B2 D U2 R' D2 U'
B R D2 F U2 B' R2 F2 B' U' L' R2 B U2 R' D B' F' U2 R' B' L R D2 R2
B2 R2 U D' B R D' R L2 D2 L2 R B2 F U' F2 B2 U' F U' D F R2 U2 B'

โปรดสังเกตว่าผลลัพธ์เหล่านี้ประกอบด้วย 25 การเคลื่อนไหว แต่มีความยาวแตกต่างกันเนื่องจากคำต่อท้ายที่เป็นตัวเลือก ไม่อนุญาตให้พิมพ์ช่องว่างเมื่อใด2หรือ'ใช้เป็นคำต่อท้าย คุณจะต้องพิมพ์หรือL2UR2F'R'U2 ไม่อนุญาตL2 U R2 F' R' U2L2U R2F'R'U2


คุณหมายถึงUR 2ไม่อนุญาตหรือไม่ U R2 ฉันควรได้รับอนุญาตฉันคิดว่าเนื่องจากช่องว่างระหว่างการเคลื่อนไหวทำให้รู้สึก
mbomb007

@ mbomb007 L2U R2F'R'U2ผมหมายถึงสิ่งที่ชอบ Uไม่มีคำต่อท้ายที่เป็นตัวเลือกดังนั้นจึงไม่ควรมีช่องว่าง พื้นที่ไม่ควรแทนที่คำต่อท้ายที่เป็นทางเลือก
Jakube

เกิดอะไรขึ้นถ้ามีช่องว่างระหว่างทุกการเคลื่อนไหว เราสามารถส่งออกU F2 L D2 R'...ตัวอย่างเช่น ในกรณีนี้ไม่มีพื้นที่เพิ่มเติมซึ่งฉันคิดว่าควรจะโอเคตามกฎของคุณ
mbomb007

@ mbomb007 ใช่ฉันจะใส่ไว้ในคำอธิบาย
Jakube

ไม่ใช่ 2 ต่อหน้าตัวอักษรเหรอ? oO
Oliver Ni

คำตอบ:


6

CJam, 47 45 ไบต์

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

ลองออนไลน์

{BA^2/6,_B-?A:B-mr0=:A"UDRLFB"=3mr[L2'']=}25*

คำอธิบาย

{               "Loop...";
  BA^2/           "If the two previous moves were not from the same group, ...";
  6,              "... then produce the available move list [0 1 2 3 4 5], ...";
  _B-             "... else produce the available move list [0 1 2 3 4 5] with
                   the second previous move removed";
  ?
  A:B             "Save the previous move as the second previous move";
  -               "Remove the previous move from the available move list";
  mr0=            "Randomly select an available move";
  :A              "Save this move as the previous move";
  "UDRLFB"=       "Map this move to its character (implicitly printed)";
  3mr[L2'']=      "Randomly select a modifier (implicitly printed)";
}25*            "... 25 times";

9

C 129

f(){int i,n,m,r,s,t;for(i=26;i--;i<25&&printf("%c%c","URFDLB"[s%6],"'2"[r%3])){for(n=m,t=1;t;t=m*n==9)m=(r=rand()%15)/3+1;s+=m;}}

ลูปด้านในสร้างค่าmในช่วง1..5ซึ่งเมื่อเพิ่มเข้าsและนำโมดูโล 6 ไปแล้วทำให้แน่ใจว่าไม่มีการเคลื่อนไหวสองครั้งติดต่อกันที่ด้านข้างของคิวบ์ ค่าเก่าของmจะถูกเก็บไว้ในnและการทดสอบm*n==9ทำให้มั่นใจได้ว่าค่าm= 3 ไม่เคยถูกสร้างขึ้นสองครั้งในหนึ่งแถว (ดังนั้นใบหน้าที่ตรงข้ามไม่สามารถเลือกได้สองครั้งในหนึ่งแถว; หมายเหตุลำดับใบหน้าในสตริง)

ส่วนที่มีความสำคัญน้อยที่สุดของการrถูกนำมาใช้ในการตัดสินใจที่ต่อท้าย ( ', 2หรือ null) "'2"กับการใช้การใช้ประโยชน์ของตัวละครโมฆะในตอนท้ายของ

ลูปภายนอกวิ่ง 26 ครั้ง ครั้งแรกUไม่สามารถเลือกได้ดังนั้นprintfจะถูกระงับสำหรับการทำซ้ำครั้งแรก

โค้ด Ungolfed ในโปรแกรมทดสอบ

รหัส ungolfed ทำให้ช่องว่างระหว่างการย้ายแต่ละครั้งเพื่อความชัดเจน (รหัส golfed ไม่ได้เพื่อบันทึกหนึ่งไบต์.) นอกจากนี้รหัส golfed บันทึกเซมิโคลอนโดยการย้ายprintfภายในforวงเล็บ

f(){
  int i,n,m,r,s,t;
  for(i=26;i--;){
    for(n=m,t=1;t;t=m*n==9)m=(r=rand()%15)/3+1;
    s+=m;
    i<25&&printf("%c%c ","URFDLB"[s%6],"'2"[r%3]);
  }
}

main(){
  int j;
  srand(time(0));
  for(j=0;j<5;j++)f(), puts("");
}

เอาท์พุททั่วไป

U' B D2 B' R' L F' D2 B D2 B2 R' B2 U D2 F' R U R' L B' L R2 B2 F'
U B U B F L2 D2 B' U' L B L R' D B U' D R D' B' F2 D' B D R
L D F2 B2 R' U F B' D2 L U R' L' U2 F' R F D U2 B L' B' U L2 F'
R2 B' F2 R2 L2 F' U2 L U' B' F R' D' F2 D F' L2 U2 R' D' B2 D F R2 L'
U2 F2 B2 D' F D F R L2 U' B D2 L' R D R F2 R' F2 U2 D R' D2 L F2



4

Pyth, 65 66

ฉันไม่เคยเล่นกอล์ฟใน Pythe บางทีอาจจะเขียนโปรแกรมหนึ่งหรือสองรายการ นี่เป็นวิธีแก้ปัญหาของ@ steveverrillที่แปลเป็นPyth ยินดีต้อนรับข้อเสนอแนะการปรับปรุง

ปรับปรุง:เพิ่ม 1 ไบต์จะทำให้ scrambles Uยังเริ่มต้นด้วย บางทีโซลูชัน C นั้นอาศัยพฤติกรรมที่ไม่ได้กำหนดเพื่อให้ทำงานได้ ...

=YO6V25JZK1WK=GO15=Z/+3G3=Kq9*ZJ)~YZpd+@"URFDLB"%Y6?@"'2"%G3>2%G3k

ฉันเชื่อว่าสิ่งนี้ควรทำโดยมอบหมายน้อย แต่ก็ต้องให้ฉันปรับเปลี่ยนอัลกอริทึมเยอะ (อาจลอง)

นี่คือคำอธิบายตามรหัส C:

=YO6           s = random.choice(range(6))
V25            for i in range(25):
  JZ               n = m
  K1               t = 1
  WK               while t:
    =GO15              r = random.choice(range(15))
    =Z/+3G3            m = (r + 3) / 3
    =Kq9*ZJ            t = 9 == m * n
  )
  ~YZ              s += m
  pd               print(..., end = " ")
  +                ... + ...
  @"URFDLB"%Y6     "URFDLB"[s % 6]
  ?@"'2"%G3>2%G3k  "'2"[G % 3] if 2 > G % 3 else ""

สวิทช์ตัวแปรและY ถูกกำหนดค่าเริ่มต้นด้วย 0 ดังนั้นคุณจึงบันทึกตัวอักษร 3 ตัวแรก ZZ
Jakube

@Jakube แต่แล้วฉันต้องตั้งค่าn = m(บรรทัดคำอธิบายที่ 3) ซึ่งต้องหมายถึงn = 0ครั้งแรกซึ่งจะต้องYเป็น 0
PurkkaKoodari

Yเป็น preinitialized []กับรายการที่ว่างเปล่า และฉันไม่คิดว่าคุณค่าของnเรื่องในการทำซ้ำครั้งแรก
Jakube

Btw รหัสของคุณไม่ได้ผลิต scrambles Uที่เริ่มต้นด้วย
Jakube

@ Jakube ขอบคุณคงที่
PurkkaKoodari

4

JavaScript (ES6) 175 178 204

แก้ไขน้อยกว่า 3 ไบต์ 1 โดยการเปลี่ยนรหัสและ 2 โดยการเปลี่ยนวิธีนับไบต์ (ไม่นับF=)

รหัสเพื่อหลีกเลี่ยงการซ้ำซ้อนถูกนำมาจาก @stevemiller วิธีการจัดการกลุ่มจดหมายของเขาดีขึ้นกว่าเดิม แต่ฉันจะไม่ขโมย

โบนัส: คุณสามารถระบุจำนวนการเคลื่อนไหวได้

(n=25,R=n=>Math.random()*n|0)=>(r=>{for(N=_=>'UDRLFB'[(r-=~R(5))%6],b=N(a=N(s=''));n;~(a+b+c).search('^([UD]*|[RL]*|[FB]*)$')?0:s+=(--n,a=b,b=c)+["","'",2][R(3)])c=N()})(0)||s

น้อย golfed

(n = 25) => 
{
  R = n => Math.random()*n | 0;
  N = _ => 'UDRLFB'[(r += 1+R(5)) % 6];
  r = 0;
  b = N();
  a = N();
  for(s = '' ; n; )
     c = N(),
     ~(a+b+c).search('^([UD]*|[RL]*|[FB]*)$')
       ? 0
       : s += (--n, a=b, b=c) + ["","'",2][R(3)];
  return s
}

ทดสอบ

var F=
(n=25,R=n=>Math.random()*n|0)=>(r=>{for(N=_=>'UDRLFB'[(r-=~R(5))%6],b=N(a=N(s=''));n;~(a+b+c).search('^([UD]*|[RL]*|[FB]*)$')?0:s+=(--n,a=b,b=c)+["","'",2][R(3)])c=N()})(0)||s

function go() {
  console.log(F(+M.value))
}

go()
Moves <input type=number min=1 id=M value=25 max=999>
<button onclick='go()'>Test</button>



2

Java 8, 189 183 ไบต์

v->{for(int i=26,n,m=0,r=0,s=0,t;i-->0;){for(n=m,t=1;t>0;t=m*n==9?1:0)m=(r=(int)(Math.random()*15))/3+1;s+=m;if(i<25)System.out.print("URFDLB".charAt(s%6)+(r%3<1?"'":r%3<2?"2":""));}}

ท่าเรือ@LevelRiverSt 's คำตอบ ฉันพยายามทำบางสิ่งด้วยตัวเอง แต่มันสั้นกว่าที่ฉันมี ..

ลองออนไลน์



1

Clojure 223 ไบต์

(let[R(range)F(fn[f p c](apply concat(filter f(partition-by p c))))](apply str(map str(take 25(F(fn[p](<(count p)3))(zipmap"UDLF""1122")(F(fn[p](=(count p)1))int(for[_ R](rand-nth"UDRLFB")))))(for[_ R](rand-nth[""\'\2])))))

สิ่งนี้ขึ้นอยู่กับรูปแบบ "sequence -> partition-by -> filter -> concat" ซึ่งใช้ในการกรองลำดับใบหน้า "ผิดกฎหมาย" seq นี้จะถูกแมปกับสตริงพร้อมกับ postfix แบบสุ่ม (รวมถึงสตริงว่าง)

จุดเริ่มต้นที่ไม่ดี:

(->> (for[_(range)](rand-nth"UDRLFB"))
     (partition-by int)           ; "identity" would be the correct fn to use here
     (filter(fn[p](=(count p)1))) ; Only one identical value in partition
     (apply concat)
     (partition-by(zipmap"UDLF""1122")) ; R & B are in the implicit nil group
     (filter(fn[p](<(count p)3)))       ; Only 1 or 2 consecutive faces from a group
     (apply concat)
     (take 25))
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.