แก้ปริศนาการหมุน


14

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

ในเกมนี้คุณจะเริ่มด้วยบอร์ดเช่นนี้:

4 9 2
3 5 7
8 1 6

และโดยการหมุนบล็อกซ้ายล่างสองครั้งตามเข็มนาฬิกาและบล็อกบนซ้ายตามเข็มนาฬิกาคุณจะได้:

4 9 2
8 3 7
1 5 6

4 9 2
1 8 7
3 5 6

1 4 2
8 9 7
3 5 6

และ1กระเบื้องจะอยู่ที่มุมซ้ายบนซึ่งควรจะเป็น ในที่สุดหลังจากการเคลื่อนไหวอีกสองสามครั้งคุณจะพบกับ:

1 2 3
4 5 6
7 8 9

ซึ่งเป็นการกำหนดค่า "ดั้งเดิม"

งานของคุณคือการสร้างโปรแกรมที่จะป้อนตัวเลข 3x3 กริดจาก 1 ถึง 9 (ในรูปแบบใด ๆ ที่คุณเลือก) และกลับมาเป็นเอาท์พุตลำดับของการเคลื่อนไหวที่เป็นตัวแทนของการเคลื่อนไหวที่คุณต้องใช้เพื่อคืนบอร์ดกลับไปเป็นแบบดั้งเดิม การกำหนดค่า (อีกครั้งในรูปแบบที่คุณเลือก) การเคลื่อนไหวทางกฎหมายนั้นหมายถึงการย้ายบล็อก [บน / ล่าง] - [ซ้าย / ขวา] ของ 4 แผ่น [เข็มนาฬิกา / ทวนเข็มนาฬิกา]

โปรแกรมของคุณจะต้องสามารถแก้กริด 3x3 ที่เป็นไปได้ทั้งหมด (การเปลี่ยนลำดับทั้งหมดสามารถแก้ไขได้)

รหัสที่สั้นที่สุดในการทำเช่นนี้ชนะ


...and return as output a sequence of moves representing the moves you must take to return the board back to its originalนี่หมายถึง "ย้อนกลับไปที่1 2 3\n4 5 6\n7 8 9" หรือไม่? ฉันไม่แน่ใจว่าจะอ่านยังไง
undergroundmonorail

ใช่ฉันหมายถึง 1 2 3 4 5 6 7 8 9.
Joe Z.

1
ฉันคิดว่าบอร์ดที่สองและสามในตัวอย่างของคุณควรมีการสลับ 3 และ 5
Martin Ender

@JoeZ ฉันขอแนะนำให้แก้ไขเพื่อประกาศว่าโซลูชันต้องมีประสิทธิภาพของตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ที่สุด
HostileFork พูดว่าอย่าเชื่อถือ SE

คำตอบ:


7

GolfScript ขนาด 39/83 ไบต์

# Optimized for size:

{.4rand.p.2/+>`{?1420344440`=}+$..$>}do

# Optimized for speed:

6,(7++:t;~{.(1=.@7=9=+4\-rand+..2/+@.@>:s^[3s=0s=2s=4s=1s=]+s|.)9<\t>|}do.$>30764`*

ความเร็วเทียบกับขนาด

รุ่นที่ปรับขนาดแล้วจะสุ่มเลือกการหมุนตามเข็มนาฬิกาจนสามารถเปลี่ยนรูปแบบตามต้องการได้ นี่ก็เพียงพอแล้วเนื่องจากการหมุนทวนเข็มนาฬิกาเท่ากับการหมุนตามเข็มนาฬิกา 3 ครั้งติดต่อกันของจตุรัสเดียวกัน

รุ่นที่ปรับความเร็วได้ทำเช่นเดียวกันยกเว้นสำหรับสิ่งต่อไปนี้:

  1. หากหมายเลข 1 อยู่ที่มุมซ้ายบนมันจะไม่หมุนสี่เหลี่ยมด้านซ้ายบนอีกต่อไป

  2. หากตัวเลข 9 อยู่ที่มุมขวาล่างมันจะไม่หมุนสแควร์ล่างขวาอีกต่อไป

  3. ขั้นตอนสำหรับการสลับตำแหน่ง 7 และ 8 นั้นฮาร์ดโค้ดดังนั้นจึงมีสองตำแหน่งที่อนุญาตให้ลูปแตก

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

รุ่นที่ปรับความเร็วได้นั้นต้องการการวนซ้ำน้อยลงและการวนซ้ำทุกครั้งจะเร็วกว่ามาก

มาตรฐาน

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

[{[
    0:c;10,1>{;2 32?rand}$
    #{c):c;.4rand.2/+>`{?1420344440`=}+$..$>}do
    #6,(7++:t;{.(1=.@7=9=+4\-rand+..2/+@.@>:s^[3s=0s=2s=4s=1s=]+s|.)9<\t>|}do.$>30764`*
],c+}\~*]

