Problem:
Problem C:
Colored Cubes
There are several colored cubes. All of them are of the same size but they may be colored
differently. Each face of these cubes has a single color. Colors of distinct faces of a cube may or
may not be the same.
Two cubes are said to be
identically
colored if some suitable rotations of one of the cubes give
identical looks to both of the cubes. For example, two cubes shown in Figure 2 are identically
colored. A set of cubes is said to be identically colored if every pair of them are identically
colored.
A cube and its mirror image are not necessarily identically colored. For example, two cubes
shown in Figure 3 are not identically colored.
You can make a given set of cubes identically colored by repainting some of the faces, whatever
colors the faces may have. In Figure 4, repainting four faces makes the three cubes identically
colored and repainting fewer faces will never do.
Your task is to write a program to calculate the minimum number of faces that needs to be
repainted for a given set of cubes to become identically colored.
Input
The input is a sequence of datasets. A dataset consists of a header and a body appearing in this
order. A header is a line containing one positive integer n and the body following it consists
of
n
lines. You can assume that 1 ≤
n
≤ 4. Each line in a body contains six color names
separated by a space. A color name consists of a word or words connected with a hyphen (-).
A word consists of one or more lowercase letters. You can assume that a color name is at most
24-characters long including hyphens.
A dataset corresponds to a set of colored cubes. The integer n corresponds to the number of
cubes. Each line of the body corresponds to a cube and describes the colors of its faces. Color
names in a line is ordered in accordance with the numbering of faces shown in Figure 5. A line
color
1
color
2
color
3
color
4
color
5
color
6
corresponds to a cube colored as shown in Figure 6.
The end of the input is indicated by a line containing a single zero. It is not a dataset nor a
part of a dataset.
Output
For each dataset, output a line containing the minimum number of faces that need to be repainted
to make the set of cubes identically colored.
Sample Input
3
scarlet green blue yellow magenta cyan
blue pink green magenta cyan lemon
purple red blue yellow cyan green
2
red green blue yellow magenta cyan
cyan green blue yellow magenta red
2
red green gray gray magenta cyan
cyan green gray gray magenta red
2
red green blue yellow magenta cyan
magenta red blue yellow cyan green
3
red green blue yellow magenta cyan
cyan green blue yellow magenta red
magenta red blue yellow cyan green
3
blue green green green green blue
green blue blue green green green
green green green green green sea-green
3
red yellow red yellow red yellow
red red yellow yellow red yellow
red red red red red red
4
violet violet salmon salmon salmon salmon
violet salmon salmon salmon salmon violet
violet violet salmon salmon violet violet

...(truncated)

Submitted solutions:

code_snippet: #include <algorithm>
#include <cmath>
#include <cstdlib>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_set>
#include <vector>

using namespace std;

/* 各回転における各面の行き先
	↓数字と面の対応
	0 +x
	1 +y
	2 +z
	3 -z
	4 -y
	5 -x
*/
const int R[24][6]{
	// +x -> +x 固定, +x 周りに 90°ずつ回転
	{0, 1, 2, 3, 4, 5},
	{0, 2, 4, 1, 3, 5},
	{0, 4, 3, 2, 1, 5},
	{0, 3, 1, 4, 2, 5},
	// +x -> -x 固定, -x 周りに 90°ずつ回転
	{5, 2, 1, 4, 3, 0},
	{5, 1, 3, 2, 4, 0},
	{5, 3, 4, 1, 2, 0},
	{5, 4, 2, 3, 1, 0},
	// +x -> +y 固定, +y 周りに 90°ずつ回転
	{1, 2, 0, 5, 3, 4},
	{1, 0, 3, 2, 5, 4},
	{1, 3, 5, 0, 2, 4},
	{1, 5, 2, 3, 0, 4},
	// +x -> -y 固定, -y 周りに 90°ずつ回転
	{4, 0, 2, 3, 5, 1},
	{4, 2, 5, 0, 3, 1},
	{4, 5, 3, 2, 0, 1},
	{4, 3, 0, 5, 2, 1},
	// +x -> +z 固定, +z 周りに 90°ずつ回転
	{2, 0, 1, 4, 5, 3},
	{2, 1, 5, 0, 4, 3},
	{2, 5, 4, 1, 0, 3},
	{2, 4, 0, 5, 1, 3},
	// +x -> -z 固定, -z 周りに 90°ずつ回転
	{3, 1, 0, 5, 4, 2},
	{3, 0, 4, 1, 5, 2},
	{3, 4, 5, 0, 1, 2},
	{3, 5, 1, 4, 0, 2},
};

vector<string> RotateCube(const vector<string>& cube, const int ri) {
	if (ri == 0) return cube;

	vector<string> rotated_cube(6);
	for (int j = 0; j < 6; j++) {
		rotated_cube[R[ri][j]] = cube[j];
	}
	return rotated_cube;
}

int CountFacesToBeRepainted(const vector<vector<string>>& cubes) {
	int count = 0;
	for (int f = 0; f < 6; f++) {
		map<string, int> numof_colors;
		int max_numof_color = 0;
		for (vector<string> cube : cubes) {
			numof_colors[cube[f]]++;
			max_numof_color = max(max_numof_color, numof_colors[cube[f]]);
		}

		count += cubes.size() - max_numof_color;
	}

	return count;
}

int main() {
	int n;

	while (true) {
		cin >> n;
		if (n == 0) break;
		vector<vector<string>> cubes(n, vector<string>(6));
		for (vector<string>& cube : cubes) {
			for (string& color : cube) {
				cin >> color;
			}
		}

		int ri[4]{0};
		int ri_max[4]{0};
		for (int i = 1; i < n; i++) ri_max[i] = 23;

		int minimum = 100;
		vector<vector<string>> rotated_cubes(n, vector<string>(6));
		rotated_cubes[0] = cubes[0];
		for (ri[1] = 0; ri[1] <= ri_max[1]; ri[1]++) {
			for (ri[2] = 0; ri[2] <= ri_max[2]; ri[2]++) {
				for (ri[3] = 0; ri[3] <= ri_max[3]; ri[3]++) {
					for (int i = 1; i < n; i++) {
						rotated_cubes[i] = RotateCube(cubes[i], ri[i]);
					}
					minimum = min(minimum, CountFacesToBeRepainted(rotated_cubes));
				}
			}
		}

		cout << minimum << endl;
	}

	return 0;
}
accuracy: 1
time_ms: 670
memory_kb: 3136
final_rank: 14

code_snippet: #include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime>
#include <cassert>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define MEM(a,b) memset((a),(b),sizeof(a))
const LL INF = 1e9 + 7;
const int N = 1e2 + 10;
int a[] = { 0,4,1,2,3,5 };
int b[] = { 3,0,2,5,4,1 };
int c[] = { 0,1,2,3,4,5 };
int vp[][6] =
{
	{0,1,2,3,4,5},
	{0,2,3,4,1,5},
	{1,5,2,0,4,3},
	{0,3,4,1,2,5},
	{2,5,3,0,1,4},
	{1,2,0,4,5,3},
	{5,3,2,1,4,0},
	{0,4,1,2,3,5},
	{3,5,4,0,2,1},
	{2,3,0,1,5,4},
	{5,4,3,2,1,0},
	{1,0,4,5,2,3},
	{5,2,1,4,3,0},
	{3,0,2,5,4,1},
	{4,5,1,0,3,2},
	{3,4,0,2,5,1},
	{5,1,4,3,2,0},
	{2,0,1,5,3,4},
	{4,0,3,5,1,2},
	{1,4,5,2,0,3},
	{3,2,5,4,0,1},
	{4,1,0,3,5,2},
	{2,1,5,3,0,4},
	{4,3,5,1,0,2}
};
int vs[5][6];
int ans = INF;
char str[100];
int cnt[24];
int key[10];
void dfs(int cur, int n)
{
	if (cur == n)
	{
		int tot = 0;
		for (int i = 0; i < 6; i++)
		{
			map<int, int> ms;
			int maxv = 0;
			MEM(cnt, 0);
			for (int j = 0; j < n; j++)
			{
				int* v = vp[key[j]];
				int& x = vs[j][v[i]];
				maxv = max(maxv, ++cnt[x]);
			}
			tot += n - maxv;
			if (tot >= ans) break;
		}
		ans = min(ans, tot);
		return;
	}
	for (int i = 0; i < 24; i++)
	{
		key[cur] = i;
		dfs(cur + 1, n);
	}
}
int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	int n;
	while (scanf("%d", &n) != EOF)
	{
		if (n == 0) break;
		int a[] = { 1,2,0,5,4,3 };
		map<string, int> ms;
		for (int i = 0; i < n; i++)
		{
			int* v = vs[i];
			for (int j = 0; j < 6; j++)
			{
				scanf("%s", str);
				if (!ms.count(str))
				{
					int id = ms.size();
					ms[str] = id;
				}
				v[a[j]] = ms[str];
			}
			// cin >> v[1] >> v[2] >> v[0] >> v[5] >> v[4] >> v[3];
		}
		ans = INF;
		dfs(1, n);
		printf("%d\n", ans);
	}
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3448
final_rank: 6

code_snippet: #include <map>
#include <cstdio>
#include <cstring>
#include <iostream>
#define MAXN 8
using namespace std;

inline void min(int &a, int b)
{
	if (a > b) a = b;
	return ;
}
inline void max(int &a, int b)
{
	if (a < b) a = b;
	return ;
}

const int dice[24][6] =
{
	{1, 2, 3, 4, 5, 6}, {1, 4, 2, 5, 3, 6},
	{1, 5, 4, 3, 2, 6}, {1, 3, 5, 2, 4, 6},
	{2, 6, 3, 4, 1, 5}, {2, 4, 6, 1, 3, 5},
	{2, 1, 4, 3, 6, 5}, {2, 3, 1, 6, 4, 5},
	{3, 2, 6, 1, 5, 4}, {3, 1, 2, 5, 6, 4},
	{3, 5, 1, 6, 2, 4}, {3, 6, 5, 2, 1, 4},
	{4, 2, 1, 6, 5, 3}, {4, 6, 2, 5, 1, 3},
	{4, 5, 6, 1, 2, 3}, {4, 1, 5, 2, 6, 3},
	{5, 1, 3, 4, 6, 2}, {5, 4, 1, 6, 3, 2},
	{5, 6, 4, 3, 1, 2}, {5, 3, 6, 1, 4, 2},
	{6, 5, 3, 4, 2, 1}, {6, 4, 5, 2, 3, 1},
	{6, 2, 4, 3, 5, 1}, {6, 3, 2, 5, 4, 1}
};

