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 อยู่ที่มุมซ้ายบนมันจะไม่หมุนสี่เหลี่ยมด้านซ้ายบนอีกต่อไป
หากตัวเลข 9 อยู่ที่มุมขวาล่างมันจะไม่หมุนสแควร์ล่างขวาอีกต่อไป
ขั้นตอนสำหรับการสลับตำแหน่ง 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 โดยไม่ต้องเปลี่ยนตำแหน่งขององค์ประกอบเจ็ดที่เหลือ
...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
" หรือไม่? ฉันไม่แน่ใจว่าจะอ่านยังไง