$.0='Min: '\+puts .-1='Max: '\+puts ..{+}*\,/'Avg: '\+puts .,2/='Med: '\+

ผลลัพธ์แสดงขั้นตอนต่ำสุดและสูงสุดของขั้นตอนในการสั่งซื้อตัวเลขค่าเฉลี่ยและค่ามัธยฐานของการวิ่งทั้งหมดรวมถึงเวลาที่ผ่านไปในไม่กี่วินาที:

$ TIME='\n%e s' time golfscript rotation-test-size.gs <<< 100
Min: 4652
Max: 2187030
Avg: 346668
Med: 216888

21500.10 s
$
$ TIME='\n%e s' time golfscript rotation-test-speed.gs <<< 1000
Min: 26
Max: 23963
Avg: 3036
Med: 2150

202.62 s

บนเครื่องของฉัน (Intel Core i7-3770) เวลาดำเนินการเฉลี่ยของรุ่นที่ปรับขนาดนั้นคือ 3.58 นาที เวลาดำเนินการเฉลี่ยของรุ่นที่ปรับความเร็วเพิ่มขึ้นคือ 0.20 วินาที ดังนั้นรุ่นที่ปรับความเร็วได้เร็วขึ้นประมาณ 1075 เท่า

รุ่นที่ปรับความเร็วได้ผลตอบแทน 114 เท่า การทำการหมุนแต่ละครั้งจะช้าลง 9.4 เท่าซึ่งส่วนใหญ่เป็นผลมาจากวิธีการอัพเดทสถานะ

I / O

ผลลัพธ์ประกอบด้วยตัวเลข 3 บิต MSB ถูกตั้งค่าสำหรับการหมุนทวนเข็มนาฬิกาบิตกลางจะถูกตั้งค่าสำหรับสี่เหลี่ยมที่ต่ำกว่าและ LSB ถูกตั้งค่าสำหรับสี่เหลี่ยมที่ถูกต้อง ดังนั้น 0 (4) คือจตุรัสซ้ายบน, 1 (5) หนึ่งขวาบน, 2 (6) ซ้ายล่างและ 3 (7) ขวาล่างหนึ่ง

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

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

ตัวอย่างการทำงาน:

$ echo -n '253169748' | golfscript rotation-size.gs
3
0
123456789
$ golfscript rotation-speed.gs <<< '[5 4 7 1 2 9 3 8 6]'
2210300121312212222212211121122211122221211111122211211222112230764

รหัสที่ปรับขนาดได้

{               #
  .             # Duplicate the state.
  4rand         # Push a randomly chosen integers between 0 and 3.
  .p            # Print that integer.
  .2/+          # Add 1 to it if it is grater than one. Possible results: 0, 1, 3, 4
  >`            # Slice the state at the above index.
  {             # Push a code block doing the following:
    ?           # Get the index of the element of the iteration in the sliced state.
    1420344440` # Push the string "14020344440".
    =           # Retrieve the element at the position of the computed index.
  }+            # Concatenate the code block with the sliced state.
  $             # Sort the state according to the above code block. See below.
  ..$>          # Push two copies of the state, sort the second and compare the arrays.
}do             # If the state is not sorted, repeat the loop.

การอัพเดตสถานะทำได้ในลักษณะต่อไปนี้:

การหมุน 2 ให้ผลเป็นจำนวนเต็ม 3 หลังจากเพิ่ม 1 ถ้าสถานะเป็น“ 123456789” การแบ่งสถานะให้ผลเป็น“ 456789”

ก่อนดำเนินการ“ $” องค์ประกอบสูงสุดของสแต็กคือ:

[ 1 2 3 4 5 6 7 8 9 ] { [ 4 5 6 7 8 9 ] ? "1420344440" = }

“ $” ดำเนินการบล็อกหนึ่งครั้งสำหรับทุกองค์ประกอบของอาร์เรย์ที่จะเรียงลำดับหลังจากกดองค์ประกอบเอง