int a[MAXN][MAXN], method[6], color[26];
int ans, n, cnt;
bool zero;
string s;
map <string, int> mp;

void dfs(int dep)
{
	if (dep == n)
	{
		int cc, res = 0;
		for (int j = 0; j < 6; j++)
		{
			cc = 0;
			memset(color, 0, sizeof color);
			for (int i = 1; i <= n; i++)
			{
				++color[a[i][dice[method[i]][j]]];
				max(cc, color[a[i][dice[method[i]][j]]]);
			}
			res += n - cc;
		}
		min(ans, res);
		if (!ans) zero = true;
		return ;
	}
	for (int i = 0; i < 24 && !zero; i++)
	{
		method[dep] = i;
		dfs(dep + 1);
	}
	return ;
}

void Solve()
{
	ans = ~(1 << 31); zero = false; cnt = 0;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= 6; j++)
		{
			cin >> s;
			if (mp.find(s) == mp.end()) mp.insert(make_pair(s, ++cnt));
			a[i][j] = mp[s];
		}
	dfs(1);
	cout << ans << '\n';
	mp.clear();
	return ;
}


int main()
{
	while (cin >> n)
	{
		if (!n) break;
		Solve();
	}
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3376
final_rank: 5

code_snippet: #define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
#define FOR(i,a,n) for(ll i=a;i<(ll)(n);i++)

//参考,引用: http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=534765#1
//自力では解けず、かけませんでした。

int n;
string dice[4][6]; //4*6の24通り存在する

//diceを回転させる
void rotation(int x, string *dice){
   int r[][4] = {{0,1,5,4},{0,2,5,3},{1,3,4,2}};
   string t = dice[r[x][0]];
   dice[r[x][0]]=dice[r[x][1]];
   dice[r[x][1]]=dice[r[x][2]];
   dice[r[x][2]]=dice[r[x][3]];
   dice[r[x][3]]=t;
}

int dfs(int r){
  if(r==n){
    int s=0;
    for(int i=0;i<6;i++){
      int m=1;
      for(int j=0;j<n;j++){
	int c=0;
	for(int k=0;k<n;k++){
	  c+=dice[j][i]==dice[k][i];
	}
	m=max(c,m);
      }
      s+=n-m;
    }
    return s;
  }else{
    int m=99;
    for(int i=0;i<6;i++){
      rotation(i&1,dice[r]);
      for(int j=0;j<4;j++){
	rotation(2,dice[r]);
	m=min(m,dfs(r+1));
      }
    }
    return m;
  }
}

int main(){
   /*

   考察: ダイスは24通りをとる。最大で、24^4通りあるが、これは十分間に合う。
   dfsで全探索すれば良い。

   */
   while(cin>>n, n){
      for(int i=0; i<n; i++){
         for(int j=0; j<6; j++){
            cin>>dice[i][j];
         }
      }
      cout << dfs(0) << endl;
   }
}
accuracy: 1
time_ms: 1890
memory_kb: 3008
final_rank: 16

code_snippet: #include<bits/stdc++.h>
#define ll long long
#define lp(i, n) for(int i=0;i<(n);++i)
#define per(i, n) for(int i=(n)-1;i>=0;--i)
#define lps(i, n) for(int i=1;i<(n);++i)
#define foreach(i, n) for(auto &i:(n))
#define pii pair<int, int>
#define pll pair<long long, long long>
#define all(x) (x).begin(), (x).end()
#define bit(x) (1ll << (x))
const ll MOD = (ll)1e9+7;
const int INF = (ll)1e9+7;
const ll INFLL = (ll)1e18;
using namespace std;
template<class t>
using vvector = vector<vector<t>>;
template<class t>
using vvvector = vector<vector<vector<t>>>;
template<class t>
using priority_queuer = priority_queue<t, vector<t>, greater<t>>;
template<class t, class u> bool chmax(t &a, u b){if(a<b){a=b;return true;}return false;}
template<class t, class u> bool chmin(t &a, u b){if(a>b){a=b;return true;}return false;}

struct dice{
  string f,r,t,d,l,b;
  dice(){};
  dice(string v1,string v2,string v3,string v4,string v5,string v6){
    f=v1;r=v2;t=v3;d=v4;l=v5;b=v6;
  }
  int same(dice d2){
    int cnt=6;
    if(f==d2.f)cnt--;
    if(r==d2.r)cnt--;
    if(t==d2.t)cnt--;
    if(d==d2.d)cnt--;
    if(l==d2.l)cnt--;
    if(b==d2.b)cnt--;
    return cnt;
  }
  void roll(char c){
    if(c=='s'){
      string x=f;
      f=r;
      r=b;
      b=l;
      l=x;
      return;
    }
    else{
      string x=f;
      f=t;
      t=b;
      b=d;
      d=x;
    }
  }
};

string task="sssstsssstsssstsssststssssttssss";

vector<dice> v;

int acnt(){
  vector<string> x;
  int cnt=0;
  x.clear();
  lp(i,v.size()){
    x.push_back(v[i].f);
  }
  sort(x.begin(),x.end());
  if(v.size()==3){
    if(x[0]==x[1]&&x[1]==x[2])cnt+=0;
    else if(x[0]==x[1]||x[1]==x[2])cnt+=1;
    else{
      cnt+=2;
    }
  }
  else{
    if(x[0]==x[1]&&x[1]==x[2]&&x[2]==x[3])cnt+=0;
    else if(x[0]==x[1]&&x[1]==x[2]){
      cnt+=1;
    }
    else if(x[1]==x[2]&&x[2]==x[3]){
      cnt++;
    }
    else if(x[0]==x[1]||x[2]==x[3]||x[1]==x[2])cnt+=2;
    else cnt+=3;
  }

  x.clear();
  lp(i,v.size()){
    x.push_back(v[i].r);
  }
  sort(x.begin(),x.end());
  if(v.size()==3){
    if(x[0]==x[1]&&x[1]==x[2])cnt+=0;
    else if(x[0]==x[1]||x[1]==x[2])cnt+=1;
    else{
      cnt+=2;
    }
  }
  else{
    if(x[0]==x[1]&&x[1]==x[2]&&x[2]==x[3])cnt+=0;
    else if(x[0]==x[1]&&x[1]==x[2]){
      cnt+=1;
    }
    else if(x[1]==x[2]&&x[2]==x[3]){
      cnt++;
    }
    else if(x[0]==x[1]||x[2]==x[3]||x[1]==x[2])cnt+=2;
    else cnt+=3;
  }
  
  x.clear();
  lp(i,v.size()){
    x.push_back(v[i].t);
  }
  sort(x.begin(),x.end());
  if(v.size()==3){
    if(x[0]==x[1]&&x[1]==x[2])cnt+=0;
    else if(x[0]==x[1]||x[1]==x[2])cnt+=1;
    else{
      cnt+=2;
    }
  }
  else{
    if(x[0]==x[1]&&x[1]==x[2]&&x[2]==x[3])cnt+=0;
    else if(x[0]==x[1]&&x[1]==x[2]){
      cnt+=1;
    }
    else if(x[1]==x[2]&&x[2]==x[3]){
      cnt++;
    }
    else if(x[0]==x[1]||x[2]==x[3]||x[1]==x[2])cnt+=2;
    else cnt+=3;
  }
x.clear();
  lp(i,v.size()){
    x.push_back(v[i].d);
  }
  sort(x.begin(),x.end());
  if(v.size()==3){
    if(x[0]==x[1]&&x[1]==x[2])cnt+=0;
    else if(x[0]==x[1]||x[1]==x[2])cnt+=1;
    else{
      cnt+=2;
    }
  }
  else{
    if(x[0]==x[1]&&x[1]==x[2]&&x[2]==x[3])cnt+=0;
    else if(x[0]==x[1]&&x[1]==x[2]){
      cnt+=1;
    }
    else if(x[1]==x[2]&&x[2]==x[3]){
      cnt++;
    }
    else if(x[0]==x[1]||x[2]==x[3]||x[1]==x[2])cnt+=2;
    else cnt+=3;
  }
x.clear();
  lp(i,v.size()){
    x.push_back(v[i].l);
  }
  sort(x.begin(),x.end());
  if(v.size()==3){
    if(x[0]==x[1]&&x[1]==x[2])cnt+=0;
    else if(x[0]==x[1]||x[1]==x[2])cnt+=1;
    else{
      cnt+=2;
    }
  }
  else{
    if(x[0]==x[1]&&x[1]==x[2]&&x[2]==x[3])cnt+=0;
    else if(x[0]==x[1]&&x[1]==x[2]){
      cnt+=1;
    }
    else if(x[1]==x[2]&&x[2]==x[3]){
      cnt++;
    }
    else if(x[0]==x[1]||x[2]==x[3]||x[1]==x[2])cnt+=2;
    else cnt+=3;
  }
x.clear();
  lp(i,v.size()){
    x.push_back(v[i].b);
  }
  sort(x.begin(),x.end());
  if(v.size()==3){
    if(x[0]==x[1]&&x[1]==x[2])cnt+=0;
    else if(x[0]==x[1]||x[1]==x[2])cnt+=1;
    else{
      cnt+=2;
    }
  }
  else{
    if(x[0]==x[1]&&x[1]==x[2]&&x[2]==x[3])cnt+=0;
    else if(x[0]==x[1]&&x[1]==x[2]){
      cnt+=1;
    }
    else if(x[1]==x[2]&&x[2]==x[3]){
      cnt++;
    }
    else if(x[0]==x[1]||x[2]==x[3]||x[1]==x[2])cnt+=2;
    else cnt+=3;
  }
  return cnt;
}

int solve(){
  if(v.size()==1)return 0;
  if(v.size()==2){
    int ans=INF;
    lp(i,task.size()){
      v[0].roll(task[i]);
      ans=min(ans,v[0].same(v[1]));
    }
    return ans;
  }
  if(v.size()==3){
    int ans=INF;
    lp(i,task.size()){
      v[0].roll(task[i]);
      lp(j,task.size()){
	v[1].roll(task[j]);
	ans=min(ans,acnt());
      }
    }
    return ans;
  }
  else{
    int ans=INF;
    lp(i,task.size()){
      v[0].roll(task[i]);
      lp(j,task.size()){
	v[1].roll(task[j]);
	lp(k,task.size()){
	  v[2].roll(task[k]);
	  ans=min(ans,acnt());
	}
      }
    }
    return ans;
  }
  return -1;
}

int main(){
  while(1){
    int n;
    cin>>n;
    if(n==0)break;
      v.clear();
    lp(i,n){
      string a,b,c,d,e,f;
      cin>>a>>b>>c>>d>>e>>f;
      dice k(a,b,c,d,e,f);
      v.push_back(k);
    }
    int ans=INF;
    cout<<solve()<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 430
memory_kb: 3164
final_rank: 12

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

struct Dice{
  int s[6];
  void roll(char c){
    int b;

    if(c=='S'){
      b=s[0];
      s[0]=s[4];
      s[4]=s[5];
      s[5]=s[1];
      s[1]=b;
    }
    if(c=='E'){
      b=s[0];
      s[0]=s[3];
      s[3]=s[5];
      s[5]=s[2];
      s[2]=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;
    }
  }
};

Dice D[6];
string s[10][10];
int a[10][10];

int n,ans;
int used[25];

void dfs(int dep){
  if(dep==n){
    int T=n*6;
    r(i,6){
      memset(used,0,sizeof(used));
      int MAX=0;
      r(j,n){
	used[D[j].s[i]]++;
	MAX=max(MAX,used[D[j].s[i]]);
      }
      T-=MAX;
    }
    ans=min(T,ans);
    return ;
  }
  r(k,2){
    D[dep].roll('E');
    r(i,4){
      D[dep].roll('S');
      r(j,4){
	D[dep].roll('R');
	dfs(dep+1);
      }
    }
  }
}

int main(){
  while( cin>>n , n ){
    ans=1e9;
    vector<string>v;
    r(i,n){
      r(j,6){
	cin>>s[i][j];
	v.push_back(s[i][j]);
      }
    }
    sort(v.begin(),v.end());
    v.erase(unique(v.begin(),v.end()),v.end());
    map<string,int>M;
    r(i,v.size()){
      M[v[i]]=i;
    }
    r(i,n){
      r(j,6){
	a[i][j]=M[s[i][j]];
	D[i].s[j]=a[i][j];
      }
    }
    dfs(0);
    cout<<ans<<endl;
  }
}
accuracy: 1
time_ms: 1400
memory_kb: 3188
final_rank: 15

code_snippet: #include<iostream>
#include<string>
#include<map>
using namespace std;
#define int long long
#define rep(i,n) for(int i = 0; i < n; i++)
#define INF (long long)(1e18)
#define MOD (int)(1e9+7)
#define MAX_N 103
#define MAX_V 10
#define MAX_M 101
#define yn(f) (f?"Yes":"No")
#define YN(f) (f?"YES":"NO")
#define pro "はいプロ　世界一○○が上手　○○界のtourist　○○時代の終焉を告げる者　実質○○　○○するために生まれてきた男"

struct Cube{
	string co[10];
};


Cube huga(Cube b){
	Cube a = b;
	string temp = a.co[1];
	a.co[1] = a.co[5];
	a.co[5] = a.co[6];
	a.co[6] = a.co[2]; 
	a.co[2] = temp;
	return a;
}

Cube hoge(Cube b){
	Cube a = b;
	string temp = a.co[1];
	a.co[1] = a.co[4];
	a.co[4] = a.co[6];
	a.co[6] = a.co[3];
	a.co[3] = temp;
	return a;
}

Cube hugahuga(Cube b){
	Cube a = b;
	string temp = a.co[3];
	a.co[3] = a.co[5];
	a.co[5] = a.co[4];
	a.co[4] = a.co[2]; 
	a.co[2] = temp;
	return a;
}

Cube foo(Cube c, int b){
	Cube a = c;
	switch(b){
	case 1:
		break;
	case 2:
		a=huga(a);a=huga(a);a=huga(a);
		break;
	case 3:
		a=hoge(a); a=hoge(a);a=hoge(a);
		break;
	case 4:
		a=hoge(a);
		break;
	case 5:
		a=huga(a);
		break;
	case 6:
		a=huga(a);a=huga(a);
		break;
	}
	return a;
}

int cou(Cube a,Cube b){
	int count = 0;
	for(int i = 1; i <= 6; i++){
		if(a.co[i] != b.co[i])count++;
	}
	return count;
}

int ans(int cc[10][10],int n,int used[],int k){
	int count = 0;
	for(int i = 1; i <= n; i++) count+=cc[k][i];
	return count;
}

int ha(Cube a[], int n){//cout<<" a "<<endl;
	int ans = 0;
	for(int i = 1; i <= 6; i++){
		int ma = 0;
		map<string,int> m;
		for(int j = 1; j <= n; j++){
			ma = max(ma, ++m[a[j].co[i]]);
		}
		ans += n-ma;
	}
	
	return ans;
}

int so(Cube a[], int n, int k){//cout<<k<<" "<<n<<endl;
	Cube tt = a[k];
	int ans = INF;
	//if(n+1== k) return ha(a,n);
	for(int i = 1; i <= 6; i++){
		Cube temp = foo(tt,i);
		for(int j = 1; j <= 4;j++){
			temp = hugahuga(temp);
			a[k] = temp;
			if(k<n-1)ans = min(ans,so(a,n,k+1));
			else ans = min(ans,ha(a,n));
		}
	}
	return ans;
}

signed main(){
	while(true){
		int n;
		Cube s[5];
		cin>>n;
		if(!n)break;

		for(int i = 1; i <= n; i++)
			for(int j = 1; j <= 6; j++)
				cin>>s[i].co[j];
	
		cout<<so(s,n,1)<<endl;
	}

	return 0;
}
accuracy: 1
time_ms: 390
memory_kb: 3028
final_rank: 8

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

template<typename T1,typename T2> void chmin(T1 &a,T2 b){if(a>b)a=b;};
template<typename T1,typename T2> void chmax(T1 &a,T2 b){if(a<b)a=b;};

struct Dice{
  Int s[6];
  void roll(char c){
    Int b;
    if(c == 'E'){
      b = s[0];
      s[0] = s[3];
      s[3] = s[5];
      s[5] = s[2];
      s[2] = b;
    }

    if(c == 'W'){
      b = s[0];
      s[0] = s[2];
      s[2] = s[5];
      s[5] = s[3];
      s[3] = b;
    }

    if(c == 'N'){
      b = s[0];
      s[0] = s[1];
      s[1] = s[5];
      s[5] = s[4];
      s[4] = b;
    }

    if(c == 'S'){
      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[2];
      s[2] = s[4];
      s[4] = s[3];
      s[3] = b;
    }
    
    if(c == 'L'){
      b = s[1];
      s[1] = s[3];
      s[3] = s[4];
      s[4] = s[2];
      s[2] = b;
    }
  }
};


vector<Dice> makeDices(Dice d){
  vector<Dice> res;
  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++){
      res.push_back(t);
      t.roll('E');
    }
  }
  return res;
}

signed main(){
  cin.tie(0);
  ios::sync_with_stdio(0);
  Int n;
  while(cin>>n,n){
    vector<Dice> vs;
    Int sz=0;
    map<string, Int> cm;
    for(Int i=0;i<n;i++){
      vs.emplace_back();
      for(Int j=0;j<6;j++){
	string s;
	cin>>s;
	if(!cm.count(s)) cm[s]=sz++;
	vs[i].s[j]=cm[s];
      }     
    }
    
    if(n==1){
      cout<<0<<endl;
    }else if(n==2){
      auto A = makeDices(vs[0]);
      auto B = makeDices(vs[1]);
      Int ans=1e9;      
      for(auto &a:A){
	for(auto &b:B){
	  Int res=0;
	  for(Int j=0;j<6;j++){
	    map<Int, Int> x;
	    x[a.s[j]]++;
	    x[b.s[j]]++;
	    Int y=0;
	    for(auto p:x) chmax(y,p.second);
	    res+=2-y;
	  }	  
	  chmin(ans,res);
	}
      }      
      cout<<ans<<endl;
    }else if(n==3){
      auto A = makeDices(vs[0]);
      auto B = makeDices(vs[1]);
      auto C = makeDices(vs[2]);
      Int ans=1e9;
      
      for(auto &a:A){
	for(auto &b:B){
	  for(auto &c:C){
	    Int res=0;
	    for(Int j=0;j<6;j++){
	      map<Int, Int> x;
	      x[a.s[j]]++;
	      x[b.s[j]]++;
	      x[c.s[j]]++;
	      Int y=0;
	      for(auto p:x) chmax(y,p.second);
	      res+=3-y;
	    }	  
	    chmin(ans,res);
	  }
	}
      }
      cout<<ans<<endl;
    }else{
      auto A = makeDices(vs[0]);
      auto B = makeDices(vs[1]);
      auto C = makeDices(vs[2]);
      auto D = makeDices(vs[3]);
      Int ans=1e9;      
      for(auto &a:A){
	for(auto &b:B){
	  for(auto &c:C){
	    for(auto &d:D){
	      Int res=0;
	      for(Int j=0;j<6;j++){
		map<Int, Int> x;
		x[a.s[j]]++;
		x[b.s[j]]++;
		x[c.s[j]]++;
		x[d.s[j]]++;
		Int y=0;
		for(auto p:x) chmax(y,p.second);
		res+=4-y;
	      }	  
	      chmin(ans,res);
	    }
	  }
	}
      }
      cout<<ans<<endl;
    }    
  }
}
accuracy: 1
time_ms: 4700
memory_kb: 3096
final_rank: 18

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

class Dice{
  
public:
  int TOP = 2, FRONT = 0, LEFT = 4, RIGHT = 1, BACK = 5, BOTTOM = 3;
  vector<int> val;
  Dice():val(6){for(int i=0;i<6;i++) val[i] = i;}
  Dice(int val[6]){for(int i=0;i<6;i++) this->val[i] = val[i];}
  Dice(vector<int> val):val(val){assert(val.size()==6);}
  int& operator [](int a){return val[a];}
  
  void rotN(){
    swap(val[TOP],val[FRONT]);
    swap(val[FRONT],val[BOTTOM]);
    swap(val[BOTTOM],val[BACK]);
  }
  
  void rotS(){
    swap(val[TOP],val[BACK]);
    swap(val[BACK],val[BOTTOM]);
    swap(val[BOTTOM],val[FRONT]);
  }
  
  void rotE(){
    swap(val[TOP],val[LEFT]);
    swap(val[LEFT],val[BOTTOM]);
    swap(val[BOTTOM],val[RIGHT]);
  }
  
  void rotW(){
    swap(val[TOP],val[RIGHT]);
    swap(val[RIGHT],val[BOTTOM]);
    swap(val[BOTTOM],val[LEFT]);
  }
  
  void rotCW(){
    swap(val[FRONT],val[RIGHT]);
    swap(val[RIGHT],val[BACK]);
    swap(val[BACK],val[LEFT]);
  }
  
  void rotCCW(){
    swap(val[FRONT],val[LEFT]);
    swap(val[LEFT],val[BACK]);
    swap(val[BACK],val[RIGHT]);
  }
  
};

Dice dice[4][30];
int N, ans;
int ID[4];

void cal(){
  
  int cnt = 0;
  
  for(int i=0;i<6;i++){
    
    unordered_map<int,int> A;
    
    for(int j=0;j<N;j++) A[dice[j][ID[j]][i]]++;
    
    int maxc = 0;
    
    for(auto p : A ) maxc = max( maxc, p.second );
    
    cnt += N - maxc;
    
  }
  
  ans = min( ans, cnt );
  
}

void dfs(int x){
  
  if( x == N ){
    cal();
    return;
  }
  
  for(int i=0;i<24;i++){
    ID[x] = i;
    dfs( x + 1 );
  }
  
}

int main(){
  
  while(1){
    
    cin>>N;
    if( N == 0 ) break;
    
    vector<string> d[4];
    map<string,int> memo;
    int idx = 0;
    
    for(int i=0;i<N;i++){
      
      for(int j=0;j<6;j++){
	string s;
	cin>>s;
	d[i].push_back(s);
	if( memo.count(s) == 0 ) memo[s] = idx++;
      }
                  
    }
    
    Dice di[4];
    
    for(int i=0;i<N;i++){
      
      vector<int> A;
      
      for(int j=0;j<6;j++){
	
	A.push_back( memo[d[i][j]] );
	
      }
      
      di[i] = Dice(A);
      
    }
        
    for(int I=0;I<N;I++){
      
      int idx = 0;
      
      for(int i=0;i<4;i++){
    
	for(int j=0;j<4;j++){
	  
	  dice[I][idx++] = di[I];
      
	  di[I].rotCW();
      
	}
    
	di[I].rotN();
	
      }

      for(int i=0;i<4;i++){
      
	if(i%2){
      
	  for(int j=0;j<4;j++){
      
	    dice[I][idx++] = di[I];
      
	    di[I].rotCW();
      
	  }
      
	}
	
	di[I].rotE();
	
      }
      
      
    }
    
    for(int i=0;i<N;i++){
      
      vector<int> A;
      
      for(int j=0;j<6;j++){
	
	A.push_back( memo[d[i][j]] );
	
      }
      
      di[i] = Dice(A);
      
    }
    
    ans = 100;
    
    dfs( 1 );
    
    cout<<ans<<endl;
    
  }
  
  return 0;
}
accuracy: 1
time_ms: 370
memory_kb: 3156
final_rank: 11

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

typedef long long ll;

struct cube{
  string a[6];

  int count=1;
  
  void move_N(){
    string b[6]=a;
    a[0]=b[1];
    a[1]=b[2];
    a[2]=b[3];
    a[3]=b[0];
  }

  void move_E(){
    string b[6]=a;
    a[4]=b[1];
    a[1]=b[5];
    a[5]=b[3];
    a[3]=b[4];
  }

  void move_R(){
    string b[6]=a;
    a[4]=b[2];
    a[2]=b[5];
    a[5]=b[0];
    a[0]=b[4];
  }

  bool operator == (const cube &C){return C.a==a;}

  void rotate(){
    move_R();
    if(count%4){}
    else if(count/4<4){
      move_N();
    }
    else if(count/4==4){
      move_E();
    }
    else if(count/4==5){
      move_E();
      move_E();
    }
    count++;
  }

  cube(vector<string> &A){
    a[0]=A[5];
    a[1]=A[2];
    a[2]=A[0];
    a[3]=A[3];
    a[4]=A[1];
    a[5]=A[4];
  }

  cube(){}

  void init(vector<string> &A){
    for(int i=0;i<6;i++){a[i]=A[i];}
  }

  void operator = (const cube &C){
    for(int i=0;i<6;i++){a[i]=C.a[i];}
    count=C.count;
  }
};

vector<cube> C(6);
ll n;
ll mi=1e18;

ll count(){
  ll cost=0;
  for(int i=0;i<6;i++){
    map<string,ll> M;
    ll mx=0;
    for(int t=0;t<n;t++){
      M[C[t].a[i]]++;
      mx=max(mx,M[C[t].a[i]]);
    }
    cost+=n-mx;
  }
  return cost;
}

void dfs(ll d){
  C[d].count=1;
  if(d==n-1){
    for(int i=0;i<24;i++){
      mi=min(mi,count());
      C[d].rotate();
    }
    return;
  }
  else{
    for(int i=0;i<24;i++){
      dfs(d+1);
      C[d].rotate();
    }
  }
}

int main(){
  while(cin>>n && n){
    mi=1e9;
  vector<vector<string>> a(n,vector<string>(6));
  for(int i=0;i<n;i++){
    for(int t=0;t<6;t++){
      cin>>a[i][t];
    }
  }
  if(n==1){cout<<0<<endl; continue;}
  for(int i=0;i<n;i++){C[i]=cube(a[i]);}
  dfs(1);
  cout<<mi<<endl;
  
  }
  return 0;
}
accuracy: 1
time_ms: 440
memory_kb: 3156
final_rank: 13

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

template<typename T1,typename T2> void chmin(T1 &a,T2 b){if(a>b)a=b;};
template<typename T1,typename T2> void chmax(T1 &a,T2 b){if(a<b)a=b;};

struct Dice{
  Int s[6];
  void roll(char c){
    Int b;
    if(c == 'E'){
      b = s[0];
      s[0] = s[3];
      s[3] = s[5];
      s[5] = s[2];
      s[2] = b;
    }

    if(c == 'W'){
      b = s[0];
      s[0] = s[2];
      s[2] = s[5];
      s[5] = s[3];
      s[3] = b;
    }

    if(c == 'N'){
      b = s[0];
      s[0] = s[1];
      s[1] = s[5];
      s[5] = s[4];
      s[4] = b;
    }

    if(c == 'S'){
      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[2];
      s[2] = s[4];
      s[4] = s[3];
      s[3] = b;
    }
    
    if(c == 'L'){
      b = s[1];
      s[1] = s[3];
      s[3] = s[4];
      s[4] = s[2];
      s[2] = b;
    }
  }
};


vector<Dice> makeDices(Dice d){
  vector<Dice> res;
  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++){
      res.push_back(t);
      t.roll('E');
    }
  }
  return res;
}

