Problem:
Problem C:
Cubic Eight-Puzzle
Let's play a puzzle using eight cubes placed on a 3 × 3 board leaving one empty square.
Faces of cubes are painted with three colors. As a puzzle step, you can roll one of the cubes to
the adjacent empty square. Your goal is to make the specified color pattern visible from above
by a number of such steps.
The rules of this puzzle are as follows.
Coloring of Cubes:
All the cubes are colored in the same way as shown in Figure 3.
The opposite faces have the same color.
Figure 3: Coloring of a cube
Initial Board State:
Eight cubes are placed on the 3 × 3 board leaving one empty square.
All the cubes have the same orientation as shown in Figure 4. As shown in the figure,
squares on the board are given
x
and
y
coordinates, (1, 1), (1, 2), .. ., and (3, 3). The
position of the initially empty square may vary.
Figure 4: Initial board state
Rolling Cubes:
At each step, we can choose one of the cubes adjacent to the empty square and roll it into the empty square, leaving the original position empty. Figure 5
shows an example.
Figure 5: Rolling a cube
Goal:
The goal of this puzzle is to arrange the cubes so that their top faces form the
specified color pattern by a number of cube rolling steps described above.
Your task is to write a program that finds the minimum number of steps required to make the
specified color pattern from the given initial state.
Input
The input is a sequence of datasets. The end of the input is indicated by a line containing two
zeros separated by a space. The number of datasets is less than 16. Each dataset is formatted
as follows.
x y
F
11
F
21
F
31
F
12
F
22
F
32
F
13
F
23
F
33
The first line contains two integers
x
and
y
separated by a space, indicating the position (
x
,
y
)
of the initially empty square. The values of
x
and
y
are 1, 2, or 3.
The following three lines specify the color pattern to make. Each line contains three characters
F
1
j
,
F
2
j
, and
F
3
j
, separated by a space. Character
F
ij
indicates the top color of the cube, if any, at position (
i
,
j
) as follows:
B: Blue
       W: White
       R: Red
       E: the square is Empty.
There is exactly one '
E
' character in each dataset.
Output
For each dataset, output the minimum number of steps to achieve the goal, when the goal can
be reached within 30 steps. Otherwise, output "
-1
" for the dataset.
Sample Input
1 2
W W W
E W W
W W W
2 1
R B W
R W W
E W W
3 3
W B W
B R E
R B R
3 3
B W R
B W R
B E R
2 1
B B B
B R B
B R E
1 1
R R R
W W W
R R E
2 1
R R R
B W B
R R E
3 2
R R R
W E W
R R R
0 0
Output for the Sample Input
0
3
13
23
29
30
-1
-1

Submitted solutions:

code_snippet: #include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int n=3;
const int dx[]={-1,1,0,0},dy[]={0,0,-1,1};
int fx,fy,t[4][4],ans;
struct node{
	int x,y;
	node(int x=0,int y=0):x(x),y(y){}
}a[4][4];
int nextstep(){	
	int tot=0;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			if(a[i][j].x!=t[i][j])
				tot++;return tot;
}
void update(int x,int y,int d){
	int nx=x+dx[d],ny=y+dy[d];
	if(d<2)swap(a[x][y].x,a[x][y].y);
	else a[x][y].x=6-a[x][y].x-a[x][y].y;
	swap(a[x][y],a[nx][ny]);
}
void dfs(int cnt,int x,int y){
	int s=nextstep();
	if(!s){ans=min(ans,cnt);return;}
	if(cnt+s>=ans)return;
	int nowx,nowy;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			if(!a[i][j].x)nowx=i,nowy=j;
	for(int i=0;i<4;i++){
		int nx=nowx+dx[i],ny=nowy+dy[i];
		if(nx<1||nx>n||ny<1||ny>n||(nx==x&&ny==y))continue;
		update(nx,ny,i^1);dfs(cnt+1,nowx,nowy);update(nowx,nowy,i);
	}
}
int main(){
	while(scanf("%d%d",&fy,&fx)&&fx&&fy){
		memset(a,0,sizeof(a));
		memset(t,0,sizeof(t));
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)a[i][j]=node(1,2);
		a[fx][fy]=node(0,0);
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++){
				char c;cin>>c;
				if(c=='W')t[i][j]=1;
				if(c=='R')t[i][j]=2;
				if(c=='B')t[i][j]=3;
			}
		ans=32;dfs(0,0,0);
		if(ans>30)ans=-1;
		printf("%d\n",ans);
	}
	return 0;
}
accuracy: 1
time_ms: 710
memory_kb: 3464
final_rank: 6

code_snippet: #include <bits/stdc++.h>
#define ll int
#define F first
#define S second
#define N 1679636
using namespace std;
ll trs[6][2]={{2,5},{4,3},{0,4},{5,1},{1,2},{3,0}},pw6[]={1,6,36,216,1296,7776,46656,279936,1679616};
ll f[N][3][3],q=0,ans[20];
char qry[20][3][3];
vector<ll> qs[3][3];
queue<pair<ll,pair<ll,ll> > > qu;
void print(ll mask,ll x,ll y)
{
	ll i;
	for(i=0;i<9;i++)
	{
		if(i==x*3+y)
		{
			putchar('X');
		}
		else
		{
			cout<<mask%6;
			mask/=6;
		}
	}
	assert(mask==0);
	return;
}
void solve(ll sx,ll sy)
{
	ll i,j,k,mask;
	memset(f,63,sizeof(f));
	f[0][sx][sy]=0;
	while(!qu.empty())
	{
		qu.pop();
	}
	qu.push(make_pair(0,make_pair(sx,sy)));
	while(!qu.empty())
	{
		ll st=qu.front().F,x=qu.front().S.F,y=qu.front().S.S;
		qu.pop();
		if(f[st][x][y]>=30)
		{
			break;
		}
		ll tx,ty;
		tx=x-1,ty=y;
		if(tx>=0)
		{
			ll nst=st%pw6[tx*3+ty]+((st%pw6[x*3+y])/pw6[tx*3+ty+1])*pw6[tx*3+ty];
			nst+=pw6[x*3+y-1]*trs[(st/pw6[tx*3+ty])%6][0]+(st/pw6[x*3+y])*pw6[x*3+y];
			if(f[nst][tx][ty]>f[st][x][y]+1)
			{
				f[nst][tx][ty]=f[st][x][y]+1;
				qu.push(make_pair(nst,make_pair(tx,ty)));
			}
		}
		tx=x,ty=y+1;
		if(ty<3)
		{
			ll nst=st%pw6[x*3+y]+pw6[x*3+y]*trs[(st/pw6[x*3+y])%6][1]+(st/pw6[tx*3+ty])*pw6[tx*3+ty];
			if(f[nst][tx][ty]>f[st][x][y]+1)
			{
				f[nst][tx][ty]=f[st][x][y]+1;
				qu.push(make_pair(nst,make_pair(tx,ty)));
			}
		}
		tx=x+1,ty=y;
		if(tx<3)
		{
			ll nst=st%pw6[x*3+y]+pw6[x*3+y]*trs[(st/pw6[tx*3+ty-1])%6][0];
			nst+=((st%pw6[tx*3+ty-1])/pw6[x*3+y])*pw6[x*3+y+1]+(st/pw6[tx*3+ty])*pw6[tx*3+ty];
			if(f[nst][tx][ty]>f[st][x][y]+1)
			{
				f[nst][tx][ty]=f[st][x][y]+1;
				qu.push(make_pair(nst,make_pair(tx,ty)));
			}
		}
		tx=x,ty=y-1;
		if(ty>=0)
		{
			ll nst=st%pw6[tx*3+ty]+pw6[x*3+y-1]*trs[(st/pw6[tx*3+ty])%6][1]+(st/pw6[x*3+y])*pw6[x*3+y];
			if(f[nst][tx][ty]>f[st][x][y]+1)
			{
				f[nst][tx][ty]=f[st][x][y]+1;
				qu.push(make_pair(nst,make_pair(tx,ty)));
			}
		}
	}
	for(i=0;i<qs[sx][sy].size();i++)
	{
		ll x,y,id=qs[sx][sy][i];
		ans[id]=40;
		for(mask=0;mask<(1<<8);mask++)
		{
			ll cur=0,cnt=0;
			for(j=2;j>=0;j--)
			{
				for(k=2;k>=0;k--)
				{
					if(qry[id][j][k]=='E')
					{
						x=j,y=k;
						continue;
					}
					cur=cur*6+((mask>>cnt)&1)+(qry[id][j][k]=='W'?0:(qry[id][j][k]=='R'?2:4));
					cnt++;
				}
			}
			ans[id]=min(ans[id],f[cur][x][y]);
		}
	}
	return;
}
int main(){
	ll i,j,x,y;
	while(true)
	{
		cin>>y>>x;
		if(x==0&&y==0)
		{
			break;
		}
		x--,y--;
		qs[x][y].push_back(q);
		for(i=0;i<3;i++)
		{
			for(j=0;j<3;j++)
			{
				cin>>qry[q][i][j];
			}
		}
		q++;
	}
	for(i=0;i<3;i++)
	{
		for(j=0;j<3;j++)
		{
			if(!qs[i][j].empty())
			{
				solve(i,j);
			}
		}
	}
	for(i=0;i<q;i++)
	{
		if(ans[i]>30)
		{
			ans[i]=-1;
		}
		cout<<ans[i]<<'\n';
	}
	return 0;
}
accuracy: 1
time_ms: 1610
memory_kb: 68224
final_rank: 15

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>

#include <iostream>
#include <complex>
#include <string>
#include <algorithm>
#include <numeric>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>

#include <functional>
#include <cassert>

typedef long long ll;
using namespace std;

#ifndef LOCAL
#define debug(x) ;
#else
#define debug(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl;

template <typename T1, typename T2>
ostream &operator<<(ostream &out, const pair<T1, T2> &p) {
  out << "{" << p.first << ", " << p.second << "}";
  return out;
}

template <typename T>
ostream &operator<<(ostream &out, const vector<T> &v) {
  out << '{';
  for (const T &item : v) out << item << ", ";
  out << "\b\b}";
  return out;
}
#endif

#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 200010

// 0 ... B-W-B
// 1 ... R-W-R
// 2 ... W-B-W
// 3 ... R-B-R
// 4 ... W-R-W
// 5 ... B-R-B
// 6 ... empty

// 0 -> LR, 1 -> UD

int to[6][2] = {{2, 5}, {4, 3}, {0, 4}, {5, 1}, {1, 2}, {3, 0}};

int encode(int state[3][3]) {
  int emptyPos = 0;
  int res = 0;

  for (int i=0; i<3; i++) {
    for(int j=0; j<3; j++) {
      if (state[i][j] == 6)
        emptyPos = i * 3 + j;
      else
        res = res * 6 + state[i][j];
    }
  }

  return res * 9 + emptyPos;
}

