Problem:
Jigsaw Puzzles for Computers
Ordinary Jigsaw puzzles are solved with visual hints;
players solve a puzzle with the picture which the puzzle shows on finish,
and the diverse patterns of pieces. 
Such Jigsaw puzzles may be suitable for human players,
because they require abilities of pattern recognition and imagination.
On the other hand,
"Jigsaw puzzles" described below may be just the things for
simple-minded computers.
As shown in
Figure 1
,
 a puzzle is composed of nine square pieces, and each of the four edges
of a piece is labeled with one of the following eight symbols:
"R", "G", "B", "W", "r", "g", "b"
, and
"w".
Figure 1
: The nine pieces of a puzzle
In a completed puzzle, the nine pieces are arranged in a 3 x 3 grid,
and each of the 12 pairs of edges facing each other 
must be labeled with one of the
following four combinations of symbols:
"R"
with
"r"
,
"G"
with
"g"
,
"B"
with
"b"
, and
"W"
with
"w"
.
For example, an edge labeled
"R"
can only face an edge with
"r"
.
Figure 2
is an example of a completed state of a puzzle.
In the figure, edges under this restriction are indicated by shadowing their labels.
The player can freely move and rotate the pieces, but cannot turn them over.
There are no symbols on the reverse side of a piece !
Figure 2
: A completed puzzle example
Each piece is represented by a sequence of the four symbols
on the piece, starting with the symbol of the top edge,
followed by the symbols of the right edge, the bottom edge,
and the left edge.
For example,
gwgW
represents the leftmost piece in
Figure 1
.
Note that the same piece can be represented as
wgWg
,
gWgw
or
Wgwg
since you can rotate it in 90, 180 or 270 degrees.
The mission for you
is to create a program which counts the number
of solutions.
It is needless to say that these numbers must be multiples of four,
because, as shown in
Figure 3
,
a configuration created by rotating a solution in 90, 180 or 270 degrees
is also a solution.
Figure 3
: Four obvious variations for a completed puzzle
A term
"rotationally equal"
is defined; if two different pieces are
identical when one piece is rotated (in 90, 180 or 270 degrees),
they are rotationally equal. For example,
WgWr
and
WrWg
are rotationally equal.
Another term
"rotationally symmetric"
is defined; if a piece is
rotationally equal to itself, it is rotationally symmetric. 
For example, a piece
gWgW
is rotationally symmetric.
Given puzzles satisfy the following three conditions:
There is no identical pair of pieces in a puzzle.
There is no
rotationally equal
pair of pieces in a puzzle.
There is no
rotationally symmetric
piece in a puzzle.
Input
The input consists of multiple puzzles.
N
Puzzle
1
Puzzle
2
. . .
Puzzle
N
N
is the number of puzzles. Each
Puzzle
i
gives a puzzle with a single line
of 44 characters, consisting of four-character representations of the nine
pieces of the puzzle, separated by a space character. 
For example, the following line represents the puzzle
in
Figure 1
.
gwgW RBbW GWrb GRRb BWGr Rbgw
...(truncated)

Submitted solutions:

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define FOR(i,l,r) for(ll i=l;i<r;i++)
#define REP(i,n) FOR(i,0,n)
#define ALL(A) A.begin(),A.end()
bool match(char a,char b){
    return abs(a-b)==32;
}
int f(string s,char a,char b){
    int res=0;
    REP(i,4)if(match(s[i],a)&&match(s[(i+1)%4],b))res++;
    return res;
}
int main(){
    ll N;cin>>N;
    while(N--){
        vector<string>S(9);
        REP(i,9)cin>>S[i];
        REP(i,9)reverse(ALL(S[i]));
        ll ans=0;
        sort(ALL(S));
        do{
            REP(i,4)if(match(S[0][0],S[1][i])){
                REP(j,4)if(match(S[0][1],S[2][j])){
                    REP(k,4)if(match(S[0][2],S[3][k])){
                        REP(l,4)if(match(S[0][3],S[4][l])){
                            ans+=4*f(S[5],S[1][(i+1)%4],S[4][(l+3)%4])*f(S[6],S[2][(j+1)%4],S[1][(i+3)%4])*f(S[7],S[3][(k+1)%4],S[2][(j+3)%4])*f(S[8],S[4][(l+1)%4],S[3][(k+3)%4]);
                        }
                    }
                }
            }
        }while(next_permutation(ALL(S)));
        cout<<ans<<endl;
    }
    return 0;
}
accuracy: 1
time_ms: 410
memory_kb: 3340
final_rank: 15

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) { return (ull)rng() % B; }

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    auto match = [&](char c1, char c2) -> bool { return abs((int)c1 - (int)c2) == 32; };
    int q;
    cin >> q;
    while (q--) {
        vector<string> s(9);
        for (int i = 0; i < 9; ++i) {
            cin >> s[i];
        }
        vector<string> v(9);
        auto dfs = [&](auto dfs, int i, int bit) -> int {
            if (i == 9) return 1;
            int res = 0;
            for (int j = 0; j < 9; ++j) {
                if ((1 << j) & bit) continue;
                for (int k = 0; k < 4; ++k) {
                    string t = s[j].substr(k) + s[j].substr(0, k);
                    if (i >= 3 and !match(t[0], v[i - 3][2])) continue;
                    if (i % 3 and !match(t[1], v[i - 1][3])) continue;
                    v[i] = t;
                    res += dfs(dfs, i + 1, bit + (1 << j));
                }
            }
            return res;
        };
        cout << dfs(dfs, 0, 0) << "\n";
    }
}
accuracy: 1
time_ms: 80
memory_kb: 3156
final_rank: 13