signed main(){
  cin.tie(0);
  ios::sync_with_stdio(0);
  Int n;
  while(cin>>n,n){
    vector<Dice> vs;
    Int sz=0;
    map<string, Int> cm;
    for(Int i=0;i<n;i++){
      vs.emplace_back();
      for(Int j=0;j<6;j++){
	string s;
	cin>>s;
	if(!cm.count(s)) cm[s]=sz++;
	vs[i].s[j]=cm[s];
      }     
    }
    
    if(n==1){
      cout<<0<<endl;
    }else if(n==2){
      auto A = makeDices(vs[0]);
      auto B = makeDices(vs[1]);
      Int ans=1e9;      
      for(auto &a:A){
	for(auto &b:B){
	  Int res=0;
	  for(Int j=0;j<6;j++){
	    map<Int, Int> x;
	    x[a.s[j]]++;
	    x[b.s[j]]++;
	    Int y=0;
	    for(auto p:x) chmax(y,p.second);
	    res+=2-y;
	  }	  
	  chmin(ans,res);
	}
      }      
      cout<<ans<<endl;
    }else if(n==3){
      auto A = makeDices(vs[0]);
      auto B = makeDices(vs[1]);
      auto C = makeDices(vs[2]);
      Int ans=1e9;
      
      for(auto &a:A){
	for(auto &b:B){
	  for(auto &c:C){
	    Int res=0;
	    for(Int j=0;j<6;j++){
	      map<Int, Int> x;
	      x[a.s[j]]++;
	      x[b.s[j]]++;
	      x[c.s[j]]++;
	      Int y=0;
	      for(auto p:x) chmax(y,p.second);
	      res+=3-y;
	    }	  
	    chmin(ans,res);
	  }
	}
      }
      cout<<ans<<endl;
    }else{
      auto A = makeDices(vs[0]);
      auto B = makeDices(vs[1]);
      auto C = makeDices(vs[2]);
      auto D = makeDices(vs[3]);
      Int ans=1e9;      
      for(auto &a:A){
	for(auto &b:B){
	  for(auto &c:C){
	    for(auto &d:D){
	      Int res=0;
	      for(Int j=0;j<6;j++){
		map<Int, Int> x;
		x[a.s[j]]++;
		x[b.s[j]]++;
		x[c.s[j]]++;
		x[d.s[j]]++;
		Int y=0;
		for(auto p:x) chmax(y,p.second);
		res+=4-y;
	      }	  
	      chmin(ans,res);
	    }
	  }
	}
      }
      cout<<ans<<endl;
    }    
  }
}
accuracy: 1
time_ms: 5440
memory_kb: 3100
final_rank: 19