void decode(int hash, int state[3][3]) {
  int emptyPos = hash % 9;
  hash /= 9;

  state[emptyPos/3][emptyPos%3] = 6;

  for (int i=2; i>=0; i--) {
    for (int j=2; j>=0; j--) {
      if (i * 3 + j == emptyPos) continue;
      state[i][j] = hash % 6;
      hash /= 6;
    }
  }
}

int memo[1679616 * 9]; //6^8 * 9

int base6[] = {1, 6, 36, 216, 1296, 7776, 46656, 279936, 1679616};

void print(int hash) {
  int state[3][3];
  decode(hash, state);
  for (int i=0; i<3; i++) {
    for (int j=0; j<3; j++)
      printf("%d ", state[i][j]);
    puts("");
  }
  puts("");
}

void bfs(int y, int x) {
  queue<int> que;
  int state[3][3];

  que.push(y * 3 + x);

  for(int i=0; i<=30; i++) {
    queue<int> que2;

    while(que.size()) {
      int hash = que.front();
      que.pop();

      if (memo[hash]) continue;

      memo[hash] = i + 1;

      decode(hash, state);

      int emptyX = hash % 9 % 3;
      int emptyY = hash % 9 / 3;

      if (emptyY > 0) {
        int tmp = state[emptyY-1][emptyX];
        state[emptyY][emptyX] = to[tmp][1];
        state[emptyY-1][emptyX] = 6;

        int tmp2 = encode(state);
        if (!memo[tmp2]) que2.push(tmp2);

        state[emptyY-1][emptyX] = tmp;
        state[emptyY][emptyX] = 6;
      }

      if (emptyY+1 < 3) {
        int tmp = state[emptyY+1][emptyX];
        state[emptyY][emptyX] = to[tmp][1];
        state[emptyY+1][emptyX] = 6;

        int tmp2 = encode(state);
        if (!memo[tmp2]) que2.push(tmp2);

        state[emptyY+1][emptyX] = tmp;
        state[emptyY][emptyX] = 6;
      }

      if (emptyX > 0) {
        int tmp = state[emptyY][emptyX-1];
        state[emptyY][emptyX] = to[tmp][0];
        state[emptyY][emptyX-1] = 6;

        int tmp2 = encode(state);
        if (!memo[tmp2]) que2.push(tmp2);

        state[emptyY][emptyX-1] = tmp;
        state[emptyY][emptyX] = 6;
      }

      if (emptyX+1 < 3) {
        int tmp = state[emptyY][emptyX+1];
        state[emptyY][emptyX] = to[tmp][0];
        state[emptyY][emptyX+1] = 6;

        int tmp2 = encode(state);
        if (!memo[tmp2]) que2.push(tmp2);

        state[emptyY][emptyX+1] = tmp;
        state[emptyY][emptyX] = 6;
      }
    }

    que = que2;
  }
}

int solve(int y, int x, int hash) {
  static int prevY = -1, prevX = -1;

  if (prevY != y || prevX != x) {
    memset(memo, 0, sizeof(memo));

    bfs(y, x);
  }

  int ans = INF, state[3][3];

  decode(hash, state);

  for (int i=0; i<(1<<9); i++) {

    for (int y=0; y<3; y++) {
      for (int x=0; x<3; x++) {
        if (state[y][x] < 6)
          state[y][x] = state[y][x] / 2 * 2 + (i >> (y * 3 + x)) % 2;
      }
    }

    int hash = encode(state);

    if (memo[hash] > 0)
      ans = min(ans, memo[hash] - 1);
  }

  prevY = y;
  prevX = x;

  return ans;
}

int main(){
  int x, y;
  int state[3][3];

  vector<pair<int, pair<int,int> > > query;

  for(int i=0; ;i++){
    scanf("%d%d", &x, &y);

    if (x == 0) break;
    x--; y--;

    int b = 2, r = 4;
    int rotate = 0;

    if ((y == 0 && x == 2) || (y == 1 && x == 2)) { rotate = 1; swap(b, r); }
    if ((y == 2 && x == 2) || (y == 2 && x == 1)) { rotate = 2; }
    if ((y == 2 && x == 0) || (y == 1 && x == 0)) { rotate = 3; swap(b, r); }

    for (int i=0; i<3; i++) {
      for (int j=0; j<3; j++) {
        char c;
        scanf(" %c", &c);

        if (c == 'W') state[i][j] = 0;
        if (c == 'B') state[i][j] = b;
        if (c == 'R') state[i][j] = r;
        if (c == 'E') state[i][j] = 6;
      }
    }

    for (int k=0; k<rotate; k++) {
      swap(state[0][0], state[0][2]);
      swap(state[0][2], state[2][2]);
      swap(state[2][2], state[2][0]);

      swap(state[0][1], state[1][2]);
      swap(state[1][2], state[2][1]);
      swap(state[2][1], state[1][0]);

      // (1, 2) => (0, 1)
      int tmp = x;
      x = y;
      y = 2 - tmp;
    }

    int hash = encode(state);

    debug(y); debug(x);
    debug(rotate);

    query.push_back({y * 3 + x, {hash, i}});
  }

  sort(query.begin(), query.end());

  vector<int> ans(query.size());

  for (int i=0; i<query.size(); i++) {
    int y = query[i].first / 3;
    int x = query[i].first % 3;
    int hash = query[i].second.first;
    int idx = query[i].second.second;

    ans[idx] = solve(y, x, hash);
  }

  for (int p : ans) {
    if (p == INF)
      puts("-1");
    else
      printf("%d\n", p);
  }

  return 0;
}
accuracy: 1
time_ms: 1290
memory_kb: 67252
final_rank: 14

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


class Dice{
public:


	void roll(char dst){
		for(int i = 0; i < 6; i++) work[i] = color[i];
		switch(dst){
		case 'E':
			setColor(work[3],work[1],work[0],work[5],work[4],work[2]);
			break;
		case 'S':
			setColor(work[1],work[5],work[2],work[3],work[0],work[4]);
			break;
		case 'N':
			setColor(work[4],work[0],work[2],work[3],work[5],work[1]);
			break;
		case 'W':
			setColor(work[2],work[1],work[5],work[0],work[4],work[3]);
			break;
		}
	};

	char getTop(){
		return color[0];
	}

	void setColor(char n0,char n1,char n2,char n3,char n4,char n5){
		color[0] = n0;
		color[1] = n1;
		color[2] = n2;
		color[3] = n3;
		color[4] = n4;
		color[5] = n5;
	}

	void init(){
		setColor('W','R','B','B','R','W');
	}

	void to_empty(){
		setColor('E','E','E','E','E','E');
	}

	char color[6],work[6];
};

struct Info{
	Dice board[3][3];
	int num_step;
};

int first_row,first_col;
int diff_row[4] = {-1,0,0,1},diff_col[4] = {0,-1,1,0};
Info goal;

bool rangeCheck(int row,int col){
	if(row >= 0 && row <= 2 && col >= 0 && col <= 2)return true;
	else{
		return false;
	}
}

int calcDiff(Info info){

	int ret = 0;

	for(int row = 0; row < 3; row++){
		for(int col = 0; col < 3; col++){
			if(info.board[row][col].getTop() != goal.board[row][col].getTop()){
				ret++;
			}
		}
	}

	return ret;
}


bool FLG;

void recursive(Info info,int max_depth,int empty_row,int empty_col,int pre_row,int pre_col){

	if(FLG)return;

	int tmp_diff = calcDiff(info);

	if(tmp_diff == 0){
		FLG = true;
		return;
	}

	if(info.num_step+tmp_diff > max_depth+1)return;

	int adj_row,adj_col;
	info.num_step++;

	Dice tmp;

	for(int i = 0; i < 4; i++){
		adj_row = empty_row+diff_row[i];
		adj_col = empty_col+diff_col[i];

		if(!rangeCheck(adj_row,adj_col))continue;
		if(adj_row == pre_row && adj_col == pre_col)continue;

		tmp = info.board[adj_row][adj_col];

		switch(i){
		case 0:
			info.board[adj_row][adj_col].roll('S');
			break;
		case 1:
			info.board[adj_row][adj_col].roll('E');
			break;
		case 2:
			info.board[adj_row][adj_col].roll('W');
			break;
		case 3:
			info.board[adj_row][adj_col].roll('N');
			break;
		}

		swap(info.board[empty_row][empty_col],info.board[adj_row][adj_col]);
		recursive(info,max_depth,adj_row,adj_col,empty_row,empty_col);

		info.board[empty_row][empty_col].to_empty();
		info.board[adj_row][adj_col] = tmp;
	}
}


void func(){

	first_row--;
	first_col--;

	char buf[2];

	for(int row = 0; row < 3; row++){
		for(int col = 0; col < 3; col++){
			scanf("%s",buf);
			goal.board[row][col].color[0] = buf[0];
		}
	}

	Info first;
	for(int row = 0; row < 3; row++){
		for(int col = 0; col < 3; col++)first.board[row][col].init();
	}
	first.board[first_row][first_col].to_empty();
	first.num_step = 0;

	FLG = false;
	int ans;

	for(int max_depth = 0; max_depth <= 30; max_depth++){
		recursive(first,max_depth,first_row,first_col,-1,-1);
		if(FLG){
			ans = max_depth;
			break;
		}
	}

	if(FLG){
		printf("%d\n",ans);
	}else{
		printf("-1\n");
	}
}


