GolfScript, 39/83 byte
# 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`*
Tốc độ so với kích thước
Phiên bản tối ưu hóa kích thước sẽ chọn ngẫu nhiên các vòng quay theo chiều kim đồng hồ cho đến khi đạt được hoán vị mong muốn. Điều này là đủ, vì một vòng quay ngược chiều kim đồng hồ tương đương với ba vòng quay theo chiều kim đồng hồ liên tiếp của cùng một hình vuông.
Phiên bản tối ưu hóa tốc độ cũng làm như vậy, ngoại trừ các điều sau:
Nếu số 1 ở góc trên bên trái, nó sẽ không xoay hình vuông phía trên bên trái nữa.
Nếu số 9 ở góc dưới bên phải, nó sẽ không xoay hình vuông bên phải phía dưới nữa.
Các bước để hoán đổi vị trí 7 và 8 được mã hóa cứng, do đó, có hai vị trí cho phép vòng lặp bị phá vỡ.
Ngoài việc thay đổi thuật toán, phiên bản tối ưu hóa tốc độ đạt được sự xoay vòng một cách đơn giản, trong khi phiên bản chọn kích thước sử dụng sắp xếp tích hợp sẵn của GolfScript bằng cách ánh xạ. Nó cũng mã hóa trạng thái cuối cùng (để so sánh) thay vì sắp xếp trạng thái trong mỗi lần lặp.
Phiên bản tối ưu hóa tốc độ yêu cầu số lần lặp ít hơn và mỗi lần lặp lại nhanh hơn nhiều.
Điểm chuẩn
Tôi đã sử dụng đoạn mã sau để chọn ngẫu nhiên các vị trí của các số và thực hiện các lần chạy thử, bỏ ghi chú dòng tương ứng với phiên bản cần kiểm tra:
[{[
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: '\+
Đầu ra cho thấy số bước tối thiểu và tối đa cần thiết để sắp xếp các số, trung bình và trung bình của tất cả các lần chạy, cũng như thời gian trôi qua tính bằng giây:
$ 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
Trên máy của tôi (Intel Core i7-3770), thời gian thực hiện trung bình của phiên bản được tối ưu hóa kích thước là 3,58 phút. Thời gian thực hiện trung bình của phiên bản tối ưu hóa tốc độ là 0,20 giây. Do đó, phiên bản tối ưu hóa tốc độ nhanh hơn khoảng 1075 lần.
Phiên bản tối ưu hóa tốc độ mang lại số lần quay ít hơn 114 lần. Thực hiện mỗi vòng quay chậm hơn 9,4 lần, điều này chủ yếu là do cách thức cập nhật trạng thái.
Tôi / O
Đầu ra bao gồm các số 3 bit. MSB được đặt cho các vòng quay ngược chiều kim đồng hồ, bit giữa được đặt cho các ô vuông thấp hơn và LSB được đặt cho các ô vuông bên phải. Do đó, 0 (4) là hình vuông trên bên trái, 1 (5) bên trên bên phải, 2 (6) bên dưới bên trái và 3 (7) bên dưới bên phải.
Phiên bản tối ưu hóa tốc độ in tất cả các phép quay trên một dòng. Phiên bản tối ưu hóa kích thước in một vòng quay trên mỗi dòng, theo sau là vị trí cuối cùng của các số.
Đối với phiên bản được tối ưu hóa tốc độ, đầu vào phải tạo ra một mảng chứa các số từ 1 đến 9 khi được đánh giá. Đối với phiên bản được tối ưu hóa kích thước, đầu vào phải là một chuỗi không có dòng mới cuối cùng; nó không được đánh giá.
Ví dụ chạy:
$ echo -n '253169748' | golfscript rotation-size.gs
3
0
123456789
$ golfscript rotation-speed.gs <<< '[5 4 7 1 2 9 3 8 6]'
2210300121312212222212211121122211122221211111122211211222112230764
Mã tối ưu hóa kích thước
{ #
. # 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.
Cập nhật trạng thái đạt được theo cách sau:
Xoay 2 mang lại số nguyên 3 sau khi thêm 1. Nếu trạng thái là 123456789, cắt, trạng thái mang lại lợi ích 456789.
Ngay trước khi thực hiện, $ $, các yếu tố trên cùng của ngăn xếp là:
[ 1 2 3 4 5 6 7 8 9 ] { [ 4 5 6 7 8 9 ] ? "1420344440" = }
Một trong những phần tử của mảng được thực hiện một lần cho mỗi phần tử của mảng được sắp xếp, sau khi tự đẩy phần tử đó.
Chỉ số 1 trong Tiếng [4 5 6 7 8 9] Giáp là -1 (không có mặt), do đó, yếu tố cuối cùng của "1420344440" được đẩy. Điều này mang lại 48, mã ASCII tương ứng với ký tự 0. Trong 2 và 3, 48 cũng được đẩy.
Các số nguyên được đẩy cho 4, 5, 6, 7, 8 và 9 là 49, 52, 50, 48, 51 và 52.
Sau khi sắp xếp, phần tử đầu tiên của trạng thái sẽ là một trong những phần tử mang lại 48; cái cuối cùng sẽ là một trong những cái mang lại 52. Nói chung, loại tích hợp không ổn định, nhưng tôi đã xác minh theo kinh nghiệm rằng nó ổn định trong trường hợp cụ thể này.
Kết quả là ra [1 2 3 7 4 6 8 5 9], tương ứng với một vòng quay theo chiều kim đồng hồ của hình vuông bên trái phía dưới.
Mã tối ưu hóa tốc độ
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".
Quan sát rằng các phép quay 3, 0, 7, 6 và 4 hoán đổi các phần tử ở vị trí 7 và 8, mà không làm thay đổi vị trí của bảy phần tử còn lại.
...and return as output a sequence of moves representing the moves you must take to return the board back to its original
Điều này có nghĩa là "trở lại1 2 3\n4 5 6\n7 8 9
"? Tôi không chắc làm thế nào để đọc nó.