--- /dev/null
+#!/usr/bin/awk -f
+
+BEGIN {
+ FS = ","
+ N = 1000
+ n = 0
+}
+
+!/^[0-9,]*$/ {
+ print "error line", NR, $0
+}
+
+{
+ n++
+ x[n] = $1
+ y[n] = $2
+ z[n] = $3
+}
+
+function dist(x, y, z, i, j, xx, yy, zz) {
+ xx = (x[i] - x[j])
+ yy = (y[i] - y[j])
+ zz = (z[i] - z[j])
+ return xx * xx + yy * yy + zz * zz
+}
+
+function mat(d, x, y, z, n, i, j) {
+ for (i = 1; i <= n; i++) {
+ for (j = 1; j <= n; j++) {
+ if (i < j) d[i "," j] = dist(x, y, z, i, j)
+ }
+ }
+}
+
+function min(d, n, i, j, m, m0, d0, t) {
+ d0 = 0
+ m0 = ""
+ for (i = 1; i <= n; i++) {
+ for (j = 1; j < i; j++) {
+ m = i "," j
+ t = d[m]
+ if ((t > 0) && ((d0 == 0) || (d0 > t))) {
+ d0 = t
+ m0 = m
+ }
+ }
+ }
+ return m0
+}
+
+function disp(d, x, y, z, p, i, j) {
+ i = p[1]
+ j = p[2]
+ printf "%d: (%d %d) %d,%d,%d -> %d,%d,%d\n", d[i "," j], i, j, x[i], y[i], z[i], x[j], y[j], z[j]
+}
+
+function dispmat(d, n, i, j) {
+ for (i = 1; i <= n; i++) {
+ for (j = 1; j <= n; j++) {
+ printf " %1.4e", d[i "," j]
+ }
+ printf "\n"
+ }
+}
+
+function sortmat(d, o, N, i, j, b, t, L) {
+ L = 0
+ for (i in d) b[++L] = i
+ for (i = 0; i < N; i++) {
+ printf "\b\b\b%d%%", i * 100 / N
+ for (j = 1; j < L - i; j++) {
+ if (d[b[j]] < d[b[j + 1]]) {
+ t = b[j]
+ b[j] = b[j + 1]
+ b[j + 1] = t
+ }
+ }
+ }
+ printf "\n"
+ for (i = 1; i <= N; i++) o[i] = b[L - i + 1]
+}
+
+function group(g, p, f, gg, i, j, k, l) {
+ for (i in g) {
+ delete gg
+ split(g[i], gg, ",")
+ delete f
+ for (j in gg) for (k in p) if (gg[j] == p[k]) f[k] = 1
+ if (length(f) > 0) {
+ l = length(gg)
+ for (k in p) {
+ if (!f[k]) g[i] = g[i] "," p[k]
+ }
+ delete gg
+ split(g[i], gg, ",")
+ return (l < length(gg)) ? 2 : 1
+ }
+ }
+ return 0
+}
+
+function last(g, i, n) {
+ n = 0
+ for (i in g) if (i > n) n = i
+ return n
+}
+
+function adisp(n, g, i) {
+ printf "%s:", n
+ for (i in g) printf " %s", g[i]
+ printf "\n"
+}
+
+END {
+ print "distance"
+ mat(d, x, y, z, n)
+ #dispmat(d, n)
+
+ print "sort"
+ L = sortmat(d, o, N)
+ for (i = 1; i <= N; i++) printf " %s", o[i]; printf "\n"
+
+ print "pairing"
+ delete g
+ for (i = 1; i <= N; i++) {
+ m = o[i]
+ split(m, p, ",")
+ printf "%d: ", i; disp(d, x, y, z, p)
+ if (group(g, p) == 0) {
+ g[i] = m
+ } else {
+ for (j in g) {
+ split(g[j], p, ",")
+ if (group(g, p) == 2) delete g[j]
+ }
+ }
+ }
+ adisp("group", g)
+
+ print "size"
+ for (i in g) {
+ split(g[i], gg, ",")
+ s[i] = length(gg)
+ }
+ adisp("size", s)
+
+ print "result"
+ asort(s)
+ r = 1
+ for (i = 0; i < 3; i++) r *= s[length(s) - i]
+ print r
+}
--- /dev/null
+#!/usr/bin/awk -f
+
+BEGIN {
+ FS = ","
+ N = -1
+ n = 0
+}
+
+!/^[0-9,]*$/ {
+ print "error line", NR, $0
+}
+
+{
+ n++
+ x[n] = $1
+ y[n] = $2
+ z[n] = $3
+}
+
+function dist(x, y, z, i, j, xx, yy, zz) {
+ xx = (x[i] - x[j])
+ yy = (y[i] - y[j])
+ zz = (z[i] - z[j])
+ return xx * xx + yy * yy + zz * zz
+}
+
+function mat(d, x, y, z, n, i, j) {
+ for (i = 1; i <= n; i++) {
+ for (j = 1; j <= n; j++) {
+ if (i < j) d[i "," j] = dist(x, y, z, i, j)
+ }
+ }
+}
+
+function min(d, n, i, j, m, m0, d0, t) {
+ d0 = 0
+ m0 = ""
+ for (i = 1; i <= n; i++) {
+ for (j = 1; j < i; j++) {
+ m = i "," j
+ t = d[m]
+ if ((t > 0) && ((d0 == 0) || (d0 > t))) {
+ d0 = t
+ m0 = m
+ }
+ }
+ }
+ return m0
+}
+
+function disp(d, x, y, z, p, i, j) {
+ i = p[1]
+ j = p[2]
+ printf "%d: (%d %d) %d,%d,%d -> %d,%d,%d\n", d[i "," j], i, j, x[i], y[i], z[i], x[j], y[j], z[j]
+}
+
+function dispmat(d, n, i, j) {
+ for (i = 1; i <= n; i++) {
+ for (j = 1; j <= n; j++) {
+ printf " %1.4e", d[i "," j]
+ }
+ printf "\n"
+ }
+}
+
+function sortmat(d, o, N, i, j, b, t, L) {
+ L = 0
+ for (i in d) b[++L] = i
+ if (N == -1) N = L
+ for (i = 0; i < N; i++) {
+ printf "\b\b\b%d%%", i * 100 / N
+ for (j = 1; j < L - i; j++) {
+ if (d[b[j]] < d[b[j + 1]]) {
+ t = b[j]
+ b[j] = b[j + 1]
+ b[j + 1] = t
+ }
+ }
+ }
+ printf "\n"
+ for (i = 1; i <= N; i++) o[i] = b[L - i + 1]
+ return N
+}
+
+function group(g, p, f, gg, i, j, k, l) {
+ for (i in g) {
+ delete gg
+ split(g[i], gg, ",")
+ delete f
+ for (j in gg) for (k in p) if (gg[j] == p[k]) f[k] = 1
+ if (length(f) > 0) {
+ l = length(gg)
+ for (k in p) {
+ if (!f[k]) g[i] = g[i] "," p[k]
+ }
+ delete gg
+ split(g[i], gg, ",")
+ return (l < length(gg)) ? 2 : 1
+ }
+ }
+ return 0
+}
+
+function last(g, i, n) {
+ n = 0
+ for (i in g) if (i > n) n = i
+ return n
+}
+
+function adisp(n, g, i) {
+ printf "%s:", n
+ for (i in g) printf " %s", g[i]
+ printf "\n"
+}
+
+END {
+ print "distance"
+ mat(d, x, y, z, n)
+ #dispmat(d, n)
+
+ print "sort"
+ N = sortmat(d, o, N)
+ for (i = 1; i <= N; i++) printf " %s", o[i]; printf "\n"
+
+ print "pairing"
+ delete g
+ for (i = 1; i <= N; i++) {
+ m = o[i]
+ split(m, p, ",")
+ printf "%d: ", i; disp(d, x, y, z, p)
+ if (group(g, p) == 0) {
+ g[i] = m
+ } else {
+ for (j in g) {
+ split(g[j], p, ",")
+ if (group(g, p) == 2) delete g[j]
+ }
+ }
+ }
+ adisp("group", g)
+
+ split(m, p, ",")
+ print "prod", x[p[1]] * x[p[2]]
+
+ print "size"
+ for (i in g) {
+ split(g[i], gg, ",")
+ s[i] = length(gg)
+ }
+ adisp("size", s)
+
+ print "result"
+ asort(s)
+ r = 1
+ for (i = 0; i < 3; i++) r *= s[length(s) - i]
+ print r
+
+}