code_snippet: #include<iostream>
#include<algorithm>
#include<string>
#include<map>
#include<vector>
#include<complex>
#include<sstream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cctype>
#include<cstring>
using namespace std;
 
#define REP(i,x,n) for(int i = x ; i < (int)(n) ; i++)
#define rep(i,n) REP(i, 0, n)
 
struct Dice{
  //top, front, right, left, back, bottom
  string side[6];
  Dice(){}
  Dice(string s[]){
    rep(i,6) side[i] = s[i];
  }
    
  void rotate(int op){
    string tmp = "";
    //右に倒す
    if(op==0){
      tmp = side[0];
      side[0] = side[3];
      side[3] = side[5];
      side[5] = side[2];
      side[2] = tmp;
    }
  
    //前に倒す
    if(op==1){
      tmp = side[0];
      side[0] = side[4];
      side[4] = side[5];
      side[5] = side[1];
      side[1] = tmp;
    }
        
    //左に倒す
    if(op==2){
      tmp = side[0];
      side[0] = side[2];
      side[2] = side[5];
      side[5] = side[3];
      side[3] = tmp;
    }
        
    //後ろに倒す
    if(op==3){
      tmp = side[0];
      side[0] = side[1];
      side[1] = side[5];
      side[5] = side[4];
      side[4] = tmp;
    }
  
    //topとbottomを軸に右回転
    if(op==4){
      tmp = side[1];
      side[1] = side[2];
      side[2] = side[4];
      side[4] = side[3];
      side[3] = tmp;
    }
        
    //topとbottomを軸に左回転
    if(op==5){
      tmp = side[1];
      side[1] = side[3];
      side[3] = side[4];
      side[4] = side[2];
      side[2] = tmp;
    }
  }
};
 