code_snippet: #include<stdio.h>
#include<stdlib.h>
#include<math.h>

char piece[9][4];
char current[9][4];
int is_using[9] = { 0 };

int tryJigsaw( int num )
{
    if( num == 9 ) return 1;

    int count = 0;
    for( int i = 0; i < 9; i++ )
    {
        if( is_using[i] ) continue;
        for( int j = 0; j < 4; j++ )
        {
            if( num > 2 && abs( current[num - 3][2] - piece[i][( 0 + j ) % 4] ) != 32 ) continue;
            if( num % 3 != 0 && abs( current[num - 1][1] - piece[i][( 3 + j ) % 4] ) != 32 ) continue;

            for( int k = 0; k < 4; k++ )
            {
                current[num][k] = piece[i][( j + k ) % 4];
            }
            is_using[i] = 1;
            count += tryJigsaw( num + 1 );
            is_using[i] = 0;
            for( int k = 0; k < 4; k++ )
            {
                current[num][k] = '.';
            }
        }
    }

    return count;
}

int main( void )
{
    int N;
    scanf( "%d", &N );

    while( N-- > 0 )
    {
        for( int i = 0; i < 9; i++ )
        {
            scanf( "%s", piece[i] );
        }
        for( int k = 0; k < 9; k++ )
        {
            for( int i = 0; i < 4; i++ )
            {
                current[k][i] = '.';
            }
        }

        printf( "%d\n", tryJigsaw( 0 ) );
    }

    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 2792
final_rank: 8

code_snippet: #include<iostream>
#include<vector>

using namespace std;

string puzzle[9];
int ans;

char ToLower(char c)
{
	if (c >= 97 && c <= 122)
		return c;
	return char(c + 32);
}
char GetLabel(string puzzle, int rotateD, int dir)
{
	return puzzle[(rotateD / 90 + dir) % 4];
}
vector<int> TryMatch(string puzzle,char upLabel,char leftLabel)
{
	vector<int> result;
	for (int d = 0; d < 360; d += 90)
	{
		char upL = GetLabel(puzzle, d, 0);
		char LeftL = GetLabel(puzzle, d, 3);
		if (upL != upLabel && (ToLower(upL) == ToLower(upLabel) || upLabel == ' ') &&
			LeftL != leftLabel && (ToLower(LeftL) == ToLower(leftLabel) || leftLabel == ' '))
			result.push_back(d);
	}

	return result;
}

void DP(vector<pair<int,int>>& crtPuzzle)
{
	int crtIndex = crtPuzzle.size();
	if (crtIndex == 9)
	{
		ans++;
		return;
	}

	char upLabel = ' ';
	if (crtIndex / 3 > 0)
	{
		pair<int, int> p = crtPuzzle[crtIndex - 3];
		upLabel = GetLabel(puzzle[p.first], p.second, 2);
	}
	char leftLabel = ' ';
	if (crtIndex % 3 != 0)
	{
		pair<int, int> p = crtPuzzle[crtIndex - 1];
		leftLabel = GetLabel(puzzle[p.first], p.second, 1);
	}

	bool used[9];
	fill(used, used + 9, false);
	for (auto& p : crtPuzzle)
		used[p.first] = true;
	for (int i = 0; i < 9; i++)
	{
		if (used[i]) continue;
		vector<int> ds = TryMatch(puzzle[i], upLabel, leftLabel);
		for (int d : ds)
		{
			crtPuzzle.push_back(make_pair(i, d));
			DP(crtPuzzle);
			crtPuzzle.pop_back();
		}
	}
}

int main()
{
	int N;
	cin >> N;
	while (N-- != 0)
	{
		ans = 0;
		for (int i = 0; i < 9; i++)
			cin >> puzzle[i];
		vector<pair<int, int>> crtPuzzle;
		DP(crtPuzzle);
		cout << ans << endl;
	}
}
accuracy: 1
time_ms: 90
memory_kb: 3296
final_rank: 14

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

bool used[9];
string p[9];
string piece_str[9];
string rot(string s){
    return s[3] + s.substr(0, 3);
}
bool match(char a, char b){
    return max(a, b) -min(a, b) == 32;
}
int solve(int a){
    if(a == 9) return 1;
    int res = 0;
    for(int i=0; i<9; i++){
        if(used[i]) continue;
        string s = p[i];
        for(int d=0; d<4; d++, s=rot(s)){
            bool ok = true;
            if(a>=3 and !match(s[0], piece_str[a-3][2])) ok = false;
            if(a%3!=0 and !match(s[1], piece_str[a-1][3])) ok = false;
            if(!ok) continue;
            piece_str[a] = s;
            used[i] = true;
            res += solve(a + 1);
            used[i] = false;
        }
    }
    return res;
}

int main(){
    int nt;
    cin >> nt;
    for(int rep=0; rep<nt; rep++){
        for(int i=0; i<9; i++){
            cin >> p[i];
        }
        cout << solve(0) << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 640
memory_kb: 3152
final_rank: 16

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

using namespace std;

char grid[5][5][4];
char puzzles[9][7];
bool mask[5][5]={
    {1,1,1,1,1},
    {1,0,0,0,1},
    {1,0,0,0,1},
    {1,0,0,0,1},
    {1,1,1,1,1}
};

const int diff=abs('A'-'a');

int solve(int pos,int comb){
    // printf("pos=%d\n",pos);
    if (pos>=9) return 1;
    int x=pos%3+1,y=pos/3+1;
    int ret=0;

    //全てのパズルを試す
    for(int pid=0;pid<9;pid++){
        if ((1<<pid)&comb) continue;
        // printf("pid=%d\n",pid);
        const auto &pz=puzzles[pid];

        //パズルを回す
        for(int r=0;r<4;r++){
            if (!mask[x-1][y]&&abs(grid[x-1][y][2]-pz[r])!=diff) continue;
            if (!mask[x][y-1]&&abs(grid[x][y-1][3]-pz[(r+1)%4])!=diff) continue;
            // puts("rot");
            for(int i=0;i<4;i++) grid[x][y][i]=pz[(r+i)%4];
            ret+=solve(pos+1,comb|(1<<pid));
        }

    }

    return ret;
}

int main(){

    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        for(int i=0;i<9;i++) scanf("%5s",puzzles+i);
        // for(int i=0;i<9;i++) printf("%s\n",puzzles+i);
        printf("%d\n",solve(0,0));

    }

    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 2580
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define rep(i,n)   FOR(i,0,n)
#define pb push_back
#define mp make_pair
typedef long long ll;
typedef pair<int,int> pint;

string p[9],m[9];
bool used[9];
int dfs(int cnt){
    int ret=0;
    if(cnt==9) return 1;
    rep(i,9){
        if(used[i]) continue;
        rep(j,4){
            if(cnt>0&&cnt%3==0){
                if(abs(m[cnt-3][2]-p[i][j])!=32) continue;
            }
            else if(cnt>2&&cnt%3!=0){
                if(abs(m[cnt-3][2]-p[i][j])!=32||abs(m[cnt-1][1]-p[i][(j+3)%4])!=32) continue;
            }
            else if(cnt<3&&cnt>0){
                if(abs(m[cnt-1][1]-p[i][(j+3)%4])!=32) continue;
            }
            used[i]=true;
            string rp=p[i];
            rotate_copy(p[i].begin(),p[i].begin()+j,p[i].end(),rp.begin());
            m[cnt]=rp;
            ret +=dfs(cnt+1);
            used[i]=false;
        }
    }
    return ret;
}
int main(){
    int n;
    cin>>n;
    while(n--){
        rep(i,9) cin>>p[i];
        cout<<dfs(0)<<endl;
    }
    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 3140
final_rank: 12

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
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;

enum Loc{
	Top,
	Right,
	Under,
	Left,
};

enum Roll{
	r_0,
	r_90,
	r_180,
	r_270,
};

Roll roll_type[4] = {r_0,r_90,r_180,r_270};

struct Data{
	int data_id;
	Roll roll;
};

struct Info{
	int next_loc;
	bool check[9];
	Data table[3][3];
};

void copyInfo(Info from,Info& to){
	for(int i = 0; i < 9; i++)to.check[i] = from.check[i];
	for(int i = 0; i < 3; i++){
		for(int k = 0; k < 3; k++){
			to.table[i][k].data_id = from.table[i][k].data_id;
			to.table[i][k].roll = from.table[i][k].roll;
		}
	}
}

int N,ans;
char data[9][4];

bool isMatch(char left,char right){

	if(left > right){
		swap(left,right);
	}

	if(left == 'R' && right == 'r'){
		return true;
	}else if(left == 'G' && right == 'g'){
		return true;
	}else if(left == 'B' && right == 'b'){
		return true;
	}else if(left == 'W' && right == 'w'){
		return true;
	}

	return false;
}

char getWord(int data_id,Roll roll,Loc loc){

	switch(roll){
	case r_0:
		switch(loc){
		case Top:
			return data[data_id][Top];
		case Right:
			return data[data_id][Right];
		case Under:
			return data[data_id][Under];
		case Left:
			return data[data_id][Left];
		}
		break;
	case r_90:
		switch(loc){
		case Top:
			return data[data_id][Left];
		case Right:
			return data[data_id][Top];
		case Under:
			return data[data_id][Right];
		case Left:
			return data[data_id][Under];
		}
		break;
	case r_180:
		switch(loc){
		case Top:
			return data[data_id][Under];
		case Right:
			return data[data_id][Left];
		case Under:
			return data[data_id][Top];
		case Left:
			return data[data_id][Right];
		}
		break;
	case r_270:
		switch(loc){
		case Top:
			return data[data_id][Right];
		case Right:
			return data[data_id][Under];
		case Under:
			return data[data_id][Left];
		case Left:
			return data[data_id][Top];
		}
		break;
	}
	return 'X'; //must not reach here
}


void recursive(Info info){

	if(info.next_loc == 9){
		ans++;
		return;
	}

	for(int i = 0; i < 9; i++){
		if(info.check[i] == false){

			switch(info.next_loc){
			case 1:
				for(int k = 0; k < 4; k++){
					if(isMatch(data[info.table[1][1].data_id][Top],getWord(i,roll_type[k],Under))){
						Info new_info;
						copyInfo(info,new_info);
						new_info.check[i] = true;
						new_info.table[0][1].data_id = i;
						new_info.table[0][1].roll = roll_type[k];
						new_info.next_loc = info.next_loc+1;
						recursive(new_info);
					}
				}
				break;
			case 2:
				for(int k = 0; k < 4; k++){
					if(isMatch(data[info.table[1][1].data_id][Right],getWord(i,roll_type[k],Left))){
						Info new_info;
						copyInfo(info,new_info);
						new_info.check[i] = true;
						new_info.table[1][2].data_id = i;
						new_info.table[1][2].roll = roll_type[k];
						new_info.next_loc = info.next_loc+1;
						recursive(new_info);
					}
				}
				break;
			case 3:
				for(int k = 0; k < 4; k++){
					if(isMatch(data[info.table[1][1].data_id][Under],getWord(i,roll_type[k],Top))){
						Info new_info;
						copyInfo(info,new_info);
						new_info.check[i] = true;
						new_info.table[2][1].data_id = i;
						new_info.table[2][1].roll = roll_type[k];
						new_info.next_loc = info.next_loc+1;
						recursive(new_info);
					}
				}
				break;
			case 4:
				for(int k = 0; k < 4; k++){
					if(isMatch(data[info.table[1][1].data_id][Left],getWord(i,roll_type[k],Right))){
						Info new_info;
						copyInfo(info,new_info);
						new_info.check[i] = true;
						new_info.table[1][0].data_id = i;
						new_info.table[1][0].roll = roll_type[k];
						new_info.next_loc = info.next_loc+1;
						recursive(new_info);
					}
				}
				break;
			case 5:
				for(int k = 0; k < 4; k++){
					if(isMatch(getWord(info.table[0][1].data_id,info.table[0][1].roll,Right),getWord(i,roll_type[k],Left)) == true &&
							isMatch(getWord(info.table[1][2].data_id,info.table[1][2].roll,Top),getWord(i,roll_type[k],Under)) == true){
						Info new_info;
						copyInfo(info,new_info);
						new_info.check[i] = true;
						new_info.table[0][2].data_id = i;
						new_info.table[0][2].roll = roll_type[k];
						new_info.next_loc = info.next_loc+1;
						recursive(new_info);
					}
				}
				break;
			case 6:
				for(int k = 0; k < 4; k++){
					if(isMatch(getWord(info.table[1][2].data_id,info.table[1][2].roll,Under),getWord(i,roll_type[k],Top)) == true &&
							isMatch(getWord(info.table[2][1].data_id,info.table[2][1].roll,Right),getWord(i,roll_type[k],Left)) == true){
						Info new_info;
						copyInfo(info,new_info);
						new_info.check[i] = true;
						new_info.table[2][2].data_id = i;
						new_info.table[2][2].roll = roll_type[k];
						new_info.next_loc = info.next_loc+1;
						recursive(new_info);
					}
				}
				break;
			case 7:
				for(int k = 0; k < 4; k++){
					if(isMatch(getWord(info.table[2][1].data_id,info.table[2][1].roll,Left),getWord(i,roll_type[k],Right)) == true &&
							isMatch(getWord(info.table[1][0].data_id,info.table[1][0].roll,Under),getWord(i,roll_type[k],Top)) == true){
						Info new_info;
						copyInfo(info,new_info);
						new_info.check[i] = true;
						new_info.table[2][0].data_id = i;
						new_info.table[2][0].roll = roll_type[k];
						new_info.next_loc = info.next_loc+1;
						recursive(new_info);
					}
				}
				break;
			case 8:
				for(int k = 0; k < 4; k++){
					if(isMatch(getWord(info.table[1][0].data_id,info.table[1][0].roll,Top),getWord(i,roll_type[k],Under)) == true &&
							isMatch(getWord(info.table[0][1].data_id,info.table[0][1].roll,Left),getWord(i,roll_type[k],Right)) == true){
						Info new_info;
						copyInfo(info,new_info);
						new_info.check[i] = true;
						new_info.table[0][0].data_id = i;
						new_info.table[0][0].roll = roll_type[k];
						new_info.next_loc = info.next_loc+1;
						recursive(new_info);
					}
				}
				break;
			}
		}
	}

}

void func(){

	ans = 0;

	char buf[5];

	for(int i = 0; i < 9; i++){
		scanf("%s",buf);

		for(int k = 0; k < 4; k++){
			data[i][k] = buf[k];
		}
	}

	for(int i = 0; i < 9; i++){
		Info info;
		for(int k = 0; k < 9; k++)info.check[k] = false;
		info.table[1][1].data_id = i;
		info.table[1][1].roll = r_0;
		info.check[i] = true;
		info.next_loc = 1;
		recursive(info);
	}

	printf("%d\n",ans*4);
}

int main(){

	scanf("%d",&N);
	for(int i = 0; i < N; i++){
		func();
	}

	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 2700
final_rank: 7

code_snippet: #include<bits/stdc++.h>
#define rep(i,n)for(int i=0;i<(n);i++)
using namespace std;

char s[9][5], t[3][3][5];
int dx[]{ -1,0,1,0 }, dy[]{ 0,1,0,-1 };
int cnt = 0;
void dfs(int p) {
	rep(i, 3)rep(j, 3) {
		if (t[i][j][0])continue;
		rep(k, 4) {
			rep(l, 4) {
				int nx = i + dx[l], ny = j + dy[l];
				if (nx < 0 || 3 <= nx || ny < 0 || 3 <= ny || !t[nx][ny][0])continue;
				if (abs(s[p][(l + k) % 4] - t[nx][ny][(l + 2) % 4]) != 'a' - 'A')goto g;
			}
			if (p == 8)cnt++;
			else {
				rep(l, 4)t[i][j][l] = s[p][(l + k) % 4];
				dfs(p + 1); t[i][j][0] = 0;
			}g:;
		}
	}
}
int main() {
	int n; scanf("%d", &n);
	rep(i, n) {
		rep(j, 9)scanf("%s", s[j]);
		cnt = 0; dfs(0);
		printf("%d\n", cnt);
	}
}
accuracy: 1
time_ms: 1450
memory_kb: 3200
final_rank: 19

code_snippet: #include<bits/stdc++.h>
#define rep(i,n)for(int i=0;i<(n);i++)
using namespace std;

char s[9][5], t[3][3][5];
int dx[]{ -1,0,1,0 }, dy[]{ 0,1,0,-1 };
int dfs(int p) {
	int res = 0;
	rep(i, 3)rep(j, 3) {
		if (t[i][j][0])continue;
		rep(k, 4) {
			rep(l, 4) {
				int nx = i + dx[l], ny = j + dy[l];
				if (nx < 0 || 3 <= nx || ny < 0 || 3 <= ny || !t[nx][ny][0])continue;
				if (abs(s[p][(l + k) % 4] - t[nx][ny][(l + 2) % 4]) != 'a' - 'A')goto g;
			}
			if (p == 8)res++;
			else {
				rep(l, 4)t[i][j][l] = s[p][(l + k) % 4];
				res += dfs(p + 1); t[i][j][0] = 0;
			}g:;
		}
	}
	return res;
}
int main() {
	int n; scanf("%d", &n);
	rep(i, n) {
		rep(j, 9)scanf("%s", s[j]);
		printf("%d\n", dfs(0));
	}
}
accuracy: 1
time_ms: 1410
memory_kb: 3224
final_rank: 18

code_snippet: #include<bits/stdc++.h>
#define rep(i,n)for(int i=0;i<(n);i++)
using namespace std;

char s[9][5], t[3][3][5];
int dx[]{ -1,0,1,0 }, dy[]{ 0,1,0,-1 };
int dfs(int p) {
	int res = 0;
	rep(i, 3)rep(j, 3) {
		if (t[i][j][0])continue;
		rep(k, 4) {
			rep(l, 4) {
				int nx = i + dx[l], ny = j + dy[l];
				if (nx < 0 || 3 <= nx || ny < 0 || 3 <= ny || !t[nx][ny][0])continue;
				if (abs(s[p][(l + k) % 4] - t[nx][ny][(l + 2) % 4]) != 'a' - 'A')goto g;
			}
			if (p == 8)res++;
			else {
				rep(l, 4)t[i][j][l] = s[p][(l + k) % 4];
				res += dfs(p + 1); t[i][j][0] = 0;
			}g:;
		}
	}
	return res;
}
int main() {
	int n; scanf("%d", &n);
	rep(i, n) {
		rep(j, 9)cin >> s[j];
		printf("%d\n", dfs(0));
	}
}
accuracy: 1
time_ms: 1400
memory_kb: 3092
final_rank: 17

code_snippet: #include<bits/stdc++.h>
#define rep(i,n)for(int i=0;i<(n);i++)
using namespace std;

string s[9], t[3][3];
int dx[]{ -1,0,1,0 }, dy[]{ 0,1,0,-1 };
int dfs(int p) {
	int res = 0;
	rep(i, 3)rep(j, 3) {
		if (!t[i][j].empty())continue;
		rep(k, 4) {
			rep(l, 4) {
				int nx = i + dx[l], ny = j + dy[l];
				if (nx < 0 || 3 <= nx || ny < 0 || 3 <= ny || t[nx][ny].empty())continue;
				if (abs(s[p][(l + k) % 4] - t[nx][ny][(l + 2) % 4]) != 'a' - 'A')goto g;
			}
			if (p == 8)res++;
			else {
				rep(l, 4)t[i][j] += s[p][(l + k) % 4];
				res += dfs(p + 1); t[i][j].clear();
			}g:;
		}
	}
	return res;
}
int main() {
	int n; scanf("%d", &n);
	rep(i, n) {
		rep(j, 9)cin >> s[j];
		printf("%d\n", dfs(0));
	}
}
accuracy: 1
time_ms: 2010
memory_kb: 3132
final_rank: 20

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
const ld eps = 1e-9;

//// < "d:\d_download\visual studio 2015\projects\programing_contest_c++\debug\a.txt" > "d:\d_download\visual studio 2015\projects\programing_contest_c++\debug\b.txt"

const int dx[4] = { -1,0,1,0 };
const int dy[4] = { 0,1,0,-1 };

int dfs(vector<vector<vector<int>>>&field, int nowx, int nowy,bitset<9>&used,const vector<vector<int>>&pieces) {
	if (nowy == 3)return 1;
	else {
		int ans = 0;
		for (int i = 0; i < 9; ++i) {
			if (!used[i]) {
				used[i] = true;
				vector<int>v(pieces[i]);
				for (int way = 0; way < 4; ++way) {
					rotate(v.begin(), v.begin() + 1, v.end());
					bool ok = true;
					if (nowx) {
						if (field[nowy][nowx - 1][2] + v[0]) {
							ok = false;
						}
					}
					if (nowy) {
						if (field[nowy - 1][nowx][1] + v[3]) {
							ok = false;
						}
					}
					if (ok) {
						field[nowy][nowx] = v;
						ans += dfs(field, (nowx + 1) % 3, nowx == 2 ? nowy + 1 : nowy, used, pieces);
						field[nowy][nowx].clear();
					}
				}
				used[i] = false;
				
			}
		}
		return ans;
	}
}
int main() {
	int N; cin >> N;
	map<int, int>mp;
	mp['W'] = 1;
	mp['R'] = 2;
	mp['G'] = 3;
	mp['B'] = 4;
	mp['w'] = -1;
	mp['r'] = -2;
	mp['g'] = -3;
	mp['b'] = -4;
	while (N--) {
		vector<vector<int>>pieces(9);
		for (int i = 0; i < 9; ++i) {

			string st; cin >> st;
			for (int j = 0; j < 4; ++j) {
				pieces[i].push_back(mp[st[j]]);
			}
		}
		bitset<9>used;
		vector<vector<vector<int>>>field(3, vector<vector<int>>(3));
		int ans = dfs(field, 0, 0, used, pieces);
		cout << ans << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 3004
final_rank: 10

code_snippet: #include <bits/stdc++.h>
 
using namespace std;
 
char p[3][3][4];
char pz[9][4];
 
bool check(char a,char b){
    return (a-32 == b || b-32 == a);
}
 
int rec(int now,int S){
    if(now == 9) return 1;
    int res = 0;
    int X = now%3, Y = now/3;
    for(int s = 0 ; s < 9 ; s++){
        if(S >> s & 1) continue;
        for(int i = 0 ; i < 4 ; i++){
            for(int j = 0 ; j < 4 ; j++){
                p[Y][X][j] = pz[s][(i+j)%4];
            }
            bool can = true;    
            if(X > 0 && !check(p[Y][X][0],p[Y][X-1][2])){
                can = false;
            }
            if(Y > 0 && !check(p[Y][X][1],p[Y-1][X][3])){
                can = false;            
            }
            if(can) res += rec(now+1,S|(1<<s));
        }
    }
    return res;
}
 
int main(){
    int Tc;
    cin >> Tc;
    while(Tc--){
        for(int i = 0 ; i < 9 ; i++){
            for(int j = 0 ; j < 4 ; j++){
                cin >> pz[i][j];
            }
        }
        cout << rec(0,0) << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3004
final_rank: 9

code_snippet: #include<iostream>
#include<iomanip>
#include<string>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<vector>
#include<iomanip>


using namespace std;

int cnt;
//vector<string> memo;

char tonum(char word) {
	if(word == 'R') return '1';
	if(word == 'G') return '2';
	if(word == 'B') return '3';
	if(word == 'W') return '4';
	if(word == 'r') return '5';
	if(word == 'g') return '6';
	if(word == 'b') return '7';
	if(word == 'w') return '8';

	return '0';
}

void calc(int num, string rest, string ing) {
	string bkup_r = rest;
	string bkup_i = ing;

	if(num==9) {
		cnt++; return;
	}

	if(num == 0) {
		for(int i=0; i<9; i++) {
			for(int j=0; j<4; j++) {
				ing.push_back(rest[j%4 + i*4]);
				ing.push_back(rest[(j+1)%4 + i*4]);
				ing.push_back(rest[(j+2)%4 + i*4]);
				ing.push_back(rest[(j+3)%4 + i*4]);
//				if(find(memo.begin(), memo.end(), ing) != memo.end())
//					return;
//				else {
//					memo.push_back(ing); 
					calc(1, rest.erase(i*4, 4), ing);  
//				}
				rest = bkup_r;
				ing = "";
			}
		}
	}
	else if(num<3) {
		for(int i=0; i<rest.size(); i++) {
			if(abs((int)ing[2+(num-1)*4] - (int)rest[i]) == 4) {
				ing.push_back(rest[i%4 + i/4*4]);
				ing.push_back(rest[(i+1)%4 + i/4*4]);
				ing.push_back(rest[(i+2)%4 + i/4*4]);
				ing.push_back(rest[(i+3)%4 + i/4*4]);
//				if(find(memo.begin(), memo.end(), ing) != memo.end())
//					return;
//				else {
//					memo.push_back(ing); 
					calc(num+1, rest.erase(i/4*4, 4), ing);  
//				}
				rest = bkup_r;
				ing = bkup_i;
			}
		}
	}
	else if(num%3 == 0) {
		for(int i=0; i<rest.size(); i++) {
			if(abs((int)ing[3+(num-3)*4] - (int)rest[i]) == 4) {
				ing.push_back(rest[(i+3)%4 + i/4*4]);
				ing.push_back(rest[i%4 + i/4*4]);
				ing.push_back(rest[(i+1)%4 + i/4*4]);
				ing.push_back(rest[(i+2)%4 + i/4*4]);
//				if(find(memo.begin(), memo.end(), ing) != memo.end())
//					return;
//				else {
//					memo.push_back(ing); 
					calc(num+1, rest.erase(i/4*4, 4), ing);  
//				}
				rest = bkup_r;
				ing = bkup_i;
			}
		}
	}
	else {
		for(int i=0; i<rest.size(); i++) {
			if(abs((int)ing[2+(num-1)*4] - (int)rest[i]) == 4 &&
				abs((int)ing[3+(num-3)*4] - (int)rest[(i+1)%4 + i/4*4]) == 4) {
				ing.push_back(rest[i%4 + i/4*4]);
				ing.push_back(rest[(i+1)%4 + i/4*4]);
				ing.push_back(rest[(i+2)%4 + i/4*4]);
				ing.push_back(rest[(i+3)%4 + i/4*4]);
//				if(find(memo.begin(), memo.end(), ing) != memo.end())
//					return;
//				else {
//					memo.push_back(ing); 
					calc(num+1, rest.erase(i/4*4, 4), ing);  
//				}
				rest = bkup_r;
				ing = bkup_i;
			}
		}
	}
}

int main() {
	int n;
	char input;
	string pieces;

	cin >> n;
	for(int t=0; t<n; t++) {
//			memo.clear();
			pieces = "";
		for(int i=0; i<36; i++) {
			cin >> input;
			pieces.push_back(tonum(input));
		}
		cnt = 0;
		calc(0, pieces, "");
		cout << cnt << endl;
	}

	return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 1236
final_rank: 5

code_snippet: #include <array>
#include <algorithm>
#include <bitset>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <stack>
#include <vector>

using namespace std;

int result = 0;
char Map[9][4];
bool check[9];
int t_map[3][3];
int alf[256];
// 0 1 2
// 3 4 5
// 6 7 8
void rotate(int num){
    char c = Map[num][0];
    for(int i = 0;i < 3;i++){
        Map[num][i] = Map[num][i+1];
    }
    Map[num][3] = c;
}

void dfs(int num){
    if(num == 9)result++;
    else{
        for(int i = 0;i < 9;i++){
            if(check[i])continue;
            check[i] = true;
            t_map[num/3][num%3] = i;
            for(int j = 0;j < 4;j++){
                if(num / 3 > 0 && num % 3 > 0){
                    if(alf[Map[t_map[num/3][num%3]][1]] == -alf[Map[t_map[num/3][(num%3)-1]][3]]
                       && alf[Map[t_map[num/3][num%3]][0]] == -alf[Map[t_map[(num/3)-1][num%3]][2]])dfs(num+1);
                }else if(num / 3 > 0){
                    if(alf[Map[t_map[num/3][num%3]][0]] == -alf[Map[t_map[(num/3)-1][num%3]][2]])dfs(num+1);
                }else if(num % 3 > 0){
                    if(alf[Map[t_map[num/3][num%3]][1]] == -alf[Map[t_map[num/3][(num%3)-1]][3]])dfs(num+1);
                }else{
                    dfs(num+1);
                }
                rotate(i);
            }
            check[i] = false;
        }
    }
}

int main(){
    alf['r'] = 1;alf['g'] = 2; alf['b'] = 3;alf['w'] = 4;
    alf['R'] = -1;alf['G'] = -2; alf['B'] = -3;alf['W'] = -4;
    int n;string str;
    cin >> n;
    for(int i = 0;i < n;i++){
        for(int j = 0;j < 9;j++){
            cin >> str;
            for(int k = 0;k < 4;k++){
                Map[j][k] = str[k];
            }
        }
        result = 0;
        dfs(0);
        cout << result << endl;
    }
}
accuracy: 1
time_ms: 20
memory_kb: 3132
final_rank: 11

code_snippet: #include <iostream>
#include <cmath>
using namespace std;
string ps[10];
char mp[4][4][4];
int ans,used[10];
int dx[] = {1,2,3,1,2,3,1,2,3};
int dy[] = {1,1,1,2,2,2,3,3,3};

void saiki(int kai){
  if(kai == 9)ans++;
  else 
    for(int i=0;i<9;i++) {
      if(used[i] == 1) continue;
      for(int j=0;j<4;j++){
	int flg =0;
	if(abs(ps[i][j]-mp[dy[kai]][dx[kai]-1][1]) == 'a'-'A'||mp[dy[kai]][dx[kai]-1][1] == 0) flg++;
	if(abs(ps[i][(j+1)%4]-mp[dy[kai]-1][dx[kai]][2]) == 'a'-'A'||mp[dy[kai]-1][dx[kai]][2] == 0) flg++;
	if(flg == 2) {
	  for(int k=0;k<4;k++)mp[dy[kai]][dx[kai]][(3+k)%4] = ps[i][(j+k)%4];
	  used[i] = 1;
	  saiki(kai+1);
	  used[i] = 0;
	  for(int k=0;k<4;k++) mp[dy[kai]][dx[kai]][k] = 0;
	}
      }
    }
}

int main() {
  int q;
  cin >> q;
  while(q--) {
    for(int i=0;i<9;i++) cin >> ps[i];
    ans = 0;
    saiki(0);
    cout << ans << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 1204
final_rank: 4

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

using namespace std;
void func(int);
bool Check(char,char);



char board[4][4][4];
char data[9][4];
bool used[9];

int cnt;

int main(){
  int n;

  string str;
  cin >> n;
  while(n){
    n--;

    for(int i=0;i<4;i++)
      for(int j=0;j<4;j++)
	for(int k=0;k<4;k++)
	  board[i][j][k]='X';


    for(int i=0;i<9;i++){
      used[i]=false;
      cin >> str;
      for(int j=0;j<4;j++){
	data[i][j]=str[j];
      }
    }

    cnt=0;
    func(0);
    cout << cnt << endl;

  }
  return 0;
}




const int dy[9]={1,1,1,2,2,2,3,3,3};
const int dx[9]={1,2,3,1,2,3,1,2,3};

void func(int d){
  if(d==9){
    cnt++;
    return;
  }
  
  int y=dy[d],x=dx[d];
  for(int id=0;id<9;id++){
    if(used[id])continue;
    used[id]=true;

    for(int i=0;i<4;i++){

      for(int j=0;j<4;j++)board[y][x][j]=data[id][(i+j)%4];
      bool r1=Check(board[y-1][x][2],board[y][x][0]);
      bool r2=Check(board[y][x-1][1],board[y][x][3]);
      if(r1==true&&r2==true) func(d+1);
      
    }
    used[id]=false;
  }
  

}

bool Check(char a,char b){
  if(a=='X'||b=='X') return true;
  return (abs(a-b) == abs('A'-'a'));
}
accuracy: 1
time_ms: 50
memory_kb: 1204
final_rank: 3

code_snippet: #include <iostream>
#include <string>
#include <cmath>
using namespace std;
char mp[3][3][4];
string str[10];
bool used[9];long long cnt,ans;
void saiki2(int num){
  int ex[] ={0,0,2,2};
  int ey[] ={2,0,0,2};
  int tx[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};
  int ty[4][2] = {{0,-1},{1,0},{0,1},{-1,0}};
  if(num == 4) ans++;
  else
    for(int i=0;i<9;i++){
      if(used[i] == 1) continue;
      for(int j=0;j<4;j++){
	int nx = ex[num]+tx[num][0];
	int nx2 = ex[num]+tx[num][1];
	int ny = ey[num]+ty[num][0];
	int ny2 = ey[num]+ty[num][1];
	if(abs(str[i][j] - mp[ny][nx][(num+3)%4])=='a'-'A' &&
	   abs(str[i][(j+3)%4] - mp[ny2][nx2][(num+2)%4]) == 'a'-'A'){
	  used[i] = 1;
	  saiki2(num+1);
	  used[i] = 0;
	}	 
      }
    }
}

void saiki(int num){
int dx[] = {0,-1,0 ,1};
int dy[] = {1,0,-1,0};
  if(num == 4) {
    saiki2(0);
    return;
  }
  for(int i=0;i<9;i++){
    if(used[i] == 1) continue;
    for(int j=0;j<4;j++)
      if(abs(mp[1][1][(num+2)%4] - str[i][j])=='a'-'A') {
	for(int k=0;k<4;k++) mp[1+dy[num]][1+dx[num]][(k+num)%4] = str[i][(j+k)%4];
	used[i] = 1;
	saiki(num+1);
	used[i] = 0;
      }
  }
}

int main(){
  int n;
  cin >> n;
  while(n--){
    ans = 0;
  for(int i=0;i<9;i++) cin >> str[i];
  for(int i=0;i<=9;i++){
    for(int j=0;j<4;j++) mp[1][1][j] = str[i][j];
    used[i] = 1;
    saiki(0);
    used[i] = 0;
  }
  cout << ans*4<<endl;
  }
  return 0;     
}
accuracy: 1
time_ms: 30
memory_kb: 1204
final_rank: 2

code_snippet: #include <iostream>
#include <string>
#include <cmath>
using namespace std;
char mp[3][3][4];
string str[10];
bool used[9];long long cnt,ans;
void saiki2(int num){
  int ex[] ={0,0,2,2};
  int ey[] ={2,0,0,2};
  int tx[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};
  int ty[4][2] = {{0,-1},{1,0},{0,1},{-1,0}};
  if(num == 4) ans++;
  else
    for(int i=0;i<9;i++){
      if(used[i] == 1) continue;
      for(int j=0;j<4;j++){
	int nx = ex[num]+tx[num][0];
	int nx2 = ex[num]+tx[num][1];
	int ny = ey[num]+ty[num][0];
	int ny2 = ey[num]+ty[num][1];
	if(abs(str[i][j] - mp[ny][nx][(num+3)%4])=='a'-'A' &&
	   abs(str[i][(j+3)%4] - mp[ny2][nx2][(num+2)%4]) == 'a'-'A'){
	  
	  used[i] = 1;
	  saiki2(num+1);
	  used[i] = 0;
	}	 
      }
    }
}

void saiki(int num){
int dx[] = {0,-1,0 ,1};
int dy[] = {1,0,-1,0};
  if(num == 4) {
    saiki2(0);
    return;
  }
  for(int i=0;i<9;i++){
    if(used[i] == 1) continue;
    for(int j=0;j<4;j++)
      if(abs(mp[1][1][(num+2)%4] - str[i][j])=='a'-'A') {
	for(int k=0;k<4;k++) mp[1+dy[num]][1+dx[num]][(k+num)%4] = str[i][(j+k)%4];
	used[i] = 1;
	saiki(num+1);
	used[i] = 0;
      }
  }
}

int main(){
  int n;
  cin >> n;
  while(n--){
    ans = 0;
  for(int i=0;i<9;i++) cin >> str[i];
  for(int i=0;i<=9;i++){
    for(int j=0;j<4;j++) mp[1][1][j] = str[i][j];
    used[i] = 1;
    saiki(0);
    used[i] = 0;
  }
  cout << ans*4<<endl;
  }
  return 0;     
}
accuracy: 1
time_ms: 20
memory_kb: 1208
final_rank: 1