#! /bin/awk -f
##
##
## I'm not super happy with how this code looks. Rest assured, though,
## the C version would look far, far worse.
##
##
function qsort(A, left, right, i, last) {
if (left >= right)
return
swap(A, left, left+int((right-left+1)*rand()))
last = left
for (i = left+1; i <= right; i++)
if (A[i] < A[left])
swap(A, ++last, i)
swap(A, left, last)
qsort(A, left, last-1)
qsort(A, last+1, right)
}
function swap(A, i, j, t) {
t = A[i]; A[i] = A[j]; A[j] = t
}
function escape(s) {
gsub("&", "&", s)
gsub("<", "<", s)
gsub(">", ">", s)
return s
}
BEGIN {
base = ENVIRON["CTF_BASE"]
if (! base) {
base = "/var/lib/ctf"
}
# Only display two decimal places
CONVFMT = "%.2f"
# New point at least every 2.5 minutes
interval = 150
tslen = 0
nteams = 0;
}
# MAINLOOP
{
time = $1
hash = $2
cat = $3
points = int($4)
# Build a list of team names
if (! (hash in team_names)) {
fn = sprintf("%s/teams/names/%s", base, hash)
getline team_names[hash] < fn
print (hash, team_names[hash])
close(fn)
}
# Total points possible so far in this category
if (! ((cat, points) in cat_pointval)) {
cat_total[cat] += points
cat_pointval[cat, points] = 1
}
# Enumerate categories
if (! (cat in seen_cats)) {
seen_cats[cat] = 1
categories[ncats++] = cat
}
# Points this team has in this category
cat_points[hash, cat] += points
}
END {
# Adjust per-category points to a per-category percentage complete
for (hash in team_names) {
for (cat in cat_total) {
cat_score[hash, cat] = cat_points[hash, cat] / cat_total[cat]
total_score[hash] += cat_score[hash, cat]
}
scores[nteams++] = total_score[hash]
}
# Sort scores
qsort(scores, 0, nteams-1)
for (i = nteams-1; i >= 0; i -= 1) {
score = scores[i];
if (score == scores[i-1]) continue; # Skip duplicates
for (hash in team_names) {
if (total_score[hash] != score) {
continue;
}
name = team_names[hash]
printf("%s\n", name)
for (ncat = 0; ncat < ncats; ncat += 1) {
cat = categories[ncat];
points = cat_points[hash, cat];
if (cat_points[hash, cat] > 0) {
printf("", cat, points, escape(name))
printf(" %d\n",
ncat, cat_score[hash, cat] * 100, cat_points[hash, cat])
}
}
}
}
}