int n;
int ans;
Dice dice[4];
 
void solve(){
  int res = 0;
   
  rep(j,6){
    if(ans <= res) break;
    vector<string> s;
    rep(i,n) s.push_back(dice[i].side[j]);
    sort(s.begin(), s.end());
    if(n==2){
      if(s[0] != s[1]) res++;
    }
    if(n==3){
      if(s[0] != s[1] && s[1] != s[2]) res+=2;
      else if(s[0] != s[1] || s[1] != s[2]) res++;
    }
    if(n==4){
      if(s[0] != s[1] && s[1] != s[2] && s[2] != s[3]) res+=3;
      else if(s[0] == s[1] && s[1] != s[2] && s[2] != s[3]) res+=2;
      else if(s[0] != s[1] && s[1] == s[2] && s[2] != s[3]) res+=2;
      else if(s[0] != s[1] && s[1] != s[2] && s[2] == s[3]) res+=2;
      else if(s[0] == s[1] && s[1] != s[2] && s[2] == s[3]) res+=2;
      else if(s[0] == s[1] && s[1] == s[2] && s[2] != s[3]) res+=1;
      else if(s[0] != s[1] && s[1] == s[2] && s[2] == s[3]) res+=1;
    }
  }
 
  ans = min(ans, res);
}
 
void dfs(int idx){
  if(idx==n) solve();
  else{
    rep(i,24){
      if(i==4) dice[idx].rotate(1);
      if(i==8) dice[idx].rotate(1);
      if(i==12)dice[idx].rotate(1);
      if(i==16){
        dice[idx].rotate(1);
        dice[idx].rotate(0);
      }
      if(i==20){
        dice[idx].rotate(2);
        dice[idx].rotate(2);
      }
       
      dice[idx].rotate(4);
      dfs(idx + 1);
    }
  }
}
 
int main(){
  while(cin >> n && n){
    rep(i,n){
      rep(j,6){
        cin >> dice[i].side[j];
      }
    }
    ans = 6 * n;
    if(n > 1) dfs(1);
    else ans = 0;
    cout << ans << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 260
memory_kb: 3200
final_rank: 9

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

using VS = vector<string>;    using LL = long long;
using VI = vector<int>;       using VVI = vector<VI>;
using PII = pair<int, int>;   using PLL = pair<LL, LL>;
using VL = vector<LL>;        using VVL = vector<VL>;

#define ALL(a)  begin((a)),end((a))
#define RALL(a) (a).rbegin(), (a).rend()
#define SZ(a) int((a).size())
#define SORT(c) sort(ALL((c)))
#define RSORT(c) sort(RALL((c)))
#define UNIQ(c) (c).erase(unique(ALL((c))), end((c)))
#define FOR(i, s, e) for (int(i) = (s); (i) < (e); (i)++)
#define FORR(i, s, e) for (int(i) = (s); (i) > (e); (i)--)
#define debug(x) cerr << #x << ": " << x << endl
const int INF = 1e9;                          const LL LINF = 1e16;
int DX[8] = { 0, 0, 1, -1, 1, 1, -1, -1 };    int DY[8] = { 1, -1, 0, 0, 1, -1, 1, -1 };

/* -----  2018/06/20  Problem: AOJ 2703 / Link: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2703  ----- */
/* ------問題------



-----問題ここまで----- */
/* -----解説等-----



----解説ここまで---- */


using uLL = unsigned long long;

const uLL MOD = 1e9;
//BEGIN CUT HERE
struct Dice {
	int s[6];
	void roll(char c) {
		//the view from above
		// N
		//W E
		// S
		//s[0]:top
		//s[1]:south
		//s[2]:east
		//s[3]:west
		//s[4]:north
		//s[5]:bottom
		int b;
		if (c == 'E') {
			b = s[0];
			s[0] = s[3];
			s[3] = s[5];
			s[5] = s[2];
			s[2] = b;
		}
		if (c == 'W') {
			b = s[0];
			s[0] = s[2];
			s[2] = s[5];
			s[5] = s[3];
			s[3] = b;
		}
		if (c == 'N') {
			b = s[0];
			s[0] = s[1];
			s[1] = s[5];
			s[5] = s[4];
			s[4] = b;
		}
		if (c == 'S') {
			b = s[0];
			s[0] = s[4];
			s[4] = s[5];
			s[5] = s[1];
			s[1] = b;
		}

		// migi neji 
		if (c == 'R') {
			b = s[1];
			s[1] = s[2];
			s[2] = s[4];
			s[4] = s[3];
			s[3] = b;
		}

		if (c == 'L') {
			b = s[1];
			s[1] = s[3];
			s[3] = s[4];
			s[4] = s[2];
			s[2] = b;
		}

	}
	int top() {
		return s[0];
	}
	int bottom() {
		return s[5];
	}
	uLL hash() {
		uLL res = 1;
		for (int i = 0; i < 6; i++) res = res * (MOD)+s[i];
		return res;
	}
	void print() {
		cout << "Dice num: ";
		FOR(i, 0, 6) {
			cout << s[i] << " ";
		}
		cout << "Hash: " << this->hash() << endl;
		cout << endl;
	}
};
vector<Dice> makeDices(Dice d) {
	vector<Dice> res;
	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++) {
			res.push_back(t);
			t.roll('E');
		}
	}
	return res;
}
//END CUT HERE

void solve_AOJ_ITP1_11_A() {
	int N = 6;
	Dice D;
	FOR(i, 0, N) {
		int val; cin >> val;
		D.s[i] = val;
	}
	string s; cin >> s;
	FOR(i, 0, SZ(s)) {
		D.roll(s[i]);
	}
	cout << D.top() << endl;
}

void solve_AOJ_ITP1_11_B() {
	Dice D;
	int N = 6;
	FOR(i, 0, N) {
		int val; cin >> val;
		D.s[i] = val;
	}
	vector<Dice> dices = makeDices(D);
	int Q; cin >> Q;
	FOR(i, 0, Q) {
		int TOP, FRONT;
		cin >> TOP >> FRONT;
		FOR(i, 0, SZ(dices)) { //24個
			if (dices[i].top() == TOP && dices[i].s[1] == FRONT) {
				cout << dices[i].s[2] << endl;
				break;
			}
		}
	}
}

void solve_AOJ_ITP1_11_C() {
	Dice d[2];
	FOR(k, 0, 2) {
		FOR(i, 0, 6) {
			int val; cin >> val;
			d[k].s[i] = val;
		}
	}
	uLL hashval = d[0].hash();
	vector<Dice>dices = makeDices(d[1]);
	FOR(i, 0, SZ(dices)) {
		if (hashval == dices[i].hash()) {
			cout << "Yes" << endl;
			return;
		}
	}
	cout << "No" << endl;
}
void solve_AOJ_ITP1_11_D() {
	int N; cin >> N;
	vector<Dice>d(N);
	FOR(k, 0, N) {
		FOR(i, 0, 6) {
			int val; cin >> val;
			d[k].s[i] = val;
		}
	}
	set<uLL>Se;
	Se.insert(d[0].hash());
	FOR(i, 1, N) {
		vector<Dice>dices = makeDices(d[i]);
		int flag = 0;
		FOR(j, 0, SZ(dices)) {
			flag |= (Se.count(dices[j].hash()));
		}
		if (flag) {
			cout << "No" << endl;
			return;
		}
		Se.insert(dices[i].hash());

	}
	cout << "Yes" << endl;
}

void solve_AOJ_0502() {
	int Q;
	while (cin >> Q, Q) {
		Dice d; FOR(i, 0, 6)d.s[i] = i + 1;
		int ans = 1;
		FOR(kim, 0, Q) {
			string s; cin >> s;
			d.roll(s[0]);
			ans += d.top();
		}
		cout << ans << endl;
	}


}

using PII = pair<int, int>;
map<char, char>changeC;
inline  int  mhash(const PII &a) {
	return (a.first + 1200) * 2400 + a.second + 1200;
}
void solve_AOJ_2703() { // えーサイコロ関係なくないですか？ないですね
	const string ORIG = "EWNS";
	const string TO = "RLBF";
	FOR(i, 0, 4) {
		changeC[TO[i]] = ORIG[i];
	}
	int N;
	while (cin >> N, N) {
		vector<map<PII, int>>Map(N);
		int x, y;
		Dice dice;
		FOR(i, 0, N) {
			cin >> x >> y;
			cin >> dice.s[3] >> dice.s[2] >> dice.s[1] >> dice.s[4] >> dice.s[5] >> dice.s[0];
			string s; cin >> s;
			Map[i][PII(y, x)] = dice.bottom();
			FOR(j, 0, SZ(s)) {
				dice.roll(changeC[s[j]]);
				// R,L,B,F
				if (s[j] == 'R')x++;
				if (s[j] == 'L')x--;
				if (s[j] == 'B')y++;
				if (s[j] == 'F')y--;
				// y x の移動
				Map[i][PII(y, x)] = dice.bottom();
			}
		}

		vector<int>bitdp(1 << N, 0);
		FOR(state, 0, 1 << N) {
			unordered_map<int, bool>used; // orderedだと結構遅かった
			FOR(i, 0, N) {
				if (state & 1 << i) {
					for (auto it : Map[i]) {
						used[mhash(it.first)] = 1;
					}
				}
			}
			// 記録した
			FOR(i, 0, N) {
				if (state & 1 << i)continue;
				int addv = 0;

				for (auto it : Map[i]) {
					if (!used.count(mhash(it.first))) {
						addv += it.second;
					}
				}
				bitdp[state | (1 << i)] = max(bitdp[state | (1 << i)], bitdp[state] + addv);
			}
		}
		cout << bitdp[(1 << N) - 1] << endl;

	}
}

