namespace Test {
class Vec :IComparable{
public int[] d;
public int id;
public int CompareTo(object obj) {
Vec b = (Vec)obj;
for (int i = 0; i &< 3; i++) {
if (d[i] != b.d[i]) {
return d[i] - b.d[i];
}
}
return 0;
}
}
class Program {
static Vec[] rowVec = new Vec[3];
static Vec[] colVec = new Vec[3];
static int[] minimalRepresentation(int[] d) {
for (int i = 0; i &< 3; i++) {
rowVec[i].id = i;
for (int j = 0; j &< 3; j++) {
rowVec[i].d[j] = d[i * 3 + j];
}
Array.Sort(rowVec[i].d);
}
Array.Sort(rowVec);
for (int i = 0; i &< 3; i++) {
colVec[i].id = i;
for (int j = 0; j &< 3; j++) {
colVec[i].d[j] = d[j * 3 + i];
}
Array.Sort(colVec[i].d);
}
Array.Sort(colVec);
int[] ans = new int[9];
for (int i = 0; i &< 3; i++) {
for (int j = 0; j &< 3; j++) {
ans[i * 3 + j] = d[rowVec[i].id * 3 + colVec[j].id];
}
}
return ans;
}
static int Score(int[] d, bool wantMax, int step, bool[] used, Dictionary&[] cache) {
int k = 0;
for (int i = 0; i &< d.Length; i++)
k = k * 10 + d[i];
if (!cache[step].ContainsKey(k)) {
if (step == d.Length)
cache[step][k] = d[0] * d[1] * d[2] + d[3] * d[4] * d[5] + d[6] * d[7] * d[8]
- d[0] * d[3] * d[6] - d[1] * d[4] * d[7] - d[2] * d[5] * d[8];
else {
if (wantMax)
cache[step][k] = int.MinValue;
else
cache[step][k] = int.MaxValue;
for (int i = 0; i &< d.Length; i++)
if (d[i] == 0)
for (int j = 0; j &< used.Length; j++)
if (!used[j]) {
used[j] = true;
d[i] = j + 1;
if (wantMax)
cache[step][k] = Math.Max(cache[step][k], Score(minimalRepresentation(d), !wantMax, step + 1, used, cache));
else
cache[step][k] = Math.Min(cache[step][k], Score(minimalRepresentation(d), !wantMax, step + 1, used, cache));
used[j] = false;
d[i] = 0;
}
}
}
return cache[step][k];
}
static void Main(string[] args) {
Dictionary&[] cache = new Dictionary&[10];
for (int i = 0; i &< cache.Length; i++)
cache[i] = new Dictionary&();
for (int i = 0; i &< 3; i++) {
rowVec[i] = new Vec();
rowVec[i].d = new int[3];
colVec[i] = new Vec();
colVec[i].d = new int[3];
}
int s = Score(new int[9], true, 0, new bool[9], cache);
Console.WriteLine(s);
Console.WriteLine("");
for (int i = 0; i &< 10; i++) {
Console.WriteLine(cache[i].Count);
}
}
}
}