int main(){

	while(true){
		scanf("%d %d",&first_col,&first_row);
		if(first_col == 0 && first_row == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 1450
memory_kb: 3200
final_rank: 9

code_snippet: #include<bits/stdc++.h>
using namespace std;
 
struct Dice{
  int s[6],f;
  Dice(){}
  void roll(char c){
    int b;
    if(c=='E'||c==3){
      b=s[0];
      s[0]=s[3];
      s[3]=s[5];
      s[5]=s[2];
      s[2]=b;
    }
    if(c=='W'||c==1){
      b=s[0];
      s[0]=s[2];
      s[2]=s[5];
      s[5]=s[3];
      s[3]=b;
    }
    if(c=='N'||c==0){
      b=s[0];
      s[0]=s[1];
      s[1]=s[5];
      s[5]=s[4];
      s[4]=b;
    }
    if(c=='S'||c==2){
      b=s[0];
      s[0]=s[4];
      s[4]=s[5];
      s[5]=s[1];
      s[1]=b;
    }
 
    if(c=='R'){
      b=s[1];
      s[1]=s[3];
      s[3]=s[4];
      s[4]=s[2];
      s[2]=b;
    }
    if(c=='L'){
      b=s[1];
      s[1]=s[2];
      s[2]=s[4];
      s[4]=s[3];
      s[3]=b;
    }
  }
  int top(){
    if(f) return 3;
    return s[0];
  }
  int hash(){
    if(f) return -1;
    int res=0;
    for(int i=0;i<6;i++) res=res*4+s[i];
    return res;
  }
};
 
map<int,int> mi;
map<int,Dice> md;
void makeDices(Dice d){
  for(int i=0;i<6;i++){
    Dice t(d);
    if(i==1) t.roll('N');
    if(i==2) t.roll('S');
    if(i==3) t.roll('S'),t.roll('S');
    if(i==4) t.roll('L');
    if(i==5) t.roll('R');
    for(int k=0;k<4;k++){
      int h=t.hash(),p=mi.size();
      //cout<<h<<"-"<<p<<endl;
      if(!mi.count(h)){
    mi[h]=p;
    md[p]=t;
    //cout<<p<<":"<<h<<"-"<<t.f<<endl;
      }
      t.roll('E');
    }
  }
  //cout<<md.size()<<endl;
  d.f=1;
  mi[-1]=6;
  md[6]=d;
}
 
int tv(vector<Dice>& ds){
  int res=0;
  for(int i=0;i<9;i++)
    res=res*4+ds[i].top();
  return res;
}
 
int ds2i(vector<Dice>& ds){
  int res=0;
  for(int i=8;i>=0;i--) res=res*7+mi[ds[i].hash()];
  return res;
}
void i2ds(int x,vector<Dice>& ds){
  for(int i=0;i<9;i++){
    ds[i]=md[x%7];
    x/=7;
  }
}
char dp[40353607+1];
signed main(){
  int y,x;
  while(cin>>x>>y,x||y){
    x--;y--;
    char f[3][3];
    for(int i=0;i<3;i++)
      for(int j=0;j<3;j++)
	cin>>f[i][j];
    int en=0;
    for(int i=0;i<3;i++){
      for(int j=0;j<3;j++){
	int k=3;
	if(f[i][j]=='B') k=0;
	if(f[i][j]=='W') k=1;
	if(f[i][j]=='R') k=2;
	//cout<<k<<":";
	en=en*4+k;
      }
    }
    //cout<<endl;
 
    //cout<<en<<endl;
     
    vector<Dice> ds(9);
    Dice d;
    d.s[0]=d.s[5]=1;
    d.s[2]=d.s[3]=0;
    d.s[1]=d.s[4]=2;
    d.f=0;
 
    makeDices(d);
     
    for(int i=0;i<3;i++){
      for(int j=0;j<3;j++){
	ds[i*3+j]=d;
	if(y==i&&x==j) ds[i*3+j].f=1;
	//cout<<i*3+j<<"="<<ds[i*3+j].f<<"/"<<ds[i*3+j].top()<<endl;
      }
    }
 
    //for(int i=0;i<3;i++) for(int j=0;j<3;j++) cout<<i*3+j<<"="<<ds[i*3+j].f<<"/"<<ds[i*3+j].top()<<endl;
     
    int ay[]={1,0,-1,0};
    int ax[]={0,1,0,-1};
     
    int ans=-1;
    fill_n(dp,40353607+1,32);
    //map<int,int> dp;
    queue<int> q;
 
     
    q.push(ds2i(ds));
    dp[ds2i(ds)]=0;
    while(!q.empty()){
      int p=q.front();q.pop();
      //cout<<p<<endl;
      if(dp[p]>=30) break;
      i2ds(p,ds);
      //cout<<tv(ds)<<endl;
      if(tv(ds)==en){
	ans=dp[p];
	break;
      }
      int y=-1,x=-1;
      for(int i=0;i<3;i++)
	for(int j=0;j<3;j++)
	  if(ds[i*3+j].f) y=i,x=j;
 
      //cout<<dp[p]<<":"<<y<<" "<<x<<endl;
       
      for(int k=0;k<4;k++){
	int ny=y+ay[k],nx=x+ax[k];
	//cout<<k<<"/"<<ny<<" "<<nx<<endl;
	if(ny<0||3<=ny||nx<0||3<=nx) continue;
	//cout<<k<<"/"<<ny<<" "<<nx<<endl;
	ds[ny*3+nx].roll(k);
	swap(ds[ny*3+nx],ds[y*3+x]);
 
	int h=ds2i(ds);
	if(dp[h]>30){
	  if(tv(ds)==en){
	    ans=dp[p]+1;
	    break;
	  }
	  dp[h]=dp[p]+1;
	  q.push(h);
	}
 
	swap(ds[ny*3+nx],ds[y*3+x]);
	ds[ny*3+nx].roll((k+2)%4);
      }
      if(ans>=0) break;
    }
    cout<<ans<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 7340
memory_kb: 44300
final_rank: 20

code_snippet: #include<bits/stdc++.h>
using namespace std;

struct Dice{
  int s[6],f;
  Dice(){}
  void roll(char c){
    int b;
    if(c=='E'||c==3){
      b=s[0];
      s[0]=s[3];
      s[3]=s[5];
      s[5]=s[2];
      s[2]=b;
    }
    if(c=='W'||c==1){
      b=s[0];
      s[0]=s[2];
      s[2]=s[5];
      s[5]=s[3];
      s[3]=b;
    }
    if(c=='N'||c==0){
      b=s[0];
      s[0]=s[1];
      s[1]=s[5];
      s[5]=s[4];
      s[4]=b;
    }
    if(c=='S'||c==2){
      b=s[0];
      s[0]=s[4];
      s[4]=s[5];
      s[5]=s[1];
      s[1]=b;
    }

    if(c=='R'){
      b=s[1];
      s[1]=s[3];
      s[3]=s[4];
      s[4]=s[2];
      s[2]=b;
    }
    if(c=='L'){
      b=s[1];
      s[1]=s[2];
      s[2]=s[4];
      s[4]=s[3];
      s[3]=b;
    }
  }
  int top(){
    if(f) return 3;
    return s[0];
  }
  int hash(){
    if(f) return -1;
    int res=0;
    for(int i=0;i<6;i++) res=res*4+s[i];
    return res;
  }
};

map<int,int> mi;
map<int,Dice> md;
void makeDices(Dice d){
  for(int i=0;i<6;i++){
    Dice t(d);
    if(i==1) t.roll('N');
    if(i==2) t.roll('S');
    if(i==3) t.roll('S'),t.roll('S');
    if(i==4) t.roll('L');
    if(i==5) t.roll('R');
    for(int k=0;k<4;k++){
      int h=t.hash(),p=mi.size();
      //cout<<h<<"-"<<p<<endl;
      if(!mi.count(h)){
	mi[h]=p;
	md[p]=t;
	//cout<<p<<":"<<h<<"-"<<t.f<<endl;
      }
      t.roll('E');
    }
  }
  //cout<<md.size()<<endl;
  d.f=1;
  mi[-1]=6;
  md[6]=d;
}

int tv(vector<Dice>& ds){
  int res=0;
  for(int i=0;i<9;i++)
    res=res*4+ds[i].top();
  return res;
}

int ds2i(vector<Dice>& ds){
  int res=0;
  for(int i=8;i>=0;i--) res=res*7+mi[ds[i].hash()];
  return res;
}
void i2ds(int x,vector<Dice>& ds){
  for(int i=0;i<9;i++){
    ds[i]=md[x%7];
    x/=7;
  }
}
char dp[40353607+1];
signed main(){
  int y,x;
  while(cin>>x>>y,x||y){
    x--;y--;
    char f[3][3];
    for(int i=0;i<3;i++)
      for(int j=0;j<3;j++)
	cin>>f[i][j];
    int en=0;
    for(int i=0;i<3;i++){
      for(int j=0;j<3;j++){
	int k=3;
	if(f[i][j]=='B') k=0;
	if(f[i][j]=='W') k=1;
	if(f[i][j]=='R') k=2;
	//cout<<k<<":";
	en=en*4+k;
      }
    }
    //cout<<endl;

    //cout<<en<<endl;
    
    vector<Dice> ds(9);
    Dice d;
    d.s[0]=d.s[5]=1;
    d.s[2]=d.s[3]=0;
    d.s[1]=d.s[4]=2;
    d.f=0;

    makeDices(d);
    
    for(int i=0;i<3;i++){
      for(int j=0;j<3;j++){
	ds[i*3+j]=d;
	if(y==i&&x==j) ds[i*3+j].f=1;
	//cout<<i*3+j<<"="<<ds[i*3+j].f<<"/"<<ds[i*3+j].top()<<endl;
      }
    }

    //for(int i=0;i<3;i++) for(int j=0;j<3;j++) cout<<i*3+j<<"="<<ds[i*3+j].f<<"/"<<ds[i*3+j].top()<<endl;
    
    int ay[]={1,0,-1,0};
    int ax[]={0,1,0,-1};
    
    int ans=-1;
    fill_n(dp,40353607+1,32);
    //map<int,int> dp;
    queue<int> q;

    
    q.push(ds2i(ds));
    dp[ds2i(ds)]=0;
    while(!q.empty()){
      int p=q.front();q.pop();
      //cout<<p<<endl;
      if(dp[p]>=30) break;
      i2ds(p,ds);
      //cout<<tv(ds)<<endl;
      if(tv(ds)==en){
	ans=dp[p];
	break;
      }
      int y=-1,x=-1;
      for(int i=0;i<3;i++)
	for(int j=0;j<3;j++)
	  if(ds[i*3+j].f) y=i,x=j;

      //cout<<dp[p]<<":"<<y<<" "<<x<<endl;
      
      for(int k=0;k<4;k++){
	int ny=y+ay[k],nx=x+ax[k];
	//cout<<k<<"/"<<ny<<" "<<nx<<endl;
	if(ny<0||3<=ny||nx<0||3<=nx) continue;
	//cout<<k<<"/"<<ny<<" "<<nx<<endl;
	ds[ny*3+nx].roll(k);
	swap(ds[ny*3+nx],ds[y*3+x]);

	int h=ds2i(ds);
	if(dp[h]>30){
	  if(tv(ds)==en){
	    ans=dp[p]+1;
	    break;
	  }
	  dp[h]=dp[p]+1;
	  q.push(h);
	}

	swap(ds[ny*3+nx],ds[y*3+x]);
	ds[ny*3+nx].roll((k+2)%4);
      }
      if(ans>=0) break;
    }
    cout<<ans<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 7300
memory_kb: 44388
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;

int dx[4]={-1,0,1,0},dy[4]={0,-1,0,1},n=3;
bool check(int x,int y) {return x>=0&&x<n&&y>=0&&y<n;}
vector<char> rotate(vector<char> a,int k) {
  if(k%2) swap(a[0],a[2]);
  else swap(a[0],a[1]);
  return a;
}

char s[3][3];
int ans;
vector<vector<vector<char> > > v;
void dfs(int c,int p) {
  if(c>=ans) return;
  int xx,yy,d=0;
  for(int i=0; i<n; i++) {
    for(int j=0; j<n; j++) {
      if(v[i][j][0]=='E') xx=i,yy=j;
      if(v[i][j][0]!=s[i][j]) d++;
    }
  }
  if(!d) {
    ans=min(ans,c);
    return;
  }
  if(d+c>ans) return;
  for(int i=0; i<4; i++) {
    int x=xx+dx[i],y=yy+dy[i];
    if(!check(x,y)||i==p) continue;
    v[x][y]=rotate(v[x][y],i);
    swap(v[xx][yy],v[x][y]);
    dfs(c+1,(i+2)%4);
    swap(v[xx][yy],v[x][y]);
    v[x][y]=rotate(v[x][y],i);
  }
}

int main() {
  int xx,yy;
  while(cin >> yy >> xx && xx) {
    v.clear();
    for(int i=0; i<n; i++) {
      for(int j=0; j<n; j++) cin >> s[i][j];
    }
    for(int i=1; i<4; i++) {
      vector<vector<char> > a;
      for(int j=1; j<4; j++) {
        vector<char> c;
        if(i==xx&&j==yy) {
          for(int k=0; k<3; k++) c.push_back('E');
        } else {
          c.push_back('W');
          c.push_back('R');
          c.push_back('B');
        }
        a.push_back(c);
      }
      v.push_back(a);
    }
    ans=31;
    dfs(0,-1);
    if(ans==31) ans=-1;
    cout << ans << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 3910
memory_kb: 2996
final_rank: 12

code_snippet: #include <algorithm>
#include <vector>
#include <cfloat>
#include <string>
#include <cmath>
#include <set>
#include <cstdlib>
#include <map>
#include <ctime>
#include <iomanip>
#include <functional>
#include <deque>
#include <iostream>
#include <cstring>
#include <queue>
#include <cstdio>
#include <stack>
#include <climits>
#include <sys/time.h>
#include <cctype>
 
using namespace std;
 
typedef long long ll;
 
class dice {
 public:
  int a, b, c;
  dice(int a = 0, int b = 1, int c = 2): a(a), b(b), c(c) {}
  bool operator<(const dice &t) const {
    return (a < t.a) || (a == t.a && b < t.b) || (a == t.a && b == t.b && c < t.c);
  }
};
 
vector <int> goal; int ans;
int ix, iy;
map<vector<dice>, int> memo;
int d[] = {-3, 1, 3, -1};
int dx[] = {0, 1, 0, -1};
int dy[] = {-1, 0, 1, 0};
bool same(vector <int> &a, vector <int> &b) {
  for (int i = 0; i < a.size(); i++) {
    if (a[i] != b[i]) return false;
  }
  return true;
}
bool same(vector <int> &a, vector <dice> &b) {
  for (int i = 0; i < a.size(); i++) {
    if (a[i] != b[i].a) return false;
  }
  return true;
}
 
 
void rot(dice &p, int i) {
  if (i == 0 || i == 2) {
    swap(p.a, p.b);
  }else {
    swap(p.a, p.c);
  }
}
 
void view(vector <int> p) {
  for (int i = 0; i < p.size(); i++) {
    cout << p[i] << " ";
    if ((i+1)%3 == 0) cout << endl;
  }
  cout << endl;
}
void view(vector <dice> p) {
  for (int i = 0; i < p.size(); i++) {
    cout << p[i].a << " ";
    if ((i+1)%3 == 0) cout << endl;
  }
  cout << endl;
}
 
 
// int loopn = 0;
void rec(vector <dice> &p, int &x, int &y, int prex, int prey, int cnt) {
  // loopn++;
  if (ans <= cnt+abs(x-ix)+abs(y-iy)) return;
  if (cnt+abs(x-ix)+abs(y-iy) > 30) {
    return;
  }
  // vector <int> t;
  // for (int i = 0; i < 9; i++) t.push_back(p[i].a);
  // map<vector<dice>, int>::iterator it = memo.find(p);
  // if (it != memo.end()) {
  //   if ((*it).second <= cnt) {
  //     return;
  //   }
  // }
 
  //   // vector <int> pret = {0, 2, 0, 0, 0, 0, 0, 0, 0};
  //   // if (same(pret, p)) {
  //   //   if (cnt == 1) {
  //   //     cout << x << " " << y << endl;
  //   //     cout << (*it).second << " " << cnt << endl;
  //   //   }
  //   // }
 
  // // view(t);
  // memo[p] = cnt;
  if (same(goal, p)) {
    if (ans <= cnt) return;
    ans = cnt;
  }else {
    for (int i = 0; i < 4; i++) {
      int nx = x+dx[i];
      int ny = y+dy[i];
 
      if (nx < 0 || ny < 0 || nx > 2 || ny > 2) continue;
      if (nx == prex && ny == prey) continue;
      int xy = x+y*3, nxy = nx+ny*3;
      swap(p[xy], p[nxy]);
      rot(p[xy], (i+2)%4);
      // if (same(pret, np)) {
      //   if (cnt == 0) {
      //     cout << nx << " " << ny << endl;
      //     // view(np);
      //   }
      // }
       
 
      rec(p, nx, ny, x, y, cnt+1);
      rot(p[xy], (i+2)%4);
      swap(p[xy], p[nxy]);
    }
  }
}
 
int main() {
  while (true) {
    int x, y;
    cin >> x >> y;
    if (x == 0 && y == 0) break;
    x--; y--;
    vector <dice> init;
    for (int i = 0; i < 9; i++) init.push_back(dice());
    init[x+y*3] = dice(5, 0, 0);
    vector <int> empvec;
    map<vector<dice>, int> empmemo;
    memo = empmemo;
    goal = empvec;
    for (int i = 0; i < 9; i++) {
      char v;
      cin >> v;
      if (v == 'W') goal.push_back(0);
      if (v == 'R') goal.push_back(1);
      if (v == 'B') goal.push_back(2);
      if (v == 'E') goal.push_back(5);
      if (v == 'E') {
        ix = i%3;
        iy = i/3;
      }
    }
    ans = INT_MAX;
    rec(init, x, y, -1, -1, 0);
    // cout << memo.size() << endl;
    // cout << loopn << endl;
    if (ans == INT_MAX){
      cout << -1 << endl;
    }else {
      cout << ans << endl;
    }
  }
}
accuracy: 1
time_ms: 3560
memory_kb: 1220
final_rank: 11

code_snippet: #include <iostream>
#include <array>
#include <vector>
#include <set>
#include <unordered_set>
#include <map>
#include <queue>
#include <algorithm>
#include <cassert>
#define repeat_from(i,m,n) for (int i = (m); (i) < (n); ++(i))
#define repeat(i,n) repeat_from(i,0,n)
#define repeat_from_reverse(i,m,n) for (int i = (n)-1; (i) >= (m); --(i))
#define repeat_reverse(i,n) repeat_from_reverse(i,0,n)
#define dump(x)  cerr << #x << " = " << (x) << endl
#define debug(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ")" << " " << __FILE__ << endl
using namespace std;

// Wn R   Wr B
//   BWB    RWR
//    R      B
// Bn R   Br W
//   WBW    RBR
//    R      W
// Rn W   Rr B
//   BRB    WRW
//    W      B
const char Wn = 'W';
const char Wr = 'w';
const char Bn = 'B';
const char Br = 'b';
const char Rn = 'R';
const char Rr = 'r';
const char E  = 'E';
char next_tate(char dice) {
    return
        dice == Wn ? Rn :
        dice == Wr ? Br :
        dice == Bn ? Rr :
        dice == Br ? Wr :
        dice == Rn ? Wn :
        dice == Rr ? Bn : 0;
}
char next_yoko(char dice) {
    return
        dice == Wn ? Bn :
        dice == Wr ? Rr :
        dice == Bn ? Wn :
        dice == Br ? Rn :
        dice == Rn ? Br :
        dice == Rr ? Wr : 0;
}
struct state_t {
    char f[3][3];
    int8_t ey, ex;
    int8_t n;
    int8_t match;
};
bool equals_top(char const (& f)[3][3], char const (& g)[3][3]) {
    repeat (y,3) repeat (x,3) {
        if (toupper(f[y][x]) != toupper(g[y][x])) {
        // if (toupper(f[y][x] != toupper(g[y][x]))) {
            return false;
        }
    }
    return true;
}
const int dy[] = { -1, 1, 0, 0 };
const int dx[] = { 0, 0, -1, 1 };
uint32_t pack(char const (& f)[3][3]) {
    uint32_t z = 0;
    repeat (y,3) {
        repeat (x,3) {
            z *= 7;
            z +=
                f[y][x] == Wn ? 1 :
                f[y][x] == Wr ? 2 :
                f[y][x] == Bn ? 3 :
                f[y][x] == Br ? 4 :
                f[y][x] == Rn ? 5 :
                f[y][x] == Rr ? 6 : 0;
        }
    }
    return z;
}

int main() {
    while (true) {
        int sex, sey; cin >> sex >> sey;
        if (sex == 0 and sey == 0) break;
        -- sex; -- sey;
        char goal[3][3];
        repeat (y,3) repeat (x,3) cin >> goal[y][x];
        unordered_set<uint32_t> used;
        queue<state_t> que; {
            state_t s;
            repeat (y,3) repeat (x,3) s.f[y][x] = Wn;
            s.f[sey][sex] = E;
            s.ey = sey;
            s.ex = sex;
            s.n = 0;
            s.match = 0;
            repeat (y,3) repeat (x,3) if (goal[y][x] == s.f[y][x]) s.match += 1;
            que.push(s);
            used.insert(pack(s.f));
        }
        int result = -1;
        while (not que.empty()) {
            state_t s = que.front(); que.pop();
//repeat (y,3) {
//repeat (x,3) {
//cerr << s.f[y][x];
//}
//cerr << endl;
//}
//cerr << endl;
            if (equals_top(s.f, goal)) {
                result = s.n;
                break;
            }
            if (s.n == 30) continue;
            if (9 - s.match > 30 - s.n + 1) continue;
            repeat (i,4) {
                state_t t = s;
                t.ey = s.ey + dy[i];
                t.ex = s.ex + dx[i];
                if (t.ey < 0 or 3 <= t.ey or t.ex < 0 or 3 <= t.ex) continue;
                assert (s.f[s.ey][s.ex] == E);
                if (toupper(t.f[s.ey][s.ex]) == goal[s.ey][s.ex]) t.match -= 1;
                if (toupper(t.f[t.ey][t.ex]) == goal[t.ey][t.ex]) t.match -= 1;
                t.f[s.ey][s.ex] = dx[i] ? next_yoko(t.f[t.ey][t.ex]) : next_tate(t.f[t.ey][t.ex]);
                t.f[t.ey][t.ex] = E;
                if (toupper(t.f[s.ey][s.ex]) == goal[s.ey][s.ex]) t.match += 1;
                if (toupper(t.f[t.ey][t.ex]) == goal[t.ey][t.ex]) t.match += 1;
                t.n += 1;
                if (used.count(pack(t.f))) continue;
                que.push(t);
                used.insert(pack(t.f));
            }
        }
        cout << result << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 5210
memory_kb: 62044
final_rank: 18

code_snippet: #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<functional>
 
using namespace std;

/* constant */

#define INF	(1 << 30)

#define C_E	(0)
#define C_W	(1)
#define C_R	(2)
#define C_B	(3)

#define MAX_D	(30)

/* typedef */

typedef vector<int> vi;
typedef vector<long long> vl;
typedef vector<double> vd;
typedef pair<int,int> pii;
typedef pair<long,long> pll;
typedef long long ll;

struct cube_t {
  int x, y, z;
};

/* global variables */

cube_t ccube = {C_W, C_R, C_B}, ecube = {C_E, C_E, C_E};
int dxys[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};

cube_t brd[9];
int gl[9];
int gdist;

/* subroutines */

void check_rec(int d, int x0, int y0, int pdi) {
  if (d >= gdist) return;

  int diff = 0;
  for (int i = 0; i < 9; i++)
    if (brd[i].x != gl[i]) diff++;
  if (diff == 0) {
    if (gdist > d) gdist = d;
    return;
  }
  if (d + diff > gdist) return;

  int pos0 = y0 * 3 + x0;
  
  for (int di = 0; di < 4; di++) {
    if (((di + 2) % 4) == pdi) continue;
    
    int dx = dxys[di][0];
    int dy = dxys[di][1];
    int x = x0 + dx;
    int y = y0 + dy;

    if (x >= 0 && x < 3 && y >= 0 && y < 3) {
      int pos = y * 3 + x;
      cube_t pcb = brd[pos];
      brd[pos] = ecube;

      cube_t cb = pcb;
      if (dx != 0) {
        int t = cb.x; cb.x = cb.z; cb.z = t;
      }
      else {
        int t = cb.x; cb.x = cb.y; cb.y = t;
      }
      brd[pos0] = cb;

      check_rec(d + 1, x, y, di);

      brd[pos] = pcb;
      brd[pos0] = ecube;
    }
  }
}

/* main */

int main() {
  for (;;) {
    int sx, sy;
    cin >> sx >> sy;
    if ((sx | sy) == 0) break;

    sx--;
    sy--;

    for (int y = 0; y < 3; y++) {
      for (int x = 0; x < 3; x++) {
	int pos = y * 3 + x;
	string ch;
	cin >> ch;
	switch (ch[0]) {
	case 'E': gl[pos] = C_E; break;
	case 'W': gl[pos] = C_W; break;
	case 'R': gl[pos] = C_R; break;
	case 'B': gl[pos] = C_B; break;
	}
      }
    }
    //for (int i = 0; i < 9; i++) cout << gl[i]; cout << endl;
    
    for (int i = 0; i < 9; i++) brd[i] = ccube;
    brd[sy * 3 + sx] = ecube;
    //for (int i = 0; i < 9; i++) cout << brd[i].x; cout << endl;

    gdist = MAX_D + 1;

    check_rec(0, sx, sy, -1);

    cout << (gdist > MAX_D ? -1 : gdist) << endl;
  }

  return 0;
}
accuracy: 1
time_ms: 480
memory_kb: 1204
final_rank: 1

code_snippet: #include <array>
#include <climits>
#include <cstdlib>
#include <iostream>
#include <queue>
#include <unordered_map>
#include <vector>
using namespace std;

template<class T> inline void chmin(T &a, const T &b) { if(a > b) a = b; }

constexpr int SIZE = 3;
enum {B, W, R, E};
const string str = "BWRE";

typedef pair<int, int> cube;
#define top first
#define south second

typedef array<array<cube, SIZE>, SIZE> state;

inline bool out(int x, int y) {
	return x < 0 || y < 0 || x >= SIZE || y >= SIZE;
}

inline unsigned long long encode(const state &s) {
	unsigned long long res = 0;
	for(int y = 0; y < SIZE; ++y) {
		for(int x = 0; x < SIZE; ++x) {
			res = (res << 4) | (s[y][x].top << 2) | s[y][x].south;
		}
	}
	return res;
}

inline state decode(unsigned long long code) {
	constexpr unsigned long long mask = 0x3;
	state res;

	for(int y = SIZE - 1; y >= 0; --y) {
		for(int x = SIZE - 1; x >= 0; --x) {
			res[y][x].south = (code & mask);
			code >>= 2;
			res[y][x].top = (code & mask);
			code >>= 2;
		}
	}

	return res;
}

inline int match(const state &a, const state &b) {
	int res = 0;

	for(int y = 0; y < SIZE; ++y) {
		for(int x = 0; x < SIZE; ++x) {
			if(a[y][x].top == b[y][x].top) ++res;
		}
	}

	return res;
}

int bfs(const state &start, const state &goal) {
	constexpr int dx[] = {-1, 0, 1, 0};
	constexpr int dy[] = {0, -1, 0, 1};

	queue<unsigned long long> que;
	unordered_map<unsigned long long, int> dist;

	const auto s_code = encode(start);

	que.push(s_code);
	dist[s_code] =  0;

	while(!que.empty()) {
		const auto code = que.front();
		que.pop();

		const state current = decode(code);
		const int c_dist = dist[code];

		const int rest = 9 - match(current, goal);
		if(rest == 0) return c_dist;
		if(c_dist + rest - 1 > 30) continue;

		int ex = -1, ey = -1;
		for(int y = 0; y < SIZE; ++y) {
			for(int x = 0; x < SIZE; ++x) {
				if(current[y][x].top == E) {
					ex = x;
					ey = y;
					goto unloop;
				}
			}
		}

	unloop:;

		for(int d = 0; d < 4; ++d) {
			const int nex = ex + dx[d];
			const int ney = ey + dy[d];

			if(out(nex, ney)) continue;

			state next(current);
			swap(next[ey][ex], next[ney][nex]);

			if(d & 1) { // vertical
				swap(next[ey][ex].top, next[ey][ex].south);
			}
			else { // horizontal
				next[ey][ex].top = B + W + R - next[ey][ex].top - next[ey][ex].south;
			}

			const auto n_code = encode(next);
			if(!dist.count(n_code)) {
				dist.insert({n_code, c_dist + 1});
				que.push(n_code);
			}
		}
	}

	return -1;
}

int main() {
	cin.tie(nullptr);
	ios::sync_with_stdio(false);

	int value[128];

	for(int i = 0; i < static_cast<int>(str.size()); ++i) {
		value[str[i]] = i;
	}

	for(int ex, ey; cin >> ex >> ey && ex;) {
		state start;
		for(int y = 0; y < SIZE; ++y) {
			for(int x = 0; x < SIZE; ++x) {
				start[y][x] = cube(W, R);
			}
		}
		start[ey - 1][ex - 1] = cube(E, E);

		state goal;
		for(auto &row : goal) {
			for(auto &e : row) {
				char c;
				cin >> c;
				e.top = value[c];
			}
		}

		cout << bfs(start, goal) << endl;
	}

	return EXIT_SUCCESS;
}
accuracy: 1
time_ms: 4760
memory_kb: 61000
final_rank: 17

code_snippet: #include <algorithm>
#include <cassert>
#include <cctype>
#include <cstdio>
#include <complex>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <bitset>
#include <stack>
#include <utility>
#include <numeric>
#include <functional>
#include <string>
#include <sstream>
// #include <tuple>
// #include <regex>

using namespace std;
typedef long long ll;

#define ALL(c) (c).begin(),(c).end()
#define FOR(i,l,r) for(int i=(int)l;i<(int)r;++i)
#define REP(i,n) FOR(i,0,n)
#define FORr(i,l,r) for(int i=(int)r-1;i>=(int)l;--i)
#define REPr(i,n) FORr(i,0,n)
#define EACH(i,c) for(__typeof((c).begin()) i=(c).begin(); i!=(c).end(); ++i)
#define IN(l,v,r) ((l)<=(v) && (v)<(r))

template<typename T,typename U> T pmod(T x,U M){return (x%M+M)%M;}

stringstream ss;

const int H=3,W=3;
vector<vector<short>> goal;
vector<vector<short>> ts,ys,xs;

map<vector<vector<short>>,int> vmap;
map<vector<vector<short>>,int> passed;

int INF=1<<28;
int dy[4]={0,1,0,-1},dx[4]={1,0,-1,0};
int dfs(const int y,const int x,const int py,const int px,const int dep){
	if(dep>30)return INF;
	int wa=0;REP(_y,H)REP(_x,W)if(goal[_y][_x]!=ts[_y][_x])wa++;
	if(wa==0)return dep;
	if(wa>30-dep+1)return INF;
	
	int res=INF;
	REP(d,4){
		const int ny=y+dy[d],nx=x+dx[d];
		if(!IN(0,ny,H) || !IN(0,nx,W))continue;
		if(ny==py && nx ==px)continue;
		if(y==ny){//rotate X
			swap(xs[ny][nx],ts[y][x]);
			swap(ys[ny][nx],ys[y][x]);
			swap(ts[ny][nx],xs[y][x]);
			res=min(res,dfs(ny,nx,y,x,dep+1));
			swap(xs[ny][nx],ts[y][x]);
			swap(ys[ny][nx],ys[y][x]);
			swap(ts[ny][nx],xs[y][x]);
		}else{//rotate Y
			swap(ys[ny][nx],ts[y][x]);
			swap(xs[ny][nx],xs[y][x]);
			swap(ts[ny][nx],ys[y][x]);		
			res=min(res,dfs(ny,nx,y,x,dep+1));
			swap(ys[ny][nx],ts[y][x]);
			swap(xs[ny][nx],xs[y][x]);
			swap(ts[ny][nx],ys[y][x]);
		}
	}
	return res;
}
short enc(char c){
	if(c=='B')return 0;
	if(c=='W')return 1;
	if(c=='R')return 2;
	return 3;
}

int main(){
 // 	ifstream cin("in");
	// ofstream cout( "out" );
	cin.tie(0);
	ios::sync_with_stdio(false);
	ss   <<fixed <<setprecision(20);
	cout <<fixed <<setprecision(20);
	cerr <<fixed <<setprecision(20);

	while(true){
		int X,Y;cin >> X >> Y;if(Y==0 && X==0)break; Y--;X--;
		ts=vector<vector<short>>(H,vector<short>(W));
		xs=ys=vector<vector<short>>(H,vector<short>(W));
		goal=vector<vector<short>>(H,vector<short>(W));
		REP(y,H)REP(x,W){char c;cin >> c;goal[y][x]=enc(c);}
		REP(y,H)REP(x,W)if(y==Y && x==X) ys[y][x]=3; else ys[y][x]=2;
		REP(y,H)REP(x,W)if(y==Y && x==X) xs[y][x]=3; else xs[y][x]=0;
		REP(y,H)REP(x,W)if(y==Y && x==X) ts[y][x]=3; else ts[y][x]=1;
		int res=dfs(Y,X,-1,-1,0);
		if(res==INF)cout << -1 <<endl;
		else cout << res <<endl;
	}

 	return 0;
 }
accuracy: 1
time_ms: 1850
memory_kb: 1224
final_rank: 10

code_snippet: #include<iostream>
#include<set>
#include<array>
#include<cstdlib>

using namespace std;

typedef array<array<signed char,3>,3> Die;

int main(){
  for(int x,y;cin>>x>>y,x;){
    char g[3][3];
    bool nz=false;
    for(int i=0;i<3;i++){
      for(int j=0;j<3;j++){
	cin>>g[i][j];
	if(g[i][j]=='E'){
	  nz|=i!=y-1||j!=x-1;
	}else{
	  nz|=g[i][j]!='W';
	}
      }
    }
    if(!nz){
      cout<<0<<endl;
    }else{
      set<Die> s[32];
      Die d{};
      d[y-1][x-1]=-1;
      s[0].insert(d);
      for(int i=0;i<=30;i++){
	//	cout<<"c = "<<s[i].size()<<endl;
	for(auto e:s[i]){
	  int ey,ex;
	  for(int k=0;k<3;k++){
	    for(int j=0;j<3;j++){
	      if(e[k][j]==-1){
		ey=k;
		ex=j;
	      }
	    }
	  }
	  if(i<30){
	    static int dy[]={-1,0,1,0};
	    static int dx[]={0,1,0,-1};
	    for(int j=0;j<4;j++){
	      int ny=ey+dy[j];
	      int nx=ex+dx[j];
	      if(0<=ny&&ny<3&&0<=nx&&nx<3){
		auto n=e;
		n[ny][nx]=-1;
		n[ey][ex]=(e[ny][nx]+((e[ny][nx]%2^j%2)?1:5))%6;
	      
		bool f=false;
		int c=0;
		int gy,gx;
		for(int jj=0;jj<3;jj++){
		  for(int k=0;k<3;k++){
		    if(n[jj][k]==-1){
		      f|=g[jj][k]!='E';
		    }else{
		      f|=g[jj][k]!="WBRWBR"[n[jj][k]];
		    }
		    c+=g[jj][k]!='E'&&(n[jj][k]==-1||g[jj][k]!="WBRWBR"[n[jj][k]]);
		    if(g[jj][k]=='E'){
		      gy=jj;
		      gx=k;
		    }
		  }
		}
		if(!f){
		  cout<<i+1<<endl;
		  goto next;
		}
		if(max(c,abs(ny-gy)+abs(nx-gx))+i+1>30)continue;
		s[i+1].insert(n);
	      }
	    }
	  }
	}
	s[i].clear();
      }
      cout<<-1<<endl;
    next:
      ;
    }
  }
}
accuracy: 1
time_ms: 6990
memory_kb: 37152
final_rank: 16

code_snippet: #include<bits/stdc++.h>

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define IINF (INT_MAX)

using namespace std;

typedef long long ll;

enum FACE { TOP, BOTTOM, FRONT, BACK, LEFT, RIGHT };
template <class T>
class Dice {
public:
  Dice() {
    id[TOP] = 0; id[FRONT] = 1; id[LEFT] = 2;
    id[RIGHT] = 3; id[BACK] = 4; id[BOTTOM] = 5;
  }
  T& operator[] (FACE f) { return var[id[f]]; }
  const T& operator[] (FACE f) const { return var[id[f]]; }
  bool operator==(const Dice<T>& b) const {
    const Dice<T> &a = *this;
    return a[TOP] == b[TOP] && a[BOTTOM] == b[BOTTOM] &&
      a[FRONT] == b[FRONT] && a[BACK] == b[BACK] &&
      a[LEFT] == b[LEFT] && a[RIGHT] == b[RIGHT];
  }
  void roll_x() { roll(TOP, BACK, BOTTOM, FRONT); }
  void roll_y() { roll(TOP, LEFT, BOTTOM, RIGHT); }
  void roll_z() { roll(FRONT, RIGHT, BACK, LEFT); }

private:
  void roll(FACE a, FACE b, FACE c, FACE d) {
    T tmp = id[a];
    id[a] = id[b]; id[b] = id[c];
    id[c] = id[d]; id[d] = tmp;
  }
  T var[6];
  int id[6];
};

FACE face[] = {TOP,BOTTOM,FRONT,BACK,LEFT,RIGHT};

inline int toInt(char c){ return ((c=='B')?0:((c=='E')?1:((c=='R')?2:3))); }
char F[3][3];
char initial_color[] = {'W','W','R','R','B','B'};
int mincost;
int dx[] = {1,0,-1,0}; // R, B, L, T
int dy[] = {0,1,0,-1};

inline void swap_dice(Dice<char> dice[3][3],int x1,int y1,int x2,int y2,int type){
  if( type == 0 ) rep(i,3)dice[y2][x2].roll_y();
  if( type == 1 ) rep(i,3)dice[y2][x2].roll_x();
  if( type == 2 ) dice[y2][x2].roll_y();
  if( type == 3 ) dice[y2][x2].roll_x();
  swap(dice[y1][x1],dice[y2][x2]);
}

inline int finish(Dice<char> dice[3][3]){
  int diff = 0;
  rep(i,3)rep(j,3)if( dice[i][j][TOP] != F[i][j] ) diff++;
  return diff;
}

void dfs(Dice<char> dice[3][3],int x,int y,int cost,int pre){

  if( cost >= mincost) return;

  int tmp;
  if( ( tmp = finish(dice) ) == 0 ){
    mincost = min(mincost,cost);
    return;
  }

  if( tmp )tmp--;
  if( cost + tmp >= mincost ) return;

  rep(i,4){
    if( i == pre ) continue;
    int nx = x + dx[i], ny = y + dy[i];
    if( !( 0 <= nx && nx < 3 && 0 <= ny && ny < 3 ) ) continue;
    swap_dice(dice,x,y,nx,ny,i);
    dfs(dice,nx,ny,cost+1,(i+2)%4);
    swap_dice(dice,nx,ny,x,y,(i+2)%4);
  }
}

int main(){

  int x,y;
  while(scanf("%d%d",&x,&y),x|y){
    x--,y--;
    mincost = 31;
    rep(i,3)rep(j,3)cin >> F[i][j];

    Dice<char> dice[3][3];
    rep(i,3)rep(j,3)rep(k,6)dice[i][j][face[k]] = ((i==y&&j==x)?'E':initial_color[k]);

    dfs(dice,x,y,0,-1);

    if( mincost == 31 ) puts("-1");
    else                printf("%d\n",mincost);

  }
  return 0;
}
accuracy: 1
time_ms: 800
memory_kb: 1216
final_rank: 4

code_snippet: #include<bits/stdc++.h>

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define IINF (INT_MAX)
#define LEN 2

using namespace std;

typedef long long ll;

enum FACE { TOP, BOTTOM, FRONT, BACK, LEFT, RIGHT };
template <class T>
class Dice {
public:
  Dice() {
    id[TOP] = 0; id[FRONT] = 1; id[LEFT] = 2;
    id[RIGHT] = 3; id[BACK] = 4; id[BOTTOM] = 5;
  }
  T& operator[] (FACE f) { return var[id[f]]; }
  const T& operator[] (FACE f) const { return var[id[f]]; }
  bool operator==(const Dice<T>& b) const {
    const Dice<T> &a = *this;
    return a[TOP] == b[TOP] && a[BOTTOM] == b[BOTTOM] &&
      a[FRONT] == b[FRONT] && a[BACK] == b[BACK] &&
      a[LEFT] == b[LEFT] && a[RIGHT] == b[RIGHT];
  }
  void roll_x() { roll(TOP, BACK, BOTTOM, FRONT); }
  void roll_y() { roll(TOP, LEFT, BOTTOM, RIGHT); }
  void roll_z() { roll(FRONT, RIGHT, BACK, LEFT); }
  vector<Dice> all_rolls() {
    vector<Dice> ret;
    for (int k = 0; k < 6; (k&1?roll_y():roll_x()),++k)
      for (int i = 0; i < 4; roll_z(), ++i)
        ret.push_back(*this);
    return ret;
  }
  bool equivalent_to(const Dice& di) {
    for (int k = 0; k < 6; (k&1?roll_y():roll_x()),++k)
      for (int i = 0; i < 4; roll_z(), ++i)
        if (*this == di) return true;
    return false;
  }
private:
  void roll(FACE a, FACE b, FACE c, FACE d) {
    T tmp = id[a];
    id[a] = id[b]; id[b] = id[c];
    id[c] = id[d]; id[d] = tmp;
  }
  T var[6];
  int id[6];
};

FACE face[] = {TOP,BOTTOM,FRONT,BACK,LEFT,RIGHT};

int around[6][4] = 
  {
    {1,2,4,3},
    {0,3,5,2},
    {0,1,5,4},
    {0,4,5,1},
    {0,2,5,3},
    {1,3,4,2}
  };


Dice<int> makeDice(int top,int front){
  Dice<int> ret;
  ret[TOP] = top, ret[BOTTOM] = 5-top;
  ret[FRONT] = front, ret[BACK] = 5-front;
  int idx = IINF;
  for(int i=0;i<4;i++){
    if(around[top][i] == front){
      idx = i+1;
      break;
    }
  }
  assert(idx != IINF);
  idx %= 4;
  ret[RIGHT] = around[top][idx], ret[LEFT] = 5-around[top][idx];
  return ret;
}

inline int toInt(char c){ return ((c=='B')?0:((c=='E')?1:((c=='R')?2:3))); }
char F[3][3];
char initial_color[] = {'W','W','R','R','B','B'};
int mincost;
int dx[] = {1,0,-1,0}; // R, B, L, T
int dy[] = {0,1,0,-1};

inline void swap_dice(Dice<char> dice[3][3],int x1,int y1,int x2,int y2,int type){
  if( type == 0 ) rep(i,3)dice[y2][x2].roll_y();
  if( type == 1 ) rep(i,3)dice[y2][x2].roll_x();
  if( type == 2 ) dice[y2][x2].roll_y();
  if( type == 3 ) dice[y2][x2].roll_x();
  swap(dice[y1][x1],dice[y2][x2]);
}

inline int finish(Dice<char> dice[3][3]){
  int diff = 0;
  rep(i,3)rep(j,3)if( dice[i][j][TOP] != F[i][j] ) diff++;
  return diff;
}

void dfs(Dice<char> dice[3][3],int x,int y,int cost,int pre){

  if( cost >= mincost) return;

  int tmp;
  if( ( tmp = finish(dice) ) == 0 ){
    mincost = min(mincost,cost);
    return;
  }

  if( tmp )tmp--;
  if( cost + tmp >= mincost ) return;

  rep(i,4){
    if( i == pre ) continue;
    int nx = x + dx[i], ny = y + dy[i];
    if( !( 0 <= nx && nx < 3 && 0 <= ny && ny < 3 ) ) continue;
    swap_dice(dice,x,y,nx,ny,i);
    dfs(dice,nx,ny,cost+1,(i+2)%4);
    swap_dice(dice,nx,ny,x,y,(i+2)%4);
  }
}

int main(){

  int x,y;
  while(cin>>x>>y,x|y){
    x--,y--;
    mincost = 31;
    rep(i,3)rep(j,3)cin >> F[i][j];

    Dice<char> dice[3][3];
    rep(i,3)rep(j,3)rep(k,6)dice[i][j][face[k]] = initial_color[k];
    rep(k,6)dice[y][x][face[k]] = 'E';

    dfs(dice,x,y,0,-1);

    if( mincost == 31 ) puts("-1");
    else                printf("%d\n",mincost);

  }
  return 0;
}
accuracy: 1
time_ms: 800
memory_kb: 1156
final_rank: 3

code_snippet: #include<bits/stdc++.h>

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define IINF (INT_MAX)
#define LEN 2

using namespace std;

typedef long long ll;

enum FACE { TOP, BOTTOM, FRONT, BACK, LEFT, RIGHT };
template <class T>
class Dice {
public:
  Dice() {
    id[TOP] = 0; id[FRONT] = 1; id[LEFT] = 2;
    id[RIGHT] = 3; id[BACK] = 4; id[BOTTOM] = 5;
  }
  T& operator[] (FACE f) { return var[id[f]]; }
  const T& operator[] (FACE f) const { return var[id[f]]; }
  bool operator==(const Dice<T>& b) const {
    const Dice<T> &a = *this;
    return a[TOP] == b[TOP] && a[BOTTOM] == b[BOTTOM] &&
      a[FRONT] == b[FRONT] && a[BACK] == b[BACK] &&
      a[LEFT] == b[LEFT] && a[RIGHT] == b[RIGHT];
  }
  void roll_x() { roll(TOP, BACK, BOTTOM, FRONT); }
  void roll_y() { roll(TOP, LEFT, BOTTOM, RIGHT); }
  void roll_z() { roll(FRONT, RIGHT, BACK, LEFT); }
  vector<Dice> all_rolls() {
    vector<Dice> ret;
    for (int k = 0; k < 6; (k&1?roll_y():roll_x()),++k)
      for (int i = 0; i < 4; roll_z(), ++i)
        ret.push_back(*this);
    return ret;
  }
  bool equivalent_to(const Dice& di) {
    for (int k = 0; k < 6; (k&1?roll_y():roll_x()),++k)
      for (int i = 0; i < 4; roll_z(), ++i)
        if (*this == di) return true;
    return false;
  }
private:
  void roll(FACE a, FACE b, FACE c, FACE d) {
    T tmp = id[a];
    id[a] = id[b]; id[b] = id[c];
    id[c] = id[d]; id[d] = tmp;
  }
  T var[6];
  int id[6];
};

FACE face[] = {TOP,BOTTOM,FRONT,BACK,LEFT,RIGHT};

int around[6][4] = 
  {
    {1,2,4,3},
    {0,3,5,2},
    {0,1,5,4},
    {0,4,5,1},
    {0,2,5,3},
    {1,3,4,2}
  };


Dice<int> makeDice(int top,int front){
  Dice<int> ret;
  ret[TOP] = top, ret[BOTTOM] = 5-top;
  ret[FRONT] = front, ret[BACK] = 5-front;
  int idx = IINF;
  for(int i=0;i<4;i++){
    if(around[top][i] == front){
      idx = i+1;
      break;
    }
  }
  assert(idx != IINF);
  idx %= 4;
  ret[RIGHT] = around[top][idx], ret[LEFT] = 5-around[top][idx];
  return ret;
}

inline int toInt(char c){ return ((c=='B')?0:((c=='E')?1:((c=='R')?2:3))); }
char F[3][3];
char initial_color[] = {'W','W','R','R','B','B'};
int mincost;
int dx[] = {1,0,-1,0}; // R, B, L, T
int dy[] = {0,1,0,-1};

inline void swap_hash(ll &hash,int x1,int y1,int x2,int y2){
  int pos1 = x1 + y1 * 3, pos2 = x2 + y2 * 3;
  ll bitmask1 = (1LL<<4LL)-1LL;
  ll bitmask2 = ~( ( bitmask1<<(pos1*4LL) ) | ( bitmask1<<(pos2*4LL) ) );
  ll tmp1 = ( ( ( bitmask1<<(pos1*4LL) ) & hash ) >> (pos1*4LL) );
  ll tmp2 = ( ( ( bitmask1<<(pos2*4LL) ) & hash ) >> (pos2*4LL) );
  ll tmp3 = hash & bitmask2;
  assert( hash == (tmp3|(tmp1<<(pos1*4LL))|(tmp2<<(pos2*4LL)) ) );
  tmp3 |= (tmp1<<(pos2*4LL)) | (tmp2<<(pos1*4LL));
}

inline void hash_set(ll &hash,int x,int y,char fr,char rg){
  int pos = x + y * 3;
  ll bitmask = (1LL<<4LL)-1LL;
  ll rbitmask = ~(bitmask<<(pos*4LL));
  hash &= rbitmask;
  ll add1 = (toInt(rg))<<(pos*4+3);
  ll add2 = (toInt(fr))<<(pos*4);
  hash = hash|add1|add2;
}

inline void swap_dice(Dice<char> dice[3][3],int x1,int y1,int x2,int y2,int type){
  if( type == 0 ) rep(i,3)dice[y2][x2].roll_y();
  if( type == 1 ) rep(i,3)dice[y2][x2].roll_x();
  if( type == 2 ) dice[y2][x2].roll_y();
  if( type == 3 ) dice[y2][x2].roll_x();
  swap(dice[y1][x1],dice[y2][x2]);
}

inline int finish(Dice<char> dice[3][3]){
  int diff = 0;
  rep(i,3)rep(j,3)if( dice[i][j][TOP] != F[i][j] ) diff++;
  return diff;
}

void dfs(Dice<char> dice[3][3],ll hash,int x,int y,int cost,int pre){
  /*
  cout << "cost = " << cost << " empty(" << x << "," << y << ")" << endl;
  bitset<63> BIT(hash);
  cout << "hash : " << BIT << endl;
  rep(i,3){
    rep(j,3){
      cout << dice[i][j][TOP];
    }
    cout << endl;
  }
  */
  if( cost >= mincost) return;

  int tmp;
  if( ( tmp = finish(dice) ) == 0 ){
    mincost = min(mincost,cost);
    return;
  }

  if( tmp )tmp--;
  if( cost + tmp >= mincost ) return;

  rep(i,4){
    if( i == pre ) continue;
    int nx = x + dx[i], ny = y + dy[i];
    if( !( 0 <= nx && nx < 3 && 0 <= ny && ny < 3 ) ) continue;
    swap_dice(dice,x,y,nx,ny,i);
    ll new_hash = hash;
    hash_set(new_hash,x,y,dice[y][x][TOP],dice[y][x][RIGHT]);
    hash_set(new_hash,nx,ny,dice[ny][nx][TOP],dice[ny][nx][RIGHT]);
    swap_hash(new_hash,x,y,nx,ny);
    dfs(dice,new_hash,nx,ny,cost+1,(i+2)%4);
    swap_dice(dice,nx,ny,x,y,(i+2)%4);
  }

}

int main(){
  /*
    Dice<char> d;
    string LINE[6] = {"TOP   ","BOTTOM","FRONT ","BACK  ","LEFT  ","RIGHT "};
    rep(i,6) d[face[i]] = initial_color[i];
    rep(i,6) cout << LINE[i] << " : " << d[face[i]] << endl;
    d.roll_z();
    cout << endl;
    rep(i,6) cout << LINE[i] << " : " << d[face[i]] << endl;
  */

  int x,y;
  while(cin>>x>>y,x|y){
    x--,y--;
    mincost = 31;
    rep(i,3)rep(j,3)cin >> F[i][j];

    Dice<char> dice[3][3];
    rep(i,3)rep(j,3)rep(k,6)dice[i][j][face[k]] = initial_color[k];
    rep(k,6)dice[y][x][face[k]] = 'E';

    ll hash = 0LL;
    for(int i=2;i>=0;i--)for(int j=2;j>=0;j--){
	hash <<= LEN;
	hash += toInt(dice[i][j][RIGHT]);
	hash <<= LEN;
	hash += toInt(dice[i][j][TOP]);
      }

    dfs(dice,hash,x,y,0,-1);

    if( mincost == 31 ) puts("-1");
    else                printf("%d\n",mincost);

  }
  return 0;
}
accuracy: 1
time_ms: 1180
memory_kb: 1156
final_rank: 7

code_snippet: #include<iostream>
#include<cmath>

using namespace std;
#define LIMIT 30
 
struct Puzzle {
  char cont[9][3];
  int space; 
};
 
 
int dx[4]={ 0, 1, 0,-1};
int dy[4]={-1, 0, 1, 0};
 
int limit;
Puzzle puzzle;
char target[9];
 
 
int getHeuristic(){
  int sum = 0;
  for(int i=0;i<9;i++){
    if(puzzle.cont[i][0]=='E')continue;
    sum+=(puzzle.cont[i][0]!=target[i]?1:0);
  }
  return sum;
}
 
bool dfs(int depth,int prev){

  int heuri=getHeuristic();

  if(heuri==0){return true;}
  if(depth+heuri> limit )return false;
 
  
  int px,py,nx,ny;
  Puzzle tmp;
 
  px=puzzle.space%3;
  py=puzzle.space/3;

  tmp=puzzle;
  for(int i=0;i<4;i++){
    nx=px+dx[i];
    ny=py+dy[i];
    if(max(prev,i)-min(prev,i)==2)continue;
 
    if(nx<0||ny<0||nx>=3||ny>=3)continue;
 
     
 
    if(i%2){
      // puzzle.cont[py*3+px]=rb(puzzle.cont[ny*3+nx]);
      puzzle.cont[py*3+px][0]=puzzle.cont[ny*3+nx][2];
      puzzle.cont[py*3+px][1]=puzzle.cont[ny*3+nx][1];
      puzzle.cont[py*3+px][2]=puzzle.cont[ny*3+nx][0];
    }else{
      //  puzzle.cont[py*3+px]=ra(puzzle.cont[ny*3+nx]);
      puzzle.cont[py*3+px][0]=puzzle.cont[ny*3+nx][1];
      puzzle.cont[py*3+px][1]=puzzle.cont[ny*3+nx][0];
      puzzle.cont[py*3+px][2]=puzzle.cont[ny*3+nx][2];
    }
 
    puzzle.space=ny*3+nx;
    puzzle.cont[puzzle.space][0]='E';


    
    
    if(dfs(depth+1,i))return true;
    puzzle=tmp;
  }
  return false;
}

Puzzle in;
void solve(){
  int d;
  d=getHeuristic();
  for(limit=d;limit <= LIMIT ; limit++ ){
    
    if(dfs(0,-100)){
      cout<<limit<<endl;
      return;
    }
 
  }
  cout<<"-1"<<endl;
 
}
 
int main(){
  int x,y;
  while(cin>>x>>y){
    if(x==0&&y==0)break;
    x--;y--;
 
    puzzle.space=y*3+x;
    for(int i=0;i<9;i++){
      cin>>target[i];
      if(i/3==y&&i%3==x){
	puzzle.cont[i][0]='E';
      }else{
	puzzle.cont[i][0]='W';
	puzzle.cont[i][1]='R';
	puzzle.cont[i][2]='B';
      }
    }
    solve(); 
  }
  return 0;
}
accuracy: 1
time_ms: 910
memory_kb: 1160
final_rank: 5

code_snippet: #include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>

using namespace std;

#define FOR(i,k,n) for(int i=(k); i<(int)(n); ++i)
#define REP(i,n) FOR(i,0,n)
#define FORIT(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)

template<class T> void debug(T begin, T end){ for(T i = begin; i != end; ++i) cerr<<*i<<" "; cerr<<endl; }
inline bool valid(int x, int y, int W, int H){ return (x >= 0 && y >= 0 && x < W && y < H); }

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
// w, r, b
// w, b, r
// r, w, b
// r, b, w
// b, w, r
// b, r, w
int hori[6] = {5, 3, 4, 1, 2, 0};
int vert[6] = {2, 4, 0, 5, 1, 3};
int top[6] = {0, 0, 1, 1, 2, 2};
char WRB[] = "WRB";
struct S{
  vector<int> grid;
  int time;
};
int main(){
  // white, red, blue
  int sx, sy;
  while(cin >> sx >> sy && sx){
    sx--; sy--;
    char goal[3][3];
    REP(i, 3) REP(j, 3) cin >> goal[i][j];
    vector<int> goal_v;
    REP(i, 3) REP(j, 3) {
      if(goal[i][j] == 'E') goal_v.push_back(-1);
      REP(k, 3) if(WRB[k] == goal[i][j]) goal_v.push_back(k);
    }
    S start;
    start.time = 0;
    REP(i, 3) REP(j, 3){
      if(sy == i && sx == j) start.grid.push_back(-1);
      else start.grid.push_back(0);
    }
    queue<S> que;
    que.push(start);
    static bool used[1700000][9] = {};
    memset(used, 0, sizeof(used));
    int ans = -1;
    int pow6[10] = {};
    pow6[0] = 1; REP(i, 9) pow6[i + 1] = pow6[i] * 6;
    while(!que.empty()){
      S s = que.front(); que.pop();
      if(s.time > 30) break;
      int hstar = 0;
      REP(i, 9) if(s.grid[i] != -1 && top[s.grid[i]] != goal_v[i]) hstar ++;
      if(hstar == 0){
        ans = s.time;
        break;
      }
      if(s.time + hstar > 30) continue;
      REP(y, 3) REP(x, 3) {
        if(s.grid[y * 3 + x] == -1){
          REP(r, 4){
            int fx = x + dx[r];
            int fy = y + dy[r];
            if(!valid(fx, fy, 3, 3)) continue;
            S next = s;
            next.time++;
            next.grid[y * 3 + x] = (r % 2 ? vert[s.grid[fy * 3 + fx]] : hori[s.grid[fy * 3 + fx]]);
            next.grid[fy * 3 + fx] = -1;
            int hash = 0;
            int c = 0;
            REP(i, 9) if(next.grid[i] != -1) hash += next.grid[i] * pow6[c++];
            if(used[hash][fy * 3 + fx]) continue;
            used[hash][fy * 3 + fx] = true;
            que.push(next);
          }
        }
      }
    }
      cout << ans << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 1920
memory_kb: 35824
final_rank: 13

code_snippet: #include<cstdio>
#include<algorithm>

#define rep(i,n) for(int i=0;i<(n);i++)

using namespace std;

char goal[3][3],gx,gy;

char T[3][3],F[3][3],R[3][3]; // top, front, right

int hstar(int ex,int ey,int gx,int gy){
	int cnt=0;
	rep(i,3) rep(j,3) if(!(i==ey && j==ex) && T[i][j]!=goal[i][j]) cnt++;
	return max(cnt,abs(ex-gx)+abs(ey-gy));
}

int ub;
bool dfs(int t,int ex,int ey,int pre){ // 経過ターン, スペースの位置, 直前移動した方向
	bool end=true;
	rep(i,3) rep(j,3) if(!(i==ey && j==ex) && T[i][j]!=goal[i][j]) end=false;
	if(end) return true;

	if(t+hstar(ex,ey,gx,gy)>ub) return false;

	char tmp1,tmp2,tmp3;
	// (ex,ey-1)
	if(ey>0 && pre!=1){
		tmp1=T[ey][ex]=F[ey-1][ex];
		tmp2=F[ey][ex]=T[ey-1][ex];
		tmp3=R[ey][ex]=R[ey-1][ex];
		if(dfs(t+1,ex,ey-1,0)) return true;
		F[ey-1][ex]=tmp1;
		T[ey-1][ex]=tmp2;
		R[ey-1][ex]=tmp3;
	}
	// (ex,ey+1)
	if(ey<2 && pre!=0){
		tmp1=T[ey][ex]=F[ey+1][ex];
		tmp2=F[ey][ex]=T[ey+1][ex];
		tmp3=R[ey][ex]=R[ey+1][ex];
		if(dfs(t+1,ex,ey+1,1)) return true;
		F[ey+1][ex]=tmp1;
		T[ey+1][ex]=tmp2;
		R[ey+1][ex]=tmp3;
	}
	// (ex-1,ey)
	if(ex>0 && pre!=3){
		tmp1=T[ey][ex]=R[ey][ex-1];
		tmp2=F[ey][ex]=F[ey][ex-1];
		tmp3=R[ey][ex]=T[ey][ex-1];
		if(dfs(t+1,ex-1,ey,2)) return true;
		R[ey][ex-1]=tmp1;
		F[ey][ex-1]=tmp2;
		T[ey][ex-1]=tmp3;
	}
	// (ex+1,ey)
	if(ex<2 && pre!=2){
		tmp1=T[ey][ex]=R[ey][ex+1];
		tmp2=F[ey][ex]=F[ey][ex+1];
		tmp3=R[ey][ex]=T[ey][ex+1];
		if(dfs(t+1,ex+1,ey,3)) return true;
		R[ey][ex+1]=tmp1;
		F[ey][ex+1]=tmp2;
		T[ey][ex+1]=tmp3;
	}
	return false;
}

int main(){
	for(int ex,ey;scanf("%d%d",&ex,&ey),ex;){
		ex--; ey--;
		rep(i,3) rep(j,3) {
			scanf(" %c",goal[i]+j);
			if(goal[i][j]=='E') gx=j, gy=i;
			T[i][j]='W';
			F[i][j]='R';
			R[i][j]='B';
		}

		for(ub=(abs(ex-gx)+abs(ey-gy))%2;ub<=30&&!dfs(0,ex,ey,-1);ub+=2);

		printf("%d\n",ub<=30?ub:-1);
	}

	return 0;
}
accuracy: 1
time_ms: 580
memory_kb: 1028
final_rank: 2

code_snippet: #include<cstdio>
#include<algorithm>

#define rep(i,n) for(int i=0;i<(n);i++)

using namespace std;

char goal[3][3],gx,gy;

char T[3][3],F[3][3],R[3][3]; // top, front, right

int hstar(int ex,int ey,int gx,int gy){
	int cnt=0;
	rep(i,3) rep(j,3) if(!(i==ey && j==ex) && T[i][j]!=goal[i][j]) cnt++;
	return max(cnt,abs(ex-gx)+abs(ey-gy));
}

int ub;
bool dfs(int t,int ex,int ey,int pre){ // 経過ターン, スペースの位置, 直前移動した方向
	bool end=true;
	rep(i,3) rep(j,3) if(!(i==ey && j==ex) && T[i][j]!=goal[i][j]) end=false;
	if(end) return true;

	if(t+hstar(ex,ey,gx,gy)>ub) return false;

	// (ex,ey-1)
	char tmp1,tmp2,tmp3;
	if(ey>0 && pre!=1){
		tmp1=T[ey][ex]=F[ey-1][ex];
		tmp2=F[ey][ex]=T[ey-1][ex];
		tmp3=R[ey][ex]=R[ey-1][ex];
		if(dfs(t+1,ex,ey-1,0)) return true;
		F[ey-1][ex]=tmp1;
		T[ey-1][ex]=tmp2;
		R[ey-1][ex]=tmp3;
	}
	// (ex,ey+1)
	if(ey<2 && pre!=0){
		tmp1=T[ey][ex]=F[ey+1][ex];
		tmp2=F[ey][ex]=T[ey+1][ex];
		tmp3=R[ey][ex]=R[ey+1][ex];
		if(dfs(t+1,ex,ey+1,1)) return true;
		F[ey+1][ex]=tmp1;
		T[ey+1][ex]=tmp2;
		R[ey+1][ex]=tmp3;
	}
	// (ex-1,ey)
	if(ex>0 && pre!=3){
		tmp1=T[ey][ex]=R[ey][ex-1];
		tmp2=F[ey][ex]=F[ey][ex-1];
		tmp3=R[ey][ex]=T[ey][ex-1];
		if(dfs(t+1,ex-1,ey,2)) return true;
		R[ey][ex-1]=tmp1;
		F[ey][ex-1]=tmp2;
		T[ey][ex-1]=tmp3;
	}
	// (ex+1,ey)
	if(ex<2 && pre!=2){
		tmp1=T[ey][ex]=R[ey][ex+1];
		tmp2=F[ey][ex]=F[ey][ex+1];
		tmp3=R[ey][ex]=T[ey][ex+1];
		if(dfs(t+1,ex+1,ey,3)) return true;
		R[ey][ex+1]=tmp1;
		F[ey][ex+1]=tmp2;
		T[ey][ex+1]=tmp3;
	}
	return false;
}

int main(){
	for(int x0,y0;scanf("%d%d",&x0,&y0),x0;){
		x0--; y0--;
		rep(i,3) rep(j,3) {
			scanf(" %c",goal[i]+j);
			if(goal[i][j]=='E') gx=j, gy=i;
			T[i][j]='W';
			F[i][j]='R';
			R[i][j]='B';
		}

		for(ub=0;ub<=30&&!dfs(0,x0,y0,-1);ub++);

		printf("%d\n",ub<=30?ub:-1);
	}

	return 0;
}
accuracy: 1
time_ms: 1550
memory_kb: 1028
final_rank: 8