// Written by Attractive Chaos; distributed under the MIT license (D V.2 code)
import std.stdio, std.conv;
pure nothrow double[][] matGen(in int n) {
immutable double tmp = 1.0 / n / n;
auto a = new double[][](n, n);
foreach (int i, row; a)
foreach (int j, ref x; row)
x = tmp * (i - j) * (i + j);
return a;
}
pure nothrow double[][] matMul(in double[][] a, in double[][] b) {
immutable int m = a.length,
n = a[0].length,
p = b[0].length;
// transpose
auto c = new double[][](p, n);
foreach (i, brow; b)
foreach (j, bx; brow)
c[j][i] = bx;
auto x = new double[][](m, p);
foreach (i, arow; a)
foreach (j, crow; c) {
// x[i][j] = std.numeric.dotProduct(arow, crow); // right way
double s = 0.0;
foreach (k, arowk; arow)
s += arowk * crow[k];
x[i][j] = s;
}
return x;
}
void main(in string[] args) {
const int n = ((args.length >= 2) ? to!int(args[1]) : 100) / 2 * 2;
const a = matGen(n);
const b = matGen(n);
const x = matMul(a, b);
writeln(x[n / 2][n / 2]);
}