void solve_AOJ_1181() {
	int N;
	Dice BaseDi;
	FOR(i, 0, 6)BaseDi.s[i] = i + 1;
	vector<Dice>dices = makeDices(BaseDi);
	while (cin >> N, N) {
		VVI masu(210, VI(210, 0));
		vector<VVI>valset(210, VVI(210, VI()));
		FOR(okaduki, 0, N) {
			int tp, fr; cin >> tp >> fr;
			int X = 100, Y = 100;
			Dice d;
			FOR(i, 0, SZ(dices)) {
				if (dices[i].top() == tp&&dices[i].s[1] == fr) {
					d = dices[i];
					break;
				}
			}
			while (1) {
				masu[Y][X]++;
				// 落ちる方向を決める
				// 大きな方に転がり落ちる
				int dy[] = { -1, 1, 0, 0, -1, };
				int dx[] = { -1, 0, 1, -1, 0, };
				int dir = -1;
				FOR(num, 4, 6 + 1) {
					if (d.top() != num && d.bottom() != num) { //面があれ
						FOR(i, 1, 4 + 1) {
							if (d.s[i] == num) {
								if (masu[Y][X] > masu[Y + dy[i]][X + dx[i]] + 1) {
									dir = i;
								}
							}
						}
					}
				}
				if (dir == -1) {
					valset[Y][X].push_back(d.top());
					break;
				}
				masu[Y][X]--;
				string TO = "$SEWN";
				Y += dy[dir]; X += dx[dir];
				d.roll(TO[dir]);
			}
		}
		VI a(7, 0);
		FOR(i, 0, 210) {
			FOR(j, 0, 210) {
				if (!SZ(valset[i][j]))continue;
				int val = valset[i][j].back();
				a[val]++;
			}
		}
		FOR(i, 1, 6 + 1) {
			cout << a[i] << " \n"[i == 6];
		}

	}

}

vector<Dice>dices;
int tops[3][3], fronts[3][3];
vector<int> ans;
Dice putdice[3][3][3];
void dfs(int state) {
	if (state == 27) {
		int ret = 0;
		FOR(i, 0, 3) {// 右の右をとる s[2]
			FOR(j, 0, 3) {
				ret += putdice[i][2][j].s[2];
			}
		}

		ans.push_back(ret);
	}
	else {
		int X = (state / 3) % 3;
		int Y = state % 3;
		int Z = state / 9;
		FOR(i, 0, 24) { // put dices to putdice
			// ダメなもの top .front がちゃう
			if (Z == 0 && tops[X][Y] && tops[X][Y] != dices[i].top())continue;
			if (X == 2 && fronts[Z][Y] && fronts[Z][Y] != dices[i].s[1])continue;
			// ダメなもの 7じゃない
			if (X&& putdice[X - 1][Y][Z].s[4] + dices[i].s[1] != 7)continue; // 奥
			if (Y&& putdice[X][Y - 1][Z].s[2] + dices[i].s[3] != 7)continue; // 左
			if (Z&& putdice[X][Y][Z - 1].s[5] + dices[i].s[0] != 7)continue; // 上

			putdice[X][Y][Z] = dices[i];
			dfs(state + 1);
		}


	}

}


// 24^27なきもちになるけど前処理すればだいたい決まるので解析しなくても投げる気持ちが固まる
// パラメータの管理壊れる
void solve_AOJ_1253() {
	// 条件を見たすように配置したときの右面の種類
	Dice Base;
	FOR(i, 0, 6)Base.s[i] = i + 1;
	dices = makeDices(Base);

	int Case; cin >> Case;
	FOR(kyo, 0, Case) {
		FOR(i, 0, 3)FOR(j, 0, 3)cin >> tops[i][j];
		FOR(i, 0, 3)FOR(j, 0, 3)cin >> fronts[i][j];
		dfs(0);
		SORT(ans); UNIQ(ans);
		FOR(i, 0, SZ(ans)) {
			cout << ans[i] << " \n"[i == SZ(ans) - 1];
		}
		if (SZ(ans) == 0)cout << 0 << endl;
		ans.clear();
	}




}
Dice resDice[4];
vector<Dice>diceState[4];

void Dfs(int state, const int N, int& ans) {
	if (N == state) {
		int res = 0;
		// あるおきかたについて
		// 一緒になるように最小の塗り分けをする

		FOR(i, 0, 6) { //ある面について
			map<int, int>cnt;
			FOR(k, 0, N) {
				cnt[resDice[k].s[i]]++;
			}
			int mx = 0;
			for (auto it : cnt) {
				mx = max(mx, it.second); // 重複maxが保存すべきもの
			}
			res += N - mx;
		}




		ans = min(ans, res);
		return;
	}
	FOR(i, 0, 24) {
		resDice[state] = diceState[state][i];
		Dfs(state + 1, N, ans);
	}
}

void solve_AOJ_1259() {
	// N diff checkする 全探索 同じにするための塗り替えを最小にする
	int N;
	while (cin >> N, N) {
		if (N == 1) {
			string s; FOR(i, 0, 6)cin >> s;

			cout << 0 << endl;
		}
		else {

			vector<Dice>baseDice(N);
			FOR(i, 0, 4)diceState[i].clear();
			map<string, int>sHash;
			int hp = 1;
			FOR(i, 0, N) {
				FOR(j, 0, 6) {
					string s;  cin >> s;
					if (sHash.find(s) == sHash.end())sHash[s] = hp++;
					baseDice[i].s[j] = sHash[s];
				}
			}
			// 値をいれたので24^(N-1)全部つくる
			FOR(i, 0, N) {
				diceState[i] = makeDices(baseDice[i]);
			}
			int ans = INF;
			resDice[0] = baseDice[0];
			Dfs(1, N, ans);
			cout << ans << endl;
		}
	}


}
 

// R S Vは解けそう

int main() {
	cin.tie(0);
	ios_base::sync_with_stdio(false);

	//solve_AOJ_ITP1_11_A();
	//solve_AOJ_ITP1_11_B();
	//solve_AOJ_ITP1_11_C();
	//solve_AOJ_ITP1_11_D();
	//solve_AOJ_0502();

	//solve_AOJ_1181();
	//solve_AOJ_2703();
	//solve_AOJ_1253();
	solve_AOJ_1259();

	return 0;
}
//
accuracy: 1
time_ms: 190
memory_kb: 3248
final_rank: 7

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;




struct Info{
	char buf[25];
	int count;
};

class Dice{
public:

	void setPos(int num){

		for(int i = 0; i < 6; i++)work[i] = index[i];

		switch(num){
		case 0:
			setindex(work[4],work[0],work[2],work[3],work[5],work[1]);
			break;
		case 1:
			setindex(work[5],work[4],work[2],work[3],work[1],work[0]);
			break;
		case 2:
			setindex(work[1],work[5],work[2],work[3],work[0],work[4]);
			break;
		case 3:
			setindex(work[0],work[1],work[2],work[3],work[4],work[5]);
			break;
		case 4:
			setindex(work[2],work[1],work[5],work[0],work[4],work[3]);
			break;
		case 5:
			setindex(work[4],work[2],work[5],work[0],work[3],work[1]);
			break;
		case 6:
			setindex(work[3],work[4],work[5],work[0],work[1],work[2]);
			break;
		case 7:
			setindex(work[1],work[3],work[5],work[0],work[2],work[4]);
			break;
		case 8:
			setindex(work[5],work[3],work[4],work[1],work[2],work[0]);
			break;
		case 9:
			setindex(work[2],work[5],work[4],work[1],work[0],work[3]);
			break;
		case 10:
			setindex(work[0],work[2],work[4],work[1],work[3],work[5]);
			break;
		case 11:
			setindex(work[3],work[0],work[4],work[1],work[5],work[2]);
			break;
		case 12:
			setindex(work[1],work[0],work[3],work[2],work[5],work[4]);
			break;
		case 13:
			setindex(work[5],work[1],work[3],work[2],work[4],work[0]);
			break;
		case 14:
			setindex(work[4],work[5],work[3],work[2],work[0],work[1]);
			break;
		case 15:
			setindex(work[0],work[4],work[3],work[2],work[1],work[5]);
			break;
		case 16:
			setindex(work[2],work[4],work[0],work[5],work[1],work[3]);
			break;
		case 17:
			setindex(work[1],work[2],work[0],work[5],work[3],work[4]);
			break;
		case 18:
			setindex(work[3],work[1],work[0],work[5],work[4],work[2]);
			break;
		case 19:
			setindex(work[4],work[3],work[0],work[5],work[2],work[1]);
			break;
		case 20:
			setindex(work[0],work[3],work[1],work[4],work[2],work[5]);
			break;
		case 21:
			setindex(work[2],work[0],work[1],work[4],work[5],work[3]);
			break;
		case 22:
			setindex(work[5],work[2],work[1],work[4],work[3],work[0]);
			break;
		case 23:
			setindex(work[3],work[5],work[1],work[4],work[0],work[2]);
			break;
		case 24:
			//Do nothing
			break;
		}
	}

	void setindex(int w0,int w1,int w2,int w3,int w4,int w5){
		index[0] = w0;
		index[1] = w1;
		index[2] = w2;
		index[3] = w3;
		index[4] = w4;
		index[5] = w5;
	}

	void init(){
		index[0] = 2;
		index[1] = 5;
		index[2] = 1;
		index[3] = 4;
		index[4] = 0;
		index[5] = 3;
	}

	int index[6];
	int work[6];
};

int N,info_index;
Dice dice[4];
char color[4][6][25];
Info info[24];

bool strCmp(char* base, char* comp){
	int length1,length2;
	for(length1=0;base[length1] != '\0';length1++);
	for(length2=0;comp[length2] != '\0';length2++);
	if(length1 != length2)return false;

	for(int i=0;base[i] != '\0'; i++){
		if(base[i] != comp[i])return false;
	}
	return true;
}

