# 解决旋转难题

14

``````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
``````

`...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

@JoeZ。我建议对其进行修改，以声明解决方案必须具有有限的最坏情况性能。
HostileFork说不要信任2014年

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`*
``````

### 速度与大小

1. 如果数字1位于左上角，则不会再旋转左上角的正方形。

2. 如果数字9位于右下角，则不会再旋转右下角的正方形。

3. 交换位置7和8的步骤是硬编码的，因此有两个位置允许循环中断。

### 基准测试

``````[{[
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
``````

### 输入输出

``````\$ 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.
``````

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

“ [4 5 6 7 8 9]”中的索引1为-1（不存在），因此将压入最后一个元素“ 1420344440”。这将产生48，即与字符0相对应的ASCII码。对于2和3，也会推入48。

### 速度优化的代码

``````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".
``````

ɐɔıʇǝɥʇuʎs

1
@Synthetica：不过，这是迄今为止发布的最快的解决方案。

4

# 带有Numpy的Python – 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]])``

• `t`： 最佳
• `b`：底部
• `l`： 剩下
• `r`： 对
• `c`： 顺时针
• `w`：逆时针（widdershins）

¹9！是配置的总数。

2

Joe Z.

@JoeZ .：查看对我的帖子所做的编辑。
Wrzlprmft

4

# C ++最少移动解决方案-广度优先（1847个字符）

``````#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;}
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}};
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;
}
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

user12205

@ace，确实是正确的。
DreamWarrior 2014年

@Dennis，对不起，我已经用两个截然不同的g ++编译器对其进行了编译，但似乎都没有。但是，我可以看到更新，更严格的版本会发出怎样的抱怨。谢谢。
DreamWarrior 2014年

1

# 果酱-39

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

`4mr`生成一个从0到3的随机数，
`_1>+`如果它大于1，则递增该数字（所以我们
`m<`以0、1、3 或4结尾-4个块的起始索引）将字符串向左旋转（例如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个字符

``````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`：逆时针左下