ดัชนี 1 ใน“ [4 5 6 7 8 9]” คือ -1 (ไม่มีอยู่) ดังนั้นองค์ประกอบสุดท้ายของ "1420344440" จึงถูกผลัก สิ่งนี้ให้ผล 48, รหัส ASCII ที่สอดคล้องกับตัวละคร 0 สำหรับ 2 และ 3, 48 ได้รับการผลักเช่นกัน

จำนวนเต็มผลักสำหรับ 4, 5, 6, 7, 8 และ 9 คือ 49, 52, 50, 48, 51 และ 52

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

ผลลัพธ์คือ“ [1 2 3 7 4 6 8 5 9]” ซึ่งสอดคล้องกับการหมุนตามเข็มนาฬิกาของจัตุรัสด้านซ้ายล่าง

รหัสที่ปรับปรุงความเร็ว

6,(7++:t;       # Save [ 1 2 3 4 5 7 ] in variable “t” and discard it.
~               # Interpret the input string.
{               #
  :s            # Duplicate the current state.
  (1=           # Unshift the first element and push 1 if it is equal to 1 and 0 otherwise.
  .@            # Duplicate the boolean and rotate the unshifted array on top of it.
  7=9=          # Push 1 if the eighth element of “s” is equal to 9 and 0 otherwise.
  +4\-          # Add the booleans and subtract their sum from 4.
  rand          # Push a randomly chosen integers between 0 and the result from above.
  +.            # Add this integer to the first boolean and duplicate it for the output.
  .2/+          # Add 1 to the result if it is grater than one. Possible results: 0, 1, 3, 4
  @.            # Rotate the state on top of the stack and duplicate it.
  @>:s          # Slice the state at the integer from above and save the result in “s”.
  ^             # Compute the symmetric difference of state and sliced state.
  [             # Apply a clockwise rotation to the sliced array:
    3s=         # The fourth element becomes the first.
    0s=         # The first element becomes the second.
    2s=         # The third element remains the same.
    4s=         # The fifth element becomes the fourth.
    1s=         # The second element becomes the fifth.
  ]             # Collect the results into an array.
  +             # Concatenate with array of elements preceding the slice.
  s|            # Perform set union to add the remaining elements of “s”.
  .             # Duplicate the updated state.
  )9<           # Pop the last element; push 0 if it is equal to 9 and 1 otherwise.
  \t            # Swap the popped state on top and push [ 1 2 3 4 5 7 ].
  >             # Push 0 if the state begins with [ 1 2 3 4 5 6 ] and 1 otherwise.
  |             # Take the logical OR of the booleans.
}do             # If the resulting boolean is 1, repeat the loop.
.$              # Duplicate the state and sort it.
>30764`*        # If the state was not sorted, 7 and 8 are swapped, so push "30764".

สังเกตว่าการหมุน 3, 0, 7, 6 และ 4 สลับองค์ประกอบในตำแหน่งที่ 7 และ 8 โดยไม่ต้องเปลี่ยนตำแหน่งขององค์ประกอบเจ็ดที่เหลือ


เหมาะสำหรับความเร็วหรือไม่ มัน Golfscript ...
ɐɔıʇǝɥʇuʎs

1
@Synthetica: อย่างไรก็ตามมันเป็นทางออกที่เร็วที่สุดที่โพสต์ไปแล้ว
เดนนิส

4

Python กับ Numpy - 158

from numpy import*
A=input()
while any(A.flat>range(1,10)):i,j,k=random.randint(0,2,3);A[i:i+2,j:j+2]=rot90(A[i:i+2,j:j+2],1+2*k);print"tb"[i]+"lr"[j]+"wc"[k]

อินพุตต้องอยู่ในรูปแบบต่อไปนี้:

array([[1,2,5],[4,3,6],[7,8,9]])

แต่ละบรรทัดเอาต์พุตคือการย้ายที่เข้ารหัสในสตริงเช่นtrwหรือblcและต้องอ่านดังนี้:

  • t: ด้านบน
  • b: ด้านล่าง
  • l: ซ้าย
  • r: ใช่
  • c: ตามเข็มนาฬิกา
  • w: ทวนเข็มนาฬิกา (Widdershins)

โปรแกรมนี้ทำการเคลื่อนที่แบบสุ่มจนกว่าจะถึงการกำหนดค่าเป้าหมาย ภายใต้สมมติฐานโดยประมาณที่ทุกการเคลื่อนไหวมีความน่าจะเป็นอิสระที่ 1/9! ในการเข้าสู่การกำหนดค่าเป้าหมาย¹จำนวนการหมุนก่อนที่จะมีการแจกแจงแบบเลขชี้กำลังด้วยค่าเฉลี่ย (เช่นจำนวนการเคลื่อนที่เฉลี่ย) เท่ากับ 9! ≈ 3.6 ·10⁵ สิ่งนี้สอดคล้องกับการทดสอบสั้น ๆ (20 รอบ)

¹ 9! เป็นจำนวนการกำหนดค่าทั้งหมด


2
ดังนั้นโดยพื้นฐานแล้วมันจะพยายามเคลื่อนที่แบบสุ่มจนกว่าจะได้ทางออกหรือไม่
Joe Z.

ได้ผลสำหรับฉัน แม้ว่าฉันจะสนใจจำนวนการหมุนที่คาดไว้ก่อนที่จะถึงวิธีแก้ปัญหา
Joe Z.

@JoeZ: ดูการแก้ไขโพสต์ของฉัน
Wrzlprmft

ที่น่ากลัว.
Kyle Kanos

4

การแก้ปัญหาการเคลื่อนไหวน้อยที่สุด C ++ - ความกว้างก่อน (1847 ตัวอักษร)

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

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

ตอนนี้มันเป็นการค้นหาความกว้างอย่างง่าย ๆ ในสถานะกระดานต่าง ๆ นอกจากนี้ปรากฎว่าฉันต้องการเปลี่ยนชุดคีย์ (ปัจจุบันถูกเก็บไว้เป็นชุดตัวเลขในฐาน -9 ซึ่งแต่ละชุดคำนวณโดย BS :: key เป็นฐานการแสดง 9 ของบอร์ด) เป็นบิตเซ็ต มี 9! บิตดูเหมือนจะไม่มีความจำเป็น; แม้ว่าฉันจะหาวิธีการคำนวณคีย์ใน "ระบบตัวเลขแฟคทอเรียล" ซึ่งสามารถใช้ในการคำนวณบิตในบิตเซ็ตเพื่อทดสอบ / สลับ

ดังนั้นทางออกใหม่ล่าสุดคือ:

#include <iostream>
#include <list>
#include <set>
#include <vector>
using namespace std;
struct BS{
#define LPB(i) for(int*i=b;i-b<9;i++)
struct ROP{int t, d;};
typedef vector<ROP> SV;
typedef unsigned int KEY;
typedef set<KEY> KH;
BS(const int*d){const int*x=d;int*y=b;for(;x-d<9;x++,y++)*y=*x;}
BS(){LPB(i)*i=i-b+1;}
bool solved(){LPB(i)if(i-b+1!=*i)return 0;return 1;}
void rot(int t, int d){return rot((ROP){t,d});}
void rot(ROP r){rotb(r);s.push_back(r);}
bool undo(){if (s.empty())return false;ROP &u=s.back();u.d*=-1;rotb(u);s.pop_back();return true;}
SV &sol(){return s;}
KEY key(){KEY rv=0;LPB(i){rv*=9;rv+=*i-1;}return rv;}
int b[9];
SV s;
void rotb(ROP r){int c=r.t<2?r.t:r.t+1;int bi=(r.d>0?3:4)+c;const int*ri=r.d>0?(const int[]){0,1,4}:(const int[]){1,0,3};for(int i=0;i<3;i++)swap(b[bi],b[c+ri[i]]);}
};
ostream &operator<<(ostream &o, BS::ROP r){static const char *s[]={"tl","tr","bl","br"};o<<s[r.t]<<(r.d<0?"w":"c");return o;}
struct DKH{
~DKH(){for(HV::iterator i=h.begin();i<h.end();++i)if(*i!=NULL)delete *i;}
void add(int d,BS b){h.resize(d+1);if(h[d]==NULL)h[d]=new BS::KH();h[d]->insert(b.key());}
bool exists(BS &b){BS::KEY k=b.key();size_t d=min(b.sol().size(),h.size()-1);do if (h[d]->find(k)!=h[d]->end())return true;while(d--!=0);return false;}
typedef vector<BS::KH *> HV;HV h;
};
static bool solve(BS &b)
{
const BS::ROP v[8]={{0,-1},{0,1},{1,-1},{1,1},{2,-1},{2,1},{3,-1},{3,1}};
DKH h;h.add(0,b);
list<BS> q;q.push_back(b);
while (!q.empty())
{
BS qb=q.front();q.pop_front();
if (qb.solved()){b=qb;return true;}
int d=qb.sol().size()+1;
for (int m=0;m<8;++m){qb.rot(v[m]);if (!h.exists(qb)){h.add(d,qb);q.push_back(qb);}qb.undo();}
}
return false;
}
int main()
{
BS b((const int[]){4,9,2,3,5,7,8,1,6});
if (solve(b)){BS::SV s=b.sol();for(BS::SV::iterator i=s.begin();i!=s.end();++i)cout<<*i<<" ";cout<<endl;}
}

1
รหัสของคุณดูเหมือน C ++ แทน C
user12205

@ace แน่นอนมันถูกแก้ไข
DreamWarrior

ในกรณีที่คนอื่นมีปัญหานี้กับการรวบรวมกรัม ++ ผมต้องเปลี่ยนทุกกรณีint[]ไปและตั้งธงconst int[] -fpermissive
เดนนิส

@Dennis, ขออภัยเกี่ยวกับเรื่องนั้นฉันได้รวบรวมมันด้วยคอมไพเลอร์ g ++ สองอันที่แตกต่างกันและดูเหมือนจะไม่สนใจ แต่ฉันสามารถดูว่ารุ่นที่ใหม่กว่าเข้มงวดกว่าจะสะอื้นอย่างไร ขอบคุณ
DreamWarrior

รวบรวมได้ดีและเร็วขึ้นมาก การจัดการกับความคิดเห็นที่คุณลบออกจากคำถาม: มีการเปลี่ยนลำดับบางอย่างที่ดูเหมือนว่าต้องใช้ 11 ขั้นตอน 978654321 เป็นหนึ่งในนั้น
Dennis

1

CJam - 39

l{4mr_o_1>+_@m<_[Z0Y4X]\f=\5>+m>__$>}g;

อีกหนึ่งตัวแก้ปัญหาแบบสุ่ม :)
มันต้องใช้สตริงเช่น 492357816 และส่งออกชุดของตัวเลข (ยาว) จาก 0 ถึง 3 โดยแต่ละอันแทนการหมุนตามเข็มนาฬิกาของบล็อก: 0 = ซ้ายบน, 1 = บนขวา, 2 = ล่าง ซ้าย 3 = ล่างขวา

คำอธิบายสั้น ๆ :

4mrสร้างตัวเลขสุ่มจาก 0 ถึง 3
_1>+เพิ่มจำนวนถ้ามันมากกว่า 1 (ดังนั้นเราจบลงด้วย 0, 1, 3 หรือ 4 - ดัชนีเริ่มต้นของ 4 บล็อก)
m<หมุนสตริงไปทางซ้าย (เช่น 492357816 -> 923578164 ไม่ใช่การหมุนบล็อก) เพื่อให้บล็อกหมุนในตำแหน่งแรก
[Z0Y4X]\f=การหมุนบล็อกซึ่งมีผลต่อตัวอักษร 5 ตัวแรกเช่น 12345 -> 41352;
X = 1, Y = 2, Z = 3 ดังนั้น [Z0Y4X] จึงเป็นจริง [3 0 2 4 1] และนั่นคือดัชนีที่อิง 0 ของแผ่นกระเบื้องที่หมุนแล้ว
5>คัดลอกส่วนที่เหลือของสตริง
m>จะหมุนสตริง(แก้ไข) กลับไปเป็น การ
__$>ตรวจสอบที่ถูกต้องว่าสตริงถูกเรียงลำดับ (เป็นเงื่อนไขการหยุด)


1

Mathematica 104 ตัวอักษร

เราสามารถตีความงานในภาษาของกลุ่มเรียงสับเปลี่ยน การหมุนสี่ครั้งเป็นเพียงการเรียงสับเปลี่ยนสี่ครั้งที่สร้างกลุ่มสมมาตร S 9และงานนี้เพียงแค่เขียนการเรียงสับเปลี่ยนเป็นผลิตภัณฑ์ของเครื่องกำเนิดไฟฟ้า Mathematica มีฟังก์ชันในตัวเพื่อทำสิ่งนี้

i={1,2,5,4};GroupElementToWord[PermutationGroup[Cycles/@({i}+#&/@i-1)],Input[]~FindPermutation~Range@9]

ตัวอย่าง:

การป้อนข้อมูล:

{4, 9, 2, 8, 3, 7, 1, 5, 6}

เอาท์พุท:

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