void strcpy(char* to,char* str){
	for(int i=0;str[i] != '\0';i++){
		to[i] = str[i];
		to[i+1] = '\0';
	}
}


void func(){

	info_index = 0;
	bool FLG;

	for(int i = 0; i < N; i++){
		dice[i].init();
		for(int k = 0; k < 6; k++){
			scanf("%s",color[i][k]);

			FLG = false;
			for(int a = 0;a < info_index; a++){
				if(strCmp(info[a].buf,color[i][k])){
					FLG = true;
					break;
				}
			}
			if(!FLG){
				strcpy(info[info_index].buf,color[i][k]);
				info_index++;
			}
		}
	}

	if(N == 1){
		printf("0\n");
		return;
	}

	int minimum,tmp,tmp_sum,maximum;

	if(N == 2){

		minimum = BIG_NUM;

		for(int i = 0; i <= 24; i++){
			dice[1].init();
			dice[1].setPos(i);

			tmp = 0;

			for(int k = 0; k < 6; k++){
				if(strCmp(color[0][dice[0].index[k]],color[1][dice[1].index[k]]) == false){
					tmp++;
				}
			}

			minimum = min(minimum,tmp);
		}

		printf("%d\n",minimum);

	}else if(N == 3){

		minimum = BIG_NUM;

		for(int a = 0; a <= 24; a++){
			dice[1].init();
			dice[1].setPos(a);
			for(int b = 0; b <= 24; b++){
				dice[2].init();
				dice[2].setPos(b);

				tmp_sum = 0;
				for(int i = 0; i < 6; i++){
					for(int k = 0; k < info_index; k++)info[k].count = 0;

					for(int p = 0; p < 3; p++){
						for(int k = 0; k < info_index; k++){
							if(strCmp(info[k].buf,color[p][dice[p].index[i]])){
								info[k].count++;
								break;
							}
						}
					}

					maximum = 1;
					for(int k = 0; k < info_index; k++)maximum = max(maximum,info[k].count);

					tmp_sum += N-maximum;
				}
				minimum = min(minimum,tmp_sum);
			}
		}

		printf("%d\n",minimum);

	}else{ //N == 4

		minimum = BIG_NUM;

		for(int a = 0; a <= 24; a++){
			dice[1].init();
			dice[1].setPos(a);
			for(int b = 0; b <= 24; b++){
				dice[2].init();
				dice[2].setPos(b);

				for(int c = 0; c <= 24; c++){
					dice[3].init();
					dice[3].setPos(c);

					tmp_sum = 0;
					for(int i = 0; i < 6; i++){
						for(int k = 0; k < info_index; k++)info[k].count = 0;

						for(int p = 0; p < 4; p++){
							for(int k = 0; k < info_index; k++){
								if(strCmp(info[k].buf,color[p][dice[p].index[i]])){
									info[k].count++;
									break;
								}
							}
						}

						maximum = 1;
						for(int k = 0; k < info_index; k++)maximum = max(maximum,info[k].count);

						tmp_sum += N-maximum;
					}
					minimum = min(minimum,tmp_sum);
				}
			}
		}
		printf("%d\n",minimum);
	}
}

int main(){

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

		func();
	}
	return 0;
}
accuracy: 1
time_ms: 300
memory_kb: 3192
final_rank: 10

code_snippet: int dice24[24][6]=
{
	{2,1,5,0,4,3},{2,0,1,4,5,3},{2,4,0,5,1,3},{2,5,4,1,0,3},{4,2,5,0,3,1},
	{5,2,1,4,3,0},{1,2,0,5,3,4},{0,2,4,1,3,5},{0,1,2,3,4,5},{4,0,2,3,5,1},
	{5,4,2,3,1,0},{1,5,2,3,0,4},{5,1,3,2,4,0},{1,0,3,2,5,4},{0,4,3,2,1,5},
	{4,5,3,2,0,1},{1,3,5,0,2,4},{0,3,1,4,2,5},{4,3,0,5,2,1},{5,3,4,1,2,0},
	{3,4,5,0,1,2},{3,5,1,4,0,2},{3,1,0,5,4,2},{3,0,4,1,5,2},
};
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;

const int maxn=4;
int n,dice[maxn][6],ans;

vector<string> names;
int  ID(const char* name)
{
	string s(name);
	int n=names.size();
	for (int i=0;i<n;i++)
	if (names[i]==s) return i;
	names.push_back(s);
	return n;
}

int r[maxn],color[maxn][6];

void check()
{
	for (int i=0;i<n;i++)
		for (int j=0;j<6;j++)
		color[i][dice24[r[i]][j]]=dice[i][j];
	int tot=0;
	for (int j=0;j<6;j++)
	{
		int cnt[maxn*6];
		memset(cnt,0,sizeof(cnt));
		int maxface=0;
		for (int i=0;i<n;i++)
			maxface=max(maxface,++cnt[color[i][j]]);
		tot+=n-maxface;
	}
	ans=min(ans,tot);
}

void dfs(int d)
{
	if (d==n) check();
	else for(int i=0;i<24;i++)
	{
		r[d]=i;
		dfs(d+1);
	}
}
int main()
{
	while (scanf("%d",&n)==1&&n)
	{
		names.clear();
		for (int i=0;i<n;i++)
			for (int j=0;j<6;j++)
			{
				char name[30];
				scanf("%s",name);
				dice[i][j]=ID(name);
			}
		ans=n*6;
		r[0]=0;
		dfs(1);
		printf("%d\n",ans);
	}
	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 2732
final_rank: 3

code_snippet: #include <bits/stdc++.h>
 
using namespace std;
 
class Dice{
private:
    int tmp;
public:
    int d[6];
 
    void rollN(){
	tmp = d[0];
	d[0] = d[1];
	d[1] = d[5];
	d[5] = d[4];
	d[4] = tmp;
    }
    void rollE(){
	tmp = d[0];
	d[0] = d[3];
	d[3] = d[5];
	d[5] = d[2];
	d[2] = tmp;
    }
    void rotation(){
	tmp = d[1];
	d[1] = d[3];
	d[3] = d[4];
	d[4] = d[2];
	d[2] = tmp;
    }
    bool operator < (const Dice &die)const{
	for(int i = 0 ; i < 6 ; i++){
	    if(d[i] != die.d[i]) return d[i] < die.d[i];
	}
	return false;
    }
};
 
int N,ans,p[4];
map<string,int> mp;
vector<Dice> dice[4];
 
int getCost(){
    int res = 0;
    for(int i = 0 ; i < 6 ; i++){
	int cnt[25] = {0}, max = 0;
	for(int j = 0 ; j < N ; j++){
	    cnt[dice[j][p[j]].d[i]]++;
	    max = std::max(max,cnt[dice[j][p[j]].d[i]]);
	}
	res += N-max;
    }
    return res;
}
 
void solve(int x){
    if(x == N){
	ans = min(ans,getCost());
	return;
    }
    for(int i = 0 ; i < (int)dice[x].size() ; i++){
	p[x] = i;
	solve(x+1);
    }
}
 
vector<Dice> make(Dice die){
    vector<Dice> res;
    set<Dice> visited;
    for(int i = 0 ; i < 4 ; i++){
	for(int j = 0 ; j < 4 ; j++){
	    if(!visited.count(die)){
		visited.insert(die);
		res.push_back(die);
	    }
	    die.rollN();
	}
	for(int j = 0 ; j < 4 ; j++){
	    if(!visited.count(die)){
		visited.insert(die);
		res.push_back(die);
	    }
	    die.rollE();
	}
	die.rotation();
    }
    return res;
}
 
int main(){
    Dice in;
    while(cin >> N, N){
	int n = 0;
	mp.clear();
	for(int i = 0 ; i < N ; i++){
	    p[i] = -1;
	    for(int j = 0 ; j < 6 ; j++){
		string s;
		cin >> s;
		if(mp.find(s) != mp.end()){
		    in.d[j] = mp[s];
		}else{
		    mp[s] = n++;
		    in.d[j] = mp[s];
		}
	    }
	    dice[i] = make(in);
	}
	ans = 1e9;
	solve(0);
	cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 280
memory_kb: 3028
final_rank: 4

code_snippet: // Colored Cubes 
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1259

#include<iostream>
#include<map>
#include<vector>
#include<algorithm>
#include<cmath>
#include<climits>
#include<ctime>
#include<cstring>
#include<numeric>
#include<functional>

#define ALL(v) (v).begin(),(v).end()
#define REP(i,p,n) for(int i=p;i<(int)(n);++i)
#define rep(i,n) REP(i,0,n)
#define dump(a) (cerr << #a << "=" << (a) << endl)
#define DUMP(list) cout << "{ "; for(auto nth : list){ cout << nth << " "; } cout << "}" << endl;

using namespace std;

enum AXIS {X, Y, Z};
const int INF = INT_MAX / 3;
const vector<vector<int>> pattern = {
    {3, 1, 0, 5, 4, 2}, // x????????¢
    {4, 0, 2, 3, 5, 1}, // y????????¢
    {0, 3, 1, 4, 2, 5}  // z????????¢
};

int N;
int ans, max_color;
vector<vector<int>> cubes;

void roll(int n, int axis) {
    vector<int> result;
    vector<int> cube = cubes[n];
    for (int p : pattern[axis]) {
        result.push_back(cube[p]);
    }
    cubes[n] = result;
}

int repaint() {
    int res = 0;
    for (int j = 0; j < 6; ++j) {
        vector<int> counter(max_color);
        for (int i = 0; i < N; ++i) {
            ++counter[cubes[i][j]];
        }
        int most = *max_element(ALL(counter));
        res += N - most;
    }
    return res;
}

void dfs(int n) {
    if (n == N) {
        ans = min(ans, repaint());
        return;
    }
    for (int i = 0; i < 6; ++i) {
        for (int x = 0; x < 4; ++x) {
            dfs(n + 1);
            roll(n, X);
        }
        if (i % 2 == 0) {
            roll(n, Y);
        } else {
            roll(n, Z);
        }
    }
    return;
}

int main() { 
    while (cin >> N) {
        if (N == 0) break;

        map<string, int> converter;
        const function<int(string)> encode = [&](const string &color) -> int {
            if (!converter.count(color)) converter.emplace(color, converter.size());
            return converter[color];
        };

        cubes.assign(4, vector<int>(6, 0));
        for (int i = 0; i < N; ++i) {
            for (int j = 0; j < 6; ++j) {
                string color;
                cin >> color;
                cubes[i][j] = encode(color);
            }
        }

        ans = INF, max_color = converter.size();
        dfs(0);
        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 2410
memory_kb: 3164
final_rank: 17

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;

//   swap(d[], d[]);
void rot1(vector <int> &d) {
  swap(d[1], d[2]);
  swap(d[2], d[4]);
  swap(d[4], d[3]);
}
void rot2(vector <int> &d) {
  swap(d[1], d[0]);
  swap(d[0], d[4]);
  swap(d[4], d[5]);
}
void rot3(vector <int> &d) {
  swap(d[0], d[3]);
  swap(d[3], d[5]);
  swap(d[5], d[2]);
}
void rev1(vector <int> &d) {
  swap(d[1], d[3]);
  swap(d[3], d[4]);
  swap(d[4], d[2]);
}
void rev2(vector <int> &d) {
  swap(d[1], d[5]);
  swap(d[5], d[4]);
  swap(d[4], d[0]);
}
void rev3(vector <int> &d) {
  swap(d[0], d[2]);
  swap(d[2], d[5]);
  swap(d[5], d[3]);
}

int main() {
  int ttt = 0;
  while (true) {
    int n;
    cin >> n;
    if (n == 0) break;
    int cnt = 0;
    map <string, int> memo;
    vector <int> d[n];
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < 6; j++){
        string s;
        cin >> s;
        if (memo.find(s) == memo.end()) {
          d[i].push_back(cnt);
          memo[s] = cnt;
          cnt++;
        }else {
          d[i].push_back(memo[s]);
        }
      }
    }
    if (n == 1) {
      cout << 0 << endl;
      continue;
    }

    set<vector<vector<int> > > cut;
    stack <vector<vector<int> > > st;
    int ans = INT_MAX;
    bool same = true;
    for (int i = 0; i < 6; i++) {
      for (int j = 1; j < n; j++) {
        if (d[j][i] != d[j-1][i]) {
          same = false;
          break;
        }
      }
      if (!same) break;
    }
    if (same) {
      ans = 0;
    }
    vector <vector <int> > t;
    for (int i = 0; i < n; i++) {
      t.push_back(d[i]);
    }
    st.push(t);
    cut.insert(t);
    while (!st.empty()) {
      vector <vector<int> > np = st.top(); st.pop();

      for (int i = 1; i < n; i++) {
        for (int ch = 0; ch < 6; ch++) {
          vector <vector<int> > tnp = np;
          if (ch == 0) {
            rot1(tnp[i]);
          }else if (ch == 1) {
            rot2(tnp[i]);
          }else if (ch == 2){
            rot3(tnp[i]);
          }else if (ch == 3) {
            rev1(tnp[i]);
          }else if (ch == 4) {
            rev2(tnp[i]);
          }else if (ch == 5) {
            rev3(tnp[i]);
          }
          if (cut.find(tnp) != cut.end()) {
            continue;
          }
          st.push(tnp);
          cut.insert(tnp);
          int tsum = 0;
          for (int j = 0; j < 6; j++) {
            int tcnt[cnt];
            memset(tcnt, 0, sizeof(tcnt));
            int maxp = 0;
            for (int k = 0; k < n; k++) {
              tcnt[tnp[k][j]]++;
              if (tcnt[tnp[k][j]] > tcnt[maxp]) {
                maxp = tnp[k][j];
              }
            }
            tsum += n-tcnt[maxp];
          }
          ans = min(ans, tsum);
        }
      }
    }
    int tsum = 0;
    for (int j = 0; j < 6; j++) {
      int tcnt[cnt];
      memset(tcnt, 0, sizeof(tcnt));
      int maxp = 0;
      for (int k = 0; k < n; k++) {
        tcnt[d[k][j]]++;
        if (tcnt[d[k][j]] > tcnt[maxp]) {
          maxp = d[k][j];
        }
      }
      tsum += n-tcnt[maxp];
    }

    cout << min(ans, tsum) << endl;
  }
}
accuracy: 1
time_ms: 2400
memory_kb: 8140
final_rank: 20

code_snippet: #include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <iostream>

using namespace std;

const int mov[24][6]= {
  {0,1,2,3,4,5},{0,2,4,1,3,5},{0,4,3,2,1,5},{0,3,1,4,2,5},
  {3,1,0,5,4,2},{3,0,4,1,5,2},{3,4,5,0,1,2},{3,5,1,4,0,2},
  {5,1,3,2,4,0},{5,3,4,1,2,0},{5,4,2,3,1,0},{5,2,1,4,3,0},
  {2,1,5,0,4,3},{2,5,4,1,0,3},{2,4,0,5,1,3},{2,0,1,4,5,3},
  {4,0,2,3,5,1},{4,2,5,0,3,1},{4,5,3,2,0,1},{4,3,0,5,2,1},
  {1,0,3,2,5,4},{1,3,5,0,2,4},{1,5,2,3,0,4},{1,2,0,5,3,4}
};

struct Cube {
	int num[7];
};

int n, cnt, ans;
char str[1000];
Cube c[5], now[5];
map<string,int> id;

int ID(char *st) {
	if (id[st] == 0) return id[st] = ++cnt;
	return id[st];
}

void dfs(int dep) {
	if (n == dep) {
		int ans1 = 0;
		for (int j = 0; j < 6; ++j) {
			int count[30] = {0};
			for (int i = 0; i < n; ++i) ++count[now[i].num[j]];
			int up = 0;
			for (int i = 1; i <= cnt; ++i) up = max(up, count[i]);
			ans1 += n - up;
		}
		ans = min(ans, ans1);
		return ;	
	}
	for (int i = 0; i < 24; ++i) {
		for (int j = 0; j < 6; ++j) {
			now[dep].num[j] = c[dep].num[mov[i][j]];
		}
		dfs(dep + 1);
	}
}

void Clear() {
	memset(c, 0, sizeof c);
	memset(now, 0, sizeof now);
	id.clear();
	cnt = 0;
}

int main() {
	while (1 == scanf("%d", &n)) {
		if (0 == n) break;
		Clear();
		for (int i = 0; i < n; ++i) {
			for (int j = 0; j < 6; ++j) {
				scanf("%s", str);
				c[i].num[j] = ID(str);
			}
		}
		if (1 == n) {
			puts("0");
			continue;
		}
		ans = (int)1e9;
		now[0] = c[0];
		dfs(1);
		printf("%d\n", ans);
	}
	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 1244
final_rank: 1

code_snippet: /*************************************************************************
  > File Name: c.cpp
  > Author: X__X
  > Mail: Kinderlas@gmail.com 
  > Created Time: 2012/8/12 14:35:54
 ************************************************************************/

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<stack>
#include<queue>
#include<utility>
using namespace std;

#define MP make_pair
#define PB push_back
#define IT iterator
#define B begin() 
#define E end()
#define X first
#define Y second
#define foreach(it, container) \
    for(typeof((container).begin()) it = (container).begin();it!=(container).end();++it)
#define CLR(a, x) memset(a, x, sizeof (a));
typedef vector<int> VI;
typedef pair<int,int> PII;
VI::IT it;
void op(int n){cout << n << ' ';}

const int inf = 0x3f3f3f3f;
const int maxn = 1e8+10;
int ELFhash(char *key, long N)
{
    unsigned long h = 0;
    unsigned long x = 0;
    while(*key)
    {
        h = (h << 4) + (*key++);
        if( (x = h & 0xF0000000L) != 0)
        {
            h ^= (x >> 24);
            h &= ~x;
        }
    }
    return h % N;
}

int cube[4][10];
int tcube[4][10];
int ttcube[4][10];
int _rotate[6][6] = 
{
    {1, 2, 3, 4, 5, 6}, {5, 1, 3, 4, 6, 2},
    {4, 2, 1, 6, 5, 3}, {2, 6, 3, 4, 1, 5},
    {6, 5, 3, 4, 2, 1}, {3, 2, 6, 1, 5, 4}
};
int _Rotate[40][6];


char s[100];

int cnts[10];
int tt[10][10];
int n, ans;
void dfs(int k)
{ 
    if(n == k)
    {
        int tans = 0, cnt = 0;
        for(int i = 1; i <= 6; i++)
        {
            for(int j = 0; j < n; j++)
                tt[i][j] = tcube[j][i];
        }
        for(int i = 1; i <= 6; i++)
        {
            cnt = 0;
            for(int j = 0; j < n; j++)
                cnt = max(cnt, (int)count(tt[i], tt[i]+n, tt[i][j]));
            tans += cnt;
        }
        ans = min(ans, n*6-tans);
        return ;
    }
    for(int i = 0; i < 36; i++)
    {
        if(_Rotate[i][0] != -1)
        {
            for(int j = 1; j <= 6; j++)
            {
                tcube[k][j] = cube[k][_Rotate[i][j-1]];
                /*for(int ii = 0; ii < 6; ii++)
                  {
                  for(int jj = 1; jj <= 6; jj++)
                  ttcube[k][jj] = tcube[k][_rotate[ii][jj-1]];
                  dfs(k+1);
                  }*/
            }
            dfs(k+1);
        }
    }
}

void solve()
{
    for(int i = 0; i < n; i++)
    {
        for(int j = 1; j <= 6; j++)
        {
            scanf("%s", s);
            cube[i][j] = ELFhash(s, 10000007);
        }
    }
    ans = inf;
    dfs(0);
    printf("%d\n", ans);
}

bool check(int ii, int jj)
{
    for(int i = 0; i < 6; i++)
        if(_Rotate[ii][i] != _Rotate[jj][i])
            return false;
    return true;
}

int main()
{
    for(int i = 0, cnt = 0; i < 6; i++)
    {
        for(int j = 0; j < 6; j++)
        {
            for(int k = 0; k < 6; k++)
                _Rotate[cnt][k] = _rotate[i][_rotate[j][k]-1];
            cnt++;
        }
    }
    for(int i = 0; i < 36; i++)
        for(int j = 0; j < 36; j++)
            if(i != j && check(i, j))
                for(int k = 0; k < 6; k++)
                    _Rotate[i][k] = -1;
    while(scanf("%d", &n), n)
        solve();
}
accuracy: 1
time_ms: 200
memory_kb: 1192
final_rank: 2