This commit involves only file moves and renames.
--- /dev/null
+/*
+ * md5crypt based on lib/md5crypt.c from Linux shadow package.
+ * adapted by Martin Mares <mj@ucw.cz> in June 2004
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ */
+
+#include "lib/lib.h"
+#include "lib/md5.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */
+ "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+static void
+to64(char *s, unsigned int v, int n)
+{
+ while (--n >= 0)
+ {
+ *s++ = itoa64[v&0x3f];
+ v >>= 6;
+ }
+}
+
+static char *
+libshadow_md5_crypt(const char *pw, const char *salt)
+{
+ static char *magic = "$1$"; /*
+ * This string is magic for
+ * this algorithm. Having
+ * it this way, we can get
+ * get better later on
+ */
+ static char passwd[120], *p;
+ static const char *sp,*ep;
+ unsigned char final[16];
+ int sl,pl,i,j;
+ struct MD5Context ctx,ctx1;
+ unsigned long l;
+
+ /* Refine the Salt first */
+ sp = salt;
+
+ /* If it starts with the magic string, then skip that */
+ if(!strncmp(sp,magic,strlen(magic)))
+ sp += strlen(magic);
+
+ /* It stops at the first '$', max 8 chars */
+ for(ep=sp;*ep && *ep != '$' && ep < (sp+8);ep++)
+ continue;
+
+ /* get the length of the true salt */
+ sl = ep - sp;
+
+ MD5Init(&ctx);
+
+ /* The password first, since that is what is most unknown */
+ MD5Update(&ctx,pw,strlen(pw));
+
+ /* Then our magic string */
+ MD5Update(&ctx,magic,strlen(magic));
+
+ /* Then the raw salt */
+ MD5Update(&ctx,sp,sl);
+
+ /* Then just as many characters of the MD5(pw,salt,pw) */
+ MD5Init(&ctx1);
+ MD5Update(&ctx1,pw,strlen(pw));
+ MD5Update(&ctx1,sp,sl);
+ MD5Update(&ctx1,pw,strlen(pw));
+ MD5Final(final,&ctx1);
+ for(pl = strlen(pw); pl > 0; pl -= 16)
+ MD5Update(&ctx,final,pl>16 ? 16 : pl);
+
+ /* Don't leave anything around in vm they could use. */
+ memset(final,0,sizeof final);
+
+ /* Then something really weird... */
+ for (j=0,i = strlen(pw); i ; i >>= 1)
+ if(i&1)
+ MD5Update(&ctx, final+j, 1);
+ else
+ MD5Update(&ctx, pw+j, 1);
+
+ /* Now make the output string */
+ strcpy(passwd,magic);
+ strncat(passwd,sp,sl);
+ strcat(passwd,"$");
+
+ MD5Final(final,&ctx);
+
+ /*
+ * and now, just to make sure things don't run too fast
+ * On a 60 Mhz Pentium this takes 34 msec, so you would
+ * need 30 seconds to build a 1000 entry dictionary...
+ */
+ for(i=0;i<1000;i++) {
+ MD5Init(&ctx1);
+ if(i & 1)
+ MD5Update(&ctx1,pw,strlen(pw));
+ else
+ MD5Update(&ctx1,final,16);
+
+ if(i % 3)
+ MD5Update(&ctx1,sp,sl);
+
+ if(i % 7)
+ MD5Update(&ctx1,pw,strlen(pw));
+
+ if(i & 1)
+ MD5Update(&ctx1,final,16);
+ else
+ MD5Update(&ctx1,pw,strlen(pw));
+ MD5Final(final,&ctx1);
+ }
+
+ p = passwd + strlen(passwd);
+
+ l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p,l,4); p += 4;
+ l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p,l,4); p += 4;
+ l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p,l,4); p += 4;
+ l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p,l,4); p += 4;
+ l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p,l,4); p += 4;
+ l = final[11] ; to64(p,l,2); p += 2;
+ *p = '\0';
+
+ /* Don't leave anything around in vm they could use. */
+ memset(final,0,sizeof final);
+
+ return passwd;
+}
+
+int main(void)
+{
+ char pass[256], salt[10], rand[8];
+ int fd = open("/dev/urandom", O_RDONLY);
+ int n;
+ if (fd < 0)
+ {
+ fprintf(stderr, "unable to open /dev/urandom: %m\n");
+ return 1;
+ }
+ while (fgets(pass, sizeof(pass), stdin))
+ {
+ char *c = strchr(pass, '\n');
+ if (c)
+ *c = 0;
+ if (read(fd, rand, sizeof(rand)) != sizeof(rand))
+ {
+ fprintf(stderr, "Error reading /dev/urandom: %m\n");
+ return 1;
+ }
+ for (n=0; n<2; n++)
+ to64(salt+4*n, *(uint32 *)(rand+4*n), 4);
+ salt[8] = 0;
+ printf("%s\n", libshadow_md5_crypt(pass, salt));
+ }
+ return 0;
+}
--- /dev/null
+#!/bin/sh
+if [ -z "$1" ] ; then
+ echo "Directory name expected"
+ exit 1
+fi
+rm -rf solutions/mo*
+for m in `cd $1 ; echo *` ; do
+ echo -n "$m:"
+ for d in $1/$m/mo??/mo?? ; do
+ u=`basename $d`
+ if [ $u != mo00 -a -d $d/.submit ] ; then
+ echo -n " $u"
+ if [ -d solutions/$u ] ; then
+ echo -n "<DUP!!!>"
+ else
+ cp -a $d/.submit solutions/$u
+ fi
+ fi
+ done
+ echo
+done
--- /dev/null
+#!/bin/sh
+if [ -z "$1" ] ; then
+ echo "Directory name expected"
+ exit 1
+fi
+for m in `cd $1 ; echo *` ; do
+ echo -n "$m:"
+ for d in $1/$m/mo??/mo?? ; do
+ u=`basename $d`
+ if [ $u != mo00 -a `ls $d | wc -l` -gt 0 ] ; then
+ echo -n " $u"
+ if [ -d $d/.submit ] ; then
+ echo -n '('
+ ( cd $d/.submit ; echo -n * )
+ echo -n ')'
+ fi
+ fi
+ done
+ echo
+done
--- /dev/null
+#!/bin/sh
+if [ -z "$1" ] ; then
+ D=back/`date '+%H%M'`
+else
+ D=$1
+fi
+mkdir -p $D
+for m in `seq 27 74` ; do
+ m="ceoi$m"
+ echo -n "$m: "
+ mkdir $p $D/$m
+ pushd $D/$m >/dev/null
+ ssh root@$m 'cd /mo/users ; tar czf - . --exclude=.kde' | tar xzf -
+ popd >/dev/null
+ du -s $D/$m | cut -f 1
+done
--- /dev/null
+#!/bin/bash
+
+[ -f config ] || { echo "Missing config file, check cwd." ; exit 1 ; }
+set -e
+. config
+
+H=`pwd`
+cd $MO_ROOT
+rm -rf users
+mkdir users
+cd users
+
+for a in `cd $H && bin/mo-get-users` ; do
+ echo "Creating $a"
+ mkdir $a $a/$a
+ chown root.$a $a
+ chmod 750 $a
+ cp -a `find $H/template -mindepth 1 -maxdepth 1` $a/$a/
+
+ if [ -n "$REMOTE_SUBMIT" ] ; then
+ M=$a/$a/.mo
+ mkdir $M
+ cp $H/certs/$a-cert.pem $M/cert.pem
+ cp $H/certs/$a-key.pem $M/key.pem
+ chmod 600 $M/key.pem
+ cp $H/certs/ca-cert.pem $M/
+ fi
+
+ chown $a.$a $a/$a -R
+ chmod 700 $a/$a
+done
--- /dev/null
+#!/bin/bash
+
+[ -f config ] || { echo "Missing config file, check cwd." ; exit 1 ; }
+set -e
+. config
+
+H=`pwd`
+cd $MO_ROOT/eval
+
+echo "Creating $EVAL_USER"
+rm -rf eval
+mkdir eval
+cd eval
+cp -a $H/* .
+chmod +x bin/*
+if [ -d ~/.ssh ] ; then echo "Copying SSH configuration from ~/.ssh" ; cp -a ~/.ssh . ; fi
+cd ..
+chown -R $EVAL_USER.$EVAL_GROUP eval
+chmod 750 eval
--- /dev/null
+#!/bin/bash
+
+[ -f config ] || { echo "Missing config file, check cwd." ; exit 1 ; }
+set -e
+. config
+
+mode=$1
+
+case "$mode" in
+ eval) uid=$EVAL_UID_MIN;;
+ users) uid=$CT_UID_MIN;;
+ *) echo "Usage: $0 [eval|users]!"; exit 1;;
+esac
+
+>>etcshadow >>etcpasswd >>etcgroup
+expire=$((`date +%s` / 86400 - 1))
+
+case $mode in
+ eval)
+ echo -n Enter password for evaluation users:
+ read passwd
+ passwd=`echo $passwd | bin/md5crypt`
+ gid=$uid
+ tgid=$(($gid+1))
+ rgid=$(($gid+2))
+ echo $EVAL_USER:x:$uid:$gid:MO Evaluator:$MO_ROOT/eval/eval:/bin/bash >> etcpasswd
+ echo $EVAL_USER:$passwd:$expire:0:99999:7::: >> etcshadow
+ echo $EVAL_GROUP:x:$gid: >> etcgroup
+ echo $TEST_GROUP:x:$tgid:$EVAL_USER >> etcgroup
+
+ if [ -n "$REMOTE_SUBMIT" ] ; then
+ uid=$(($uid + 1))
+ echo $REMOTE_SUBMIT_USER:x:$uid:$rgid:MO Submitter:$MO_ROOT/eval/submit:/bin/bash >> etcpasswd
+ echo $REMOTE_SUBMIT_USER:$passwd:$expire:0:99999:7::: >> etcshadow
+ echo $REMOTE_SUBMIT_GROUP:x:$rgid: >> etcgroup
+ fi
+
+ tuid=$(($uid + 1))
+ for tester in $TEST_USERS; do
+ echo $tester:x:$tuid:$tgid:MO Tester `expr $tuid - $uid`:$MO_ROOT/eval/$tester:/bin/bash >> etcpasswd
+ echo $tester:$passwd:$expire:0:99999:7::: >> etcshadow
+ tuid=$(($tuid + 1))
+ done
+ ;;
+
+ users)
+# if [ -f logins.tex ]; then echo "File logins.tex exists! Bailing out!"; exit 1; fi
+ cat > logins.tex <<- EOF
+ \\nopagenumbers
+ \\voffset=-1.5cm\\vsize=280mm\\hoffset=-0.75cm\\advance\\hsize by 3cm
+ \\raggedright\\parindent=0pt
+ \\font\\ftt=cstt17
+ \\font\\frm=csr17
+ \\font\\fit=csti17
+ \\ftt
+ \\def\\user#1#2#3{\\vbox to 4.5cm{\\hsize=6cm\\vss\\vss{\\fit Practice Session}\\vss\\vss{\\frm #3}\\vss\\vss#1\\vss#2\\vss\\vss}}
+ \\leavevmode
+ EOF
+
+ bin/mo-get-users --full | while read user name; do
+ passwd=`apg -n1 -m6 -Mncl | cut -d" " -f1 | tr l1O0 '@*?-' `
+ passwd_md5=`echo $passwd | bin/md5crypt`
+ echo $user:x:$uid:$uid:$name:$MO_ROOT/users/$user/$user:/bin/bash >> etcpasswd
+ echo $user:x:$uid: >> etcgroup
+ echo $user:$passwd_md5:`expr \`date +%s\` / 86400 - 1`:0:99999:7::: >> etcshadow
+ echo "\\user{$user}{$passwd}{$name}" >> logins.tex
+ uid=$(($uid + 1))
+ done
+
+ cat >> logins.tex <<- EOF
+ \\vfil
+ \\bye
+ EOF
+ ;;
+esac
--- /dev/null
+#!/bin/bash
+# Create contestant directories with their solutions and test logs
+
+[ -f config ] || { echo "Missing config file, check cwd." ; exit 1 ; }
+set -e
+. config
+
+H=`pwd`
+cd $MO_ROOT
+rm -rf users2
+mkdir users2
+cd users2
+
+for a in `cd $H && bin/mo-get-users` ; do
+ echo "Creating $a"
+ mkdir $a $a/$a
+ chown root.$a $a
+ chmod 750 $a
+ cp -a `find $H/template -type f -name ".*"` $a/$a/
+ if [ -d $H/solutions/$a ] ; then cp -a $H/solutions/$a $a/$a/solutions ; fi
+ if [ -d $H/testing/$a ] ; then cp -a $H/testing/$a $a/$a/testing ; fi
+ chown $a.$a $a/$a -R
+ chmod 700 $a/$a
+done
--- /dev/null
+#!/bin/bash
+
+[ -f config ] || { echo "Missing config file, check cwd." ; exit 1 ; }
+set -e
+. config
+
+echo "Populating $MO_ROOT/public"
+H=`pwd`
+cd $MO_ROOT/public
+rm -rf bin lib
+
+sed '/^\(TEST_USER\|MO_ROOT\)=/s/^/#/' <$H/config >config
+
+mkdir bin
+cp -a $H/public/[a-z]* bin/
+for a in `cat $H/public/COPY` ; do
+ cp -a $H/$a bin/
+done
+
+if [ -n "$REMOTE_SUBMIT" ] ; then
+ cp $H/submit/{contest,remote-submit,remote-status} bin/
+ mkdir lib
+ cp -a $H/submit/lib .
+fi
+
+mkdir -p problems
+
+if [ `id -u` == 0 ] ; then
+ chown -R $EVAL_USER.$EVAL_GROUP .
+ chmod 755 .
+fi
--- /dev/null
+#!/bin/bash
+
+[ -f config ] || { echo "Missing config file, check cwd." ; exit 1 ; }
+set -e
+. config
+[ -n "$REMOTE_SUBMIT" ] || { echo "Remote submit not enabled." ; exit 1 ; }
+
+echo "Creating submit directory"
+
+H=`pwd`
+cd $MO_ROOT/eval/submit
+mkdir -p certs
+cp $H/certs/server* certs/
+cp $H/certs/ca-cert.pem certs/
+
+rm -rf submit
+mkdir -p submit
+cp $H/submit/{submitd,config,show-submits} submit/
+
+mkdir -p solutions
+for a in `cd $H && bin/mo-get-users` ; do
+ mkdir -p solutions/$a
+done
+
+rm -rf lib
+cp -a $H/submit/lib lib
+
+rm -rf tmp
+mkdir -p tmp
+
+mkdir -p log history
+
+chown -R $REMOTE_SUBMIT_USER.$REMOTE_SUBMIT_GROUP $MO_ROOT/eval/submit
--- /dev/null
+#!/bin/bash
+
+[ -f config ] || { echo "Missing config file, check cwd." ; exit 1 ; }
+set -e
+. config
+
+H=`pwd`
+cd $MO_ROOT/eval
+
+# mo-test home
+for u in $TEST_USERS ; do
+ echo "Creating $u"
+ rm -rf ./$u
+ mkdir $u
+ chown $u.$TEST_GROUP $u
+ chmod 770 $u
+ cp $H/bin/box eval/bin/box-$u
+ chown $u.$EVAL_GROUP eval/bin/box-$u
+ chmod 4550 eval/bin/box-$u
+done
--- /dev/null
+#!/bin/bash
+
+[ -n "$1" ] || { echo "Usage: mo-grab-remote <tasks>" ; exit 1 ; }
+[ -f config ] || { echo "Missing config file, check cwd." ; exit 1 ; }
+set -e
+. config
+
+for user in `bin/mo-get-users` ; do
+ echo -n "$user:"
+ mkdir -p solutions/$user
+ for t in $@ ; do
+ rm -rf solutions/$user/$t
+ D=$MO_ROOT/eval/submit/solutions/$user/$t
+ if [ -d $D ] ; then
+ echo -n " $t"
+ cp -a $D solutions/$user/$t
+ fi
+ done
+ echo
+done
--- /dev/null
+#!/bin/bash
+
+[ -n "$1" ] || { echo "Usage: mo-grab <tasks>" ; exit 1 ; }
+[ -f config ] || { echo "Missing config file, check cwd." ; exit 1 ; }
+set -e
+. config
+
+for user in `bin/mo-get-users` ; do
+ echo -n "$user:"
+ H=`eval echo ~$user`/.submit
+ if [ -d $H ] ; then
+ [ -d solutions/$user ] || mkdir -p solutions/$user
+ for t in $@ ; do
+ rm -rf solutions/$user/$t
+ if [ -d $H/$t ] ; then
+ echo -n " $t"
+ cp -dr $H/$t solutions/$user/$t
+ fi
+ done
+ echo
+ else
+ echo " ---"
+ fi
+done
+chown -R $EVAL_USER solutions
+chmod -R a+r solutions
--- /dev/null
+#!/bin/bash
+
+[ -f config ] || { echo "Missing config file, check cwd." ; exit 1 ; }
+set -e
+. config
+
+H=`pwd`
+
+# The eval directory
+cd $MO_ROOT
+rm -rf eval
+mkdir eval
+chgrp $EVAL_GROUP eval
+chmod 755 eval
+cd eval
+
+# mo-eval home
+( cd $H && bin/mo-create-eval )
+
+# testusers
+( cd eval && bin/mo-create-testusers )
+
+# mo-submit home
+if [ -n "$REMOTE_SUBMIT" ] ; then
+ mkdir submit
+ chmod 750 submit
+ if [ -d ~/.ssh ] ; then echo "Copying SSH configuration from ~/.ssh" ; cp -a ~/.ssh submit/ ; fi
+ ( cd $H && bin/mo-create-submit )
+fi
+
+# create public
+cd $MO_ROOT
+echo "Creating public"
+rm -rf public
+mkdir public
+
+# populate public
+( cd eval/eval ; bin/mo-create-public )
--- /dev/null
+#!/bin/bash
+[ -f config ] || { echo "Missing config file, check cwd." ; exit 1 ; }
+set -e
+. config
+
+while IFS=" " read LOGIN FULL MACH ; do
+ if [ -z "$1" -o "$1" == "$LOGIN" ] ; then
+ echo "$LOGIN -> $MACH"
+ D=/mo/users/$LOGIN/$LOGIN/
+ rsync -av $D/.mo root@$MACH:$D/
+ fi </dev/null
+done <userlist
--- /dev/null
+#!/bin/bash
+set -e
+while IFS=" " read LOGIN FULL MACH ; do
+ if [ -z "$1" -o "$1" == "$LOGIN" ] ; then
+ echo "$LOGIN -> $MACH"
+ D=/mo/users/$LOGIN/$LOGIN/
+ rsync -av ~mo-eval/testing/$LOGIN root@$MACH:$D/results
+ ssh root@$MACH "cd $D && chown -R $LOGIN.$LOGIN results"
+ fi </dev/null
+done <userlist
--- /dev/null
+#!/bin/bash
+
+[ -n "$1" ] || { echo "Usage: mo-ev-all <tasks>" ; exit 1 ; }
+
+while [ -n "$1" ] ; do
+ for user in `bin/mo-get-users` ; do
+ echo -e "\n### USER $user TASK $1 ###\n"
+ bin/ev $user $1
+ done
+ shift
+done
--- /dev/null
+#!/bin/bash
+
+[ -n "$1" ] || { echo "Usage: mo-ev-inc [--force] <tasks>" ; exit 1 ; }
+
+force=0
+if [ "$1" == --force ] ; then
+ force=1
+ shift
+fi
+for user in `bin/mo-get-users` ; do
+ for task in "$@" ; do
+ echo -n "$user/$task: "
+ if [ -d solutions/$user/$task ] ; then
+ N=`cd solutions/$user/$task && cat * | md5sum | head -c16`
+ else
+ N=none
+ fi
+ if [ -f testing/$user/$task/sum ] ; then
+ O=`cat testing/$user/$task/sum`
+ else
+ O=none
+ fi
+ if [ $force == 1 -a $N != none ] ; then
+ O=forced
+ fi
+ echo -n "($O $N) "
+ if [ $O == $N ] ; then
+ echo OK
+ elif [ $N == none ] ; then
+ rm -rf testing/$user/$task
+ echo DELETED
+ else
+ echo CHANGED
+ bin/ev $user $task
+ echo $N >testing/$user/$task/sum
+ fi
+ done
+done
--- /dev/null
+#!/bin/bash
+
+if [ "$1" = --help ] ; then
+ echo "Usage: mo-get-users [--full]"
+fi
+[ -f config ] || { echo "Missing config file, check cwd." ; exit 1 ; }
+set -e
+. config
+
+if [ -z "$CT_USER_LIST" ] ; then
+ if [ "$1" = --full ] ; then
+ FORM='$1,$5'
+ else
+ FORM='$1'
+ fi
+ awk -F: </etc/passwd "{ gsub(\",.*\",\"\",\$5); OFS=\"\t\"; if (\$3 >= $CT_UID_MIN && \$3 <= $CT_UID_MAX) print $FORM; }"
+else
+ if [ "$1" = --full ] ; then
+ cut -d ' ' -f 1,2 <$CT_USER_LIST
+ else
+ cut -d ' ' -f 1 <$CT_USER_LIST
+ fi
+fi
--- /dev/null
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use POSIX;
+
+foreach my $user (`cd testing && ls`) {
+ chomp $user;
+ print "$user:";
+ open REP, ">testing/$user/REPORT" or die;
+ print REP "Evaluation report for CEOI 2007 Day 2\n\n";
+ my $total = 0;
+ foreach my $task (@ARGV) {
+ print REP "### Task $task ###\n\n";
+ if (open PTS, "testing/$user/$task/points") {
+ my %merged_pts = ();
+ my %split_comm = ();
+ while (<PTS>) {
+ chomp;
+ my ($test, $pts, $comm) = /(\S+)\s+(\S+)\s+(.*)/;
+ my $merged = $test;
+ $merged =~ s/[^0-9]//;
+ if (!defined($merged_pts{$merged}) || $merged_pts{$merged} > $pts) {
+ $merged_pts{$merged} = $pts;
+ }
+ $split_comm{$merged}{$test} = $comm;
+ }
+ close PTS;
+ my $tt = 0;
+ foreach my $merged (sort { $a <=> $b } keys %merged_pts) {
+ printf REP "Test %2s: %2d points", $merged, $merged_pts{$merged};
+ $tt += $merged_pts{$merged};
+ my @k = sort keys %{$split_comm{$merged}};
+ if (@k == 1) {
+ print REP " -- ", $split_comm{$merged}{$k[0]}, "\n";
+ } else {
+ print REP " -- ";
+ my $cc = 0;
+ foreach my $t (@k) {
+ $cc++ and print REP ", ";
+ print REP "$t: $split_comm{$merged}{$t}";
+ }
+ print REP "\n";
+ }
+ }
+ print REP "\nTOTAL: $tt points\n\n";
+ $total += $tt;
+ print " $tt";
+ } else {
+ print REP "No solution submitted.\n\n";
+ print " -";
+ }
+ }
+ print REP "### TOTAL FOR DAY 2 ###\n\n";
+ print REP "$total points\n";
+ print REP "\n\n(generated on ", strftime("%Y-%m-%d %H:%M:%S", localtime), ")\n";
+ close REP;
+ print " -> $total\n";
+}
--- /dev/null
+#!/usr/bin/perl
+
+$debug = 0;
+$detail = 0;
+$html = 0;
+$tex = 0;
+$extras = 0;
+$alt = 0;
+$merged = 0;
+$usage = "Usage: mo-score [--detail] [--alt] [--extras] [--html] [--tex] [--merged] [<directory>/]<task> ...";
+while (($arg = $ARGV[0]) =~ /^--([a-z]+)$/) {
+ shift @ARGV;
+ $var = "\$$1";
+ if (!eval "defined $var") { die $usage; }
+ eval "$var = 1;";
+}
+@ARGV || die $usage;
+
+print STDERR "Scanning contestants... ";
+open (CT, "bin/mo-get-users --full |") || die "Cannot get list of contestants";
+while (<CT>) {
+ chomp;
+ ($u,$f) = split /\t/;
+ ($u eq "somebody") && next;
+ $users{$u}=$f;
+}
+close CT;
+print STDERR 0+keys %users, "\n";
+
+print STDERR "Scanning exceptions... ";
+if ($extras && open (EX, "exceptions")) {
+ while (<EX>) {
+ chomp;
+ (/^$/ || /^#/) && next;
+ @a = split /\s+/;
+ $u = shift @a;
+ defined $users{$u} || die "Unknown user $u";
+ while (@a) { $extra{$u} += shift @a; }
+ }
+ close EX;
+ print STDERR "OK\n";
+} else { print STDERR "none\n"; }
+
+print STDERR "Scanning task results... ";
+%messages = ();
+%error_codes = ();
+foreach $u (keys %users) {
+ foreach $task (@ARGV) {
+ my ($dir, $t) = ("testing", $task);
+ if ($task =~ m@^(.*)/([^/]*)$@) {
+ $dir = $1;
+ $t = $2;
+ }
+ $known_tasks{$t} = 1;
+ $tt = "$dir/$u/$t/points" . ($alt ? ".alt" : "");
+ -f $tt || next;
+ print STDERR "$u/$t ";
+ open (X, $tt) || die "Unable to open $tt";
+ while (<X>) {
+ chomp;
+ /^(\S+) (-?\d+)\s*(.*)/ || die "Parse error: $_";
+ $ttest = $1;
+ $tpts = $2;
+ $trem = $3;
+ $trem =~ s/\[.*//;
+ ($ttest_merged = $ttest) =~ s/[^0-9]//g;
+ $ttest = $ttest_merged if $merged;
+ $known_tests{$t}{$ttest} = 1;
+ $cmt = $tpts;
+ if ($tpts == 0 && $trem ne "OK") {
+ if ($trem =~ /^Compile /) { $cmt = "CE"; }
+ elsif ($trem =~ /^Time limit exceeded/) { $cmt = "TO"; }
+ elsif ($trem =~ /^Exited with error /) { $cmt = "RE"; }
+ elsif ($trem =~ /^Caught fatal signal /) { $cmt = "SG"; }
+ elsif ($trem =~ /^([A-Za-z])\S*\s+([A-Za-z])/) {
+ ($cmt = "$1$2") =~ tr/a-z/A-Z/;
+ }
+ if (!defined $messages{$trem}) {
+ $messages{$trem} = $cmt;
+ if (!defined $error_codes{$cmt}) {
+ $error_codes{$cmt} = $trem;
+ } else {
+ $error_codes{$cmt} .= ", $trem";
+ }
+ }
+ }
+ if (!defined($results{$u}{$t}{$ttest}) || $results{$u}{$t}{$ttest} > $tpts) {
+ $results{$u}{$t}{$ttest} = $tpts;
+ $comment{$u}{$t}{$ttest} = $cmt;
+ }
+ if (!defined($results_merged{$u}{$t}{$ttest_merged}) || $results_merged{$u}{$t}{$ttest_merged} > $tpts) {
+ $results_merged{$u}{$t}{$ttest_merged} = $tpts;
+ }
+ }
+ close X;
+ }
+ foreach my $t (keys %known_tasks) {
+ $total{$u}{$t} = 0;
+ foreach my $pts (values %{$results_merged{$u}{$t}}) { $total{$u}{$t} += $pts; }
+ }
+}
+print STDERR "OK\n";
+
+print STDERR "Creating table template... ";
+@header = ("Rank","User","Name");
+@body = ('','$u','$users{$u}');
+@bodysums = ();
+@footer = ('"Total"','','');
+if (keys %extra) {
+ push @header, "Extra";
+ push @body, '$extra{$u}';
+ $col = 0+@footer;
+ push @bodysums, $col;
+ push @footer, "sum($col)";
+}
+@tasks = ();
+foreach $task (@ARGV) {
+ my $t = ($task =~ m@/([^/]*)$@) ? $1 : $task;
+ defined $known_tasks{$t} || die "Unknown task $t";
+ push @tasks, $t;
+ push @header, substr($t, 0, 4);
+ push @body, "(\$xx = \$total{\$u}{'$t'}) > 0 ? \$xx : 0";
+ $col = 0+@footer;
+ push @footer, "sum($col)";
+ push @bodysums, $col;
+ if ($detail) {
+ foreach $s (sort { $a <=> $b } keys %{$known_tests{$t}}) {
+ push @header, "$s";
+ push @body, "\$comment{\$u}{'$t'}{'$s'}";
+ $col = 0+@footer;
+ push @footer, "sum($col)";
+ }
+ }
+}
+push @header, "Total";
+push @body, join('+', map { $_ = "\$$_" } @bodysums);
+$col = 0+@footer;
+push @footer, "sum($col)";
+print STDERR "OK\n";
+
+print STDERR "h: ", join(':',@header), "\n" if $debug;
+print STDERR "b: ", join(':',@body), "\n" if $debug;
+print STDERR "f: ", join(':',@footer), "\n" if $debug;
+
+print STDERR "Filling in results... ";
+@table = ();
+foreach $u (keys %users) {
+ $row = [];
+ foreach my $c (@body) {
+ $c =~ s/\$(\d+)/\$\$row[$1]/g;
+ $x = eval $c;
+ push @$row, (defined $x ? $x : '-');
+ }
+ print STDERR "row: ", join(':',@$row), "\n" if $debug;
+ push @table, $row;
+}
+print STDERR "OK\n";
+
+print STDERR "Sorting... ";
+$sortcol = @{$table[0]} - 1;
+$namecol = 2;
+@table = sort {
+ my $p, $an, $bn;
+ $p = $$b[$sortcol] <=> $$a[$sortcol];
+ ($an = $$a[$namecol]) =~ s/(\S+)\s+(\S+)/$2 $1/;
+ ($bn = $$b[$namecol]) =~ s/(\S+)\s+(\S+)/$2 $1/;
+ $p ? $p : ($an cmp $bn);
+} @table;
+$i=0;
+while ($i < @table) {
+ $j = $i;
+ while ($i < @table && ${$table[$i]}[$sortcol] == ${$table[$j]}[$sortcol]) {
+ $i++;
+ }
+ if ($i == $j+1) {
+ ${table[$j]}[0] = "$i.";
+ } else {
+ ${table[$j]}[0] = $j+1 . ".-" . $i . ".";
+ $j++;
+ while ($j < $i) { ${table[$j++]}[0] = ""; };
+ }
+}
+print STDERR "OK\n";
+
+print STDERR "Attaching headers and footers... ";
+sub sum { my $col=shift @_; my $t=0; foreach my $z (0..@table-1) { $t += ${$table[$z]}[$col]; } $t; }
+map { $_ = eval $_; } @footer;
+push @table, \@footer;
+unshift @table, \@header;
+print STDERR "OK\n";
+
+if ($debug) {
+ foreach $r (@table) { print join(':',@$r), "\n"; }
+} elsif ($html) {
+ print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html40/strict.dtd">', "\n";
+ print "<HTML><HEAD><TITLE>Rank list</TITLE></HEAD><BODY>\n";
+ print "<H1>Rank list</H1>\n";
+
+ my @perm;
+ &printHtmlHeader(\@perm);
+ print "<tbody>";
+
+ foreach $r (@table[1..($#table - 1)]) {
+ &printHtmlRow(@{$r}[@perm]);
+ }
+
+ print "<tbody>";
+ &printHtmlRow(@{$table[$#table]}[@perm]);
+
+ print "</TABLE>\n";
+ if ($detail) {
+ print "<H2>Error codes</H2><UL>\n";
+ foreach $r (sort keys %error_codes) { print "<LI>$r: $error_codes{$r}\n"; }
+ print "</UL>\n";
+ }
+ print "</BODY></HTML>\n";
+} elsif ($tex) {
+ print "\\error{TeX output not supported yet!}\n";
+} else {
+ foreach $r (@table) { print join("\t",@$r), "\n"; }
+ print "\n";
+ foreach $r (sort keys %error_codes) { print "$r: $error_codes{$r}\n"; }
+}
+
+
+sub printHtmlRow {
+ print "<TR>", join('',map {
+ if ($hdr) { $_ = "<TH>$_"; }
+ else { $_ = "<TD align=" . (/^[0-9A-Z-]+$/ ? "right" : "left") . (length($_) > 14 ? " width=150" : "") . ">$_"; }
+ } @_), "\n";
+}
+
+
+sub printHtmlHeader {
+
+ my ($perm) = @_;
+
+ my $colspec = "<colgroup span=3>";
+ my $hdr1;
+ my $hdr2;
+
+ @$perm = (0, 1, 2);
+ my $p = 3;
+
+ if ($detail) {
+ $hdr1 = "<th rowspan=2>Rank<th rowspan=2>User<th rowspan=2>Name";
+ $extras and $p++ and push @$perm, 3 and $hdr1.="<th rowspan=2>Extra" and $colspec.="<colgroup span=1>"; ##Extra hack
+ for my $task (@tasks) {
+
+ my $nSub = scalar(keys %{$known_tests{$task}});
+
+ $p++;
+ map { push @$perm, $p++ } (1..$nSub);
+ push @$perm, $p - $nSub - 1;
+
+ $colspec .= "<colgroup span='" . $nSub . "'>\n";
+ $colspec .= "<colgroup span='1'>\n";
+ $hdr1 .= "<th colspan='" . ($nSub + 1) . "' style='border-bottom:1px solid black;'>$task";
+ $hdr2 .= join("", map { "<th>$_" } sort {$a <=> $b} keys %{$known_tests{$task}});
+ $hdr2 .= "<th>Total";
+ }
+
+ $hdr1 .= "<th rowspan='2'>Total";
+
+ } else { ## no detail
+
+ $hdr1 = "<th>Rank<th>User<th>Name";
+ $extras and $p++ and push @$perm, 3 and $hdr1.="<th>Extra" and $colspec.="<colgroup span=1>"; ##Extra hack
+
+ for my $task (@tasks) {
+ push @$perm, $p++;
+ $hdr1 .= "<th>$task";
+ }
+ $hdr1 .= "<th>Total";
+ $colspec .= "<colgroup span='" . scalar (@tasks) . "'>";
+ }
+
+ push @$perm, $p++;
+
+ print "<TABLE rules=groups frame=all border='1' cellpadding='2'>\n";
+ print "$colspec<colgroup span='1'>\n";
+ print "<tr>$hdr1</tr>\n";
+ print "<tr>$hdr2</tr>\n" if $detail;
+
+}
+++ /dev/null
-}}}
-
-\bye
+++ /dev/null
-\language=\czech
-\frenchspacing
-\font\head=csr12 scaled \magstephalf
-\font\hexx=csti12
-\font\xxit=csti10
-\def\xit{\xxit\kern-0.1em\relax}
-\let\hb=\relax
-\parindent=0pt
-\nopagenumbers
-
-\centerline{\head Výsledková listina ústøedního kola 56. roèníku MO kategorie P}
-\bigskip
-\centerline{\hexx 21. -- 24. bøezna 2007 ve Zlínì}
-\bigskip
-\bigskip
-
-\hrule
-\bigskip
-
-\centerline{\vbox{\halign{%
-#\hfil &~~#\hfil &\quad #\hfil &~~#\hfil&\quad
-\hfil # &
-\hfil # &
-\hfil # & \kern0.4em
-\hfil # &
-\hfil # & \kern1em
-\hb\quad\hfil # \cr
-\noalign{\bigskip\bigskip\hbox{\xit Vítìzové}\bigskip}
-%\noalign{\bigskip\bigskip\hbox{\xit Úspì¹ní øe¹itelé}\bigskip}
-%\noalign{\bigskip\bigskip\hbox{\xit Ostatní úèastníci}\bigskip}
+++ /dev/null
-/*
- * md5crypt based on lib/md5crypt.c from Linux shadow package.
- * adapted by Martin Mares <mj@ucw.cz> in June 2004
- * ----------------------------------------------------------------------------
- * "THE BEER-WARE LICENSE" (Revision 42):
- * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
- * ----------------------------------------------------------------------------
- */
-
-#include "lib/lib.h"
-#include "lib/md5.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */
- "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
-
-static void
-to64(char *s, unsigned int v, int n)
-{
- while (--n >= 0)
- {
- *s++ = itoa64[v&0x3f];
- v >>= 6;
- }
-}
-
-static char *
-libshadow_md5_crypt(const char *pw, const char *salt)
-{
- static char *magic = "$1$"; /*
- * This string is magic for
- * this algorithm. Having
- * it this way, we can get
- * get better later on
- */
- static char passwd[120], *p;
- static const char *sp,*ep;
- unsigned char final[16];
- int sl,pl,i,j;
- struct MD5Context ctx,ctx1;
- unsigned long l;
-
- /* Refine the Salt first */
- sp = salt;
-
- /* If it starts with the magic string, then skip that */
- if(!strncmp(sp,magic,strlen(magic)))
- sp += strlen(magic);
-
- /* It stops at the first '$', max 8 chars */
- for(ep=sp;*ep && *ep != '$' && ep < (sp+8);ep++)
- continue;
-
- /* get the length of the true salt */
- sl = ep - sp;
-
- MD5Init(&ctx);
-
- /* The password first, since that is what is most unknown */
- MD5Update(&ctx,pw,strlen(pw));
-
- /* Then our magic string */
- MD5Update(&ctx,magic,strlen(magic));
-
- /* Then the raw salt */
- MD5Update(&ctx,sp,sl);
-
- /* Then just as many characters of the MD5(pw,salt,pw) */
- MD5Init(&ctx1);
- MD5Update(&ctx1,pw,strlen(pw));
- MD5Update(&ctx1,sp,sl);
- MD5Update(&ctx1,pw,strlen(pw));
- MD5Final(final,&ctx1);
- for(pl = strlen(pw); pl > 0; pl -= 16)
- MD5Update(&ctx,final,pl>16 ? 16 : pl);
-
- /* Don't leave anything around in vm they could use. */
- memset(final,0,sizeof final);
-
- /* Then something really weird... */
- for (j=0,i = strlen(pw); i ; i >>= 1)
- if(i&1)
- MD5Update(&ctx, final+j, 1);
- else
- MD5Update(&ctx, pw+j, 1);
-
- /* Now make the output string */
- strcpy(passwd,magic);
- strncat(passwd,sp,sl);
- strcat(passwd,"$");
-
- MD5Final(final,&ctx);
-
- /*
- * and now, just to make sure things don't run too fast
- * On a 60 Mhz Pentium this takes 34 msec, so you would
- * need 30 seconds to build a 1000 entry dictionary...
- */
- for(i=0;i<1000;i++) {
- MD5Init(&ctx1);
- if(i & 1)
- MD5Update(&ctx1,pw,strlen(pw));
- else
- MD5Update(&ctx1,final,16);
-
- if(i % 3)
- MD5Update(&ctx1,sp,sl);
-
- if(i % 7)
- MD5Update(&ctx1,pw,strlen(pw));
-
- if(i & 1)
- MD5Update(&ctx1,final,16);
- else
- MD5Update(&ctx1,pw,strlen(pw));
- MD5Final(final,&ctx1);
- }
-
- p = passwd + strlen(passwd);
-
- l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p,l,4); p += 4;
- l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p,l,4); p += 4;
- l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p,l,4); p += 4;
- l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p,l,4); p += 4;
- l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p,l,4); p += 4;
- l = final[11] ; to64(p,l,2); p += 2;
- *p = '\0';
-
- /* Don't leave anything around in vm they could use. */
- memset(final,0,sizeof final);
-
- return passwd;
-}
-
-int main(void)
-{
- char pass[256], salt[10], rand[8];
- int fd = open("/dev/urandom", O_RDONLY);
- int n;
- if (fd < 0)
- {
- fprintf(stderr, "unable to open /dev/urandom: %m\n");
- return 1;
- }
- while (fgets(pass, sizeof(pass), stdin))
- {
- char *c = strchr(pass, '\n');
- if (c)
- *c = 0;
- if (read(fd, rand, sizeof(rand)) != sizeof(rand))
- {
- fprintf(stderr, "Error reading /dev/urandom: %m\n");
- return 1;
- }
- for (n=0; n<2; n++)
- to64(salt+4*n, *(uint32 *)(rand+4*n), 4);
- salt[8] = 0;
- printf("%s\n", libshadow_md5_crypt(pass, salt));
- }
- return 0;
-}
+++ /dev/null
-#!/bin/sh
-if [ -z "$1" ] ; then
- echo "Directory name expected"
- exit 1
-fi
-rm -rf solutions/mo*
-for m in `cd $1 ; echo *` ; do
- echo -n "$m:"
- for d in $1/$m/mo??/mo?? ; do
- u=`basename $d`
- if [ $u != mo00 -a -d $d/.submit ] ; then
- echo -n " $u"
- if [ -d solutions/$u ] ; then
- echo -n "<DUP!!!>"
- else
- cp -a $d/.submit solutions/$u
- fi
- fi
- done
- echo
-done
+++ /dev/null
-#!/bin/sh
-if [ -z "$1" ] ; then
- echo "Directory name expected"
- exit 1
-fi
-for m in `cd $1 ; echo *` ; do
- echo -n "$m:"
- for d in $1/$m/mo??/mo?? ; do
- u=`basename $d`
- if [ $u != mo00 -a `ls $d | wc -l` -gt 0 ] ; then
- echo -n " $u"
- if [ -d $d/.submit ] ; then
- echo -n '('
- ( cd $d/.submit ; echo -n * )
- echo -n ')'
- fi
- fi
- done
- echo
-done
+++ /dev/null
-#!/bin/sh
-if [ -z "$1" ] ; then
- D=back/`date '+%H%M'`
-else
- D=$1
-fi
-mkdir -p $D
-for m in `seq 27 74` ; do
- m="ceoi$m"
- echo -n "$m: "
- mkdir $p $D/$m
- pushd $D/$m >/dev/null
- ssh root@$m 'cd /mo/users ; tar czf - . --exclude=.kde' | tar xzf -
- popd >/dev/null
- du -s $D/$m | cut -f 1
-done
+++ /dev/null
-#!/bin/bash
-
-[ -f config ] || { echo "Missing config file, check cwd." ; exit 1 ; }
-set -e
-. config
-
-H=`pwd`
-cd $MO_ROOT
-rm -rf users
-mkdir users
-cd users
-
-for a in `cd $H && bin/mo-get-users` ; do
- echo "Creating $a"
- mkdir $a $a/$a
- chown root.$a $a
- chmod 750 $a
- cp -a `find $H/template -mindepth 1 -maxdepth 1` $a/$a/
-
- if [ -n "$REMOTE_SUBMIT" ] ; then
- M=$a/$a/.mo
- mkdir $M
- cp $H/certs/$a-cert.pem $M/cert.pem
- cp $H/certs/$a-key.pem $M/key.pem
- chmod 600 $M/key.pem
- cp $H/certs/ca-cert.pem $M/
- fi
-
- chown $a.$a $a/$a -R
- chmod 700 $a/$a
-done
+++ /dev/null
-#!/bin/bash
-
-[ -f config ] || { echo "Missing config file, check cwd." ; exit 1 ; }
-set -e
-. config
-
-H=`pwd`
-cd $MO_ROOT/eval
-
-echo "Creating $EVAL_USER"
-rm -rf eval
-mkdir eval
-cd eval
-cp -a $H/* .
-chmod +x bin/*
-if [ -d ~/.ssh ] ; then echo "Copying SSH configuration from ~/.ssh" ; cp -a ~/.ssh . ; fi
-cd ..
-chown -R $EVAL_USER.$EVAL_GROUP eval
-chmod 750 eval
+++ /dev/null
-#!/bin/bash
-
-[ -f config ] || { echo "Missing config file, check cwd." ; exit 1 ; }
-set -e
-. config
-
-mode=$1
-
-case "$mode" in
- eval) uid=$EVAL_UID_MIN;;
- users) uid=$CT_UID_MIN;;
- *) echo "Usage: $0 [eval|users]!"; exit 1;;
-esac
-
->>etcshadow >>etcpasswd >>etcgroup
-expire=$((`date +%s` / 86400 - 1))
-
-case $mode in
- eval)
- echo -n Enter password for evaluation users:
- read passwd
- passwd=`echo $passwd | bin/md5crypt`
- gid=$uid
- tgid=$(($gid+1))
- rgid=$(($gid+2))
- echo $EVAL_USER:x:$uid:$gid:MO Evaluator:$MO_ROOT/eval/eval:/bin/bash >> etcpasswd
- echo $EVAL_USER:$passwd:$expire:0:99999:7::: >> etcshadow
- echo $EVAL_GROUP:x:$gid: >> etcgroup
- echo $TEST_GROUP:x:$tgid:$EVAL_USER >> etcgroup
-
- if [ -n "$REMOTE_SUBMIT" ] ; then
- uid=$(($uid + 1))
- echo $REMOTE_SUBMIT_USER:x:$uid:$rgid:MO Submitter:$MO_ROOT/eval/submit:/bin/bash >> etcpasswd
- echo $REMOTE_SUBMIT_USER:$passwd:$expire:0:99999:7::: >> etcshadow
- echo $REMOTE_SUBMIT_GROUP:x:$rgid: >> etcgroup
- fi
-
- tuid=$(($uid + 1))
- for tester in $TEST_USERS; do
- echo $tester:x:$tuid:$tgid:MO Tester `expr $tuid - $uid`:$MO_ROOT/eval/$tester:/bin/bash >> etcpasswd
- echo $tester:$passwd:$expire:0:99999:7::: >> etcshadow
- tuid=$(($tuid + 1))
- done
- ;;
-
- users)
-# if [ -f logins.tex ]; then echo "File logins.tex exists! Bailing out!"; exit 1; fi
- cat > logins.tex <<- EOF
- \\nopagenumbers
- \\voffset=-1.5cm\\vsize=280mm\\hoffset=-0.75cm\\advance\\hsize by 3cm
- \\raggedright\\parindent=0pt
- \\font\\ftt=cstt17
- \\font\\frm=csr17
- \\font\\fit=csti17
- \\ftt
- \\def\\user#1#2#3{\\vbox to 4.5cm{\\hsize=6cm\\vss\\vss{\\fit Practice Session}\\vss\\vss{\\frm #3}\\vss\\vss#1\\vss#2\\vss\\vss}}
- \\leavevmode
- EOF
-
- bin/mo-get-users --full | while read user name; do
- passwd=`apg -n1 -m6 -Mncl | cut -d" " -f1 | tr l1O0 '@*?-' `
- passwd_md5=`echo $passwd | bin/md5crypt`
- echo $user:x:$uid:$uid:$name:$MO_ROOT/users/$user/$user:/bin/bash >> etcpasswd
- echo $user:x:$uid: >> etcgroup
- echo $user:$passwd_md5:`expr \`date +%s\` / 86400 - 1`:0:99999:7::: >> etcshadow
- echo "\\user{$user}{$passwd}{$name}" >> logins.tex
- uid=$(($uid + 1))
- done
-
- cat >> logins.tex <<- EOF
- \\vfil
- \\bye
- EOF
- ;;
-esac
+++ /dev/null
-#!/bin/bash
-# Create contestant directories with their solutions and test logs
-
-[ -f config ] || { echo "Missing config file, check cwd." ; exit 1 ; }
-set -e
-. config
-
-H=`pwd`
-cd $MO_ROOT
-rm -rf users2
-mkdir users2
-cd users2
-
-for a in `cd $H && bin/mo-get-users` ; do
- echo "Creating $a"
- mkdir $a $a/$a
- chown root.$a $a
- chmod 750 $a
- cp -a `find $H/template -type f -name ".*"` $a/$a/
- if [ -d $H/solutions/$a ] ; then cp -a $H/solutions/$a $a/$a/solutions ; fi
- if [ -d $H/testing/$a ] ; then cp -a $H/testing/$a $a/$a/testing ; fi
- chown $a.$a $a/$a -R
- chmod 700 $a/$a
-done
+++ /dev/null
-#!/bin/bash
-
-[ -f config ] || { echo "Missing config file, check cwd." ; exit 1 ; }
-set -e
-. config
-
-echo "Populating $MO_ROOT/public"
-H=`pwd`
-cd $MO_ROOT/public
-rm -rf bin lib
-
-sed '/^\(TEST_USER\|MO_ROOT\)=/s/^/#/' <$H/config >config
-
-mkdir bin
-cp -a $H/public/[a-z]* bin/
-for a in `cat $H/public/COPY` ; do
- cp -a $H/$a bin/
-done
-
-if [ -n "$REMOTE_SUBMIT" ] ; then
- cp $H/submit/{contest,remote-submit,remote-status} bin/
- mkdir lib
- cp -a $H/submit/lib .
-fi
-
-mkdir -p problems
-
-if [ `id -u` == 0 ] ; then
- chown -R $EVAL_USER.$EVAL_GROUP .
- chmod 755 .
-fi
+++ /dev/null
-#!/bin/bash
-
-[ -f config ] || { echo "Missing config file, check cwd." ; exit 1 ; }
-set -e
-. config
-[ -n "$REMOTE_SUBMIT" ] || { echo "Remote submit not enabled." ; exit 1 ; }
-
-echo "Creating submit directory"
-
-H=`pwd`
-cd $MO_ROOT/eval/submit
-mkdir -p certs
-cp $H/certs/server* certs/
-cp $H/certs/ca-cert.pem certs/
-
-rm -rf submit
-mkdir -p submit
-cp $H/submit/{submitd,config,show-submits} submit/
-
-mkdir -p solutions
-for a in `cd $H && bin/mo-get-users` ; do
- mkdir -p solutions/$a
-done
-
-rm -rf lib
-cp -a $H/submit/lib lib
-
-rm -rf tmp
-mkdir -p tmp
-
-mkdir -p log history
-
-chown -R $REMOTE_SUBMIT_USER.$REMOTE_SUBMIT_GROUP $MO_ROOT/eval/submit
+++ /dev/null
-#!/bin/bash
-
-[ -f config ] || { echo "Missing config file, check cwd." ; exit 1 ; }
-set -e
-. config
-
-H=`pwd`
-cd $MO_ROOT/eval
-
-# mo-test home
-for u in $TEST_USERS ; do
- echo "Creating $u"
- rm -rf ./$u
- mkdir $u
- chown $u.$TEST_GROUP $u
- chmod 770 $u
- cp $H/bin/box eval/bin/box-$u
- chown $u.$EVAL_GROUP eval/bin/box-$u
- chmod 4550 eval/bin/box-$u
-done
+++ /dev/null
-#!/bin/bash
-
-[ -n "$1" ] || { echo "Usage: mo-ev-all <tasks>" ; exit 1 ; }
-
-while [ -n "$1" ] ; do
- for user in `bin/mo-get-users` ; do
- echo -e "\n### USER $user TASK $1 ###\n"
- bin/ev $user $1
- done
- shift
-done
+++ /dev/null
-#!/bin/bash
-
-[ -n "$1" ] || { echo "Usage: mo-ev-inc [--force] <tasks>" ; exit 1 ; }
-
-force=0
-if [ "$1" == --force ] ; then
- force=1
- shift
-fi
-for user in `bin/mo-get-users` ; do
- for task in "$@" ; do
- echo -n "$user/$task: "
- if [ -d solutions/$user/$task ] ; then
- N=`cd solutions/$user/$task && cat * | md5sum | head -c16`
- else
- N=none
- fi
- if [ -f testing/$user/$task/sum ] ; then
- O=`cat testing/$user/$task/sum`
- else
- O=none
- fi
- if [ $force == 1 -a $N != none ] ; then
- O=forced
- fi
- echo -n "($O $N) "
- if [ $O == $N ] ; then
- echo OK
- elif [ $N == none ] ; then
- rm -rf testing/$user/$task
- echo DELETED
- else
- echo CHANGED
- bin/ev $user $task
- echo $N >testing/$user/$task/sum
- fi
- done
-done
+++ /dev/null
-#!/bin/bash
-
-if [ "$1" = --help ] ; then
- echo "Usage: mo-get-users [--full]"
-fi
-[ -f config ] || { echo "Missing config file, check cwd." ; exit 1 ; }
-set -e
-. config
-
-if [ -z "$CT_USER_LIST" ] ; then
- if [ "$1" = --full ] ; then
- FORM='$1,$5'
- else
- FORM='$1'
- fi
- awk -F: </etc/passwd "{ gsub(\",.*\",\"\",\$5); OFS=\"\t\"; if (\$3 >= $CT_UID_MIN && \$3 <= $CT_UID_MAX) print $FORM; }"
-else
- if [ "$1" = --full ] ; then
- cut -d ' ' -f 1,2 <$CT_USER_LIST
- else
- cut -d ' ' -f 1 <$CT_USER_LIST
- fi
-fi
+++ /dev/null
-#!/bin/bash
-
-[ -n "$1" ] || { echo "Usage: mo-grab <tasks>" ; exit 1 ; }
-[ -f config ] || { echo "Missing config file, check cwd." ; exit 1 ; }
-set -e
-. config
-
-for user in `bin/mo-get-users` ; do
- echo -n "$user:"
- H=`eval echo ~$user`/.submit
- if [ -d $H ] ; then
- [ -d solutions/$user ] || mkdir -p solutions/$user
- for t in $@ ; do
- rm -rf solutions/$user/$t
- if [ -d $H/$t ] ; then
- echo -n " $t"
- cp -dr $H/$t solutions/$user/$t
- fi
- done
- echo
- else
- echo " ---"
- fi
-done
-chown -R $EVAL_USER solutions
-chmod -R a+r solutions
+++ /dev/null
-#!/bin/bash
-
-[ -n "$1" ] || { echo "Usage: mo-grab-remote <tasks>" ; exit 1 ; }
-[ -f config ] || { echo "Missing config file, check cwd." ; exit 1 ; }
-set -e
-. config
-
-for user in `bin/mo-get-users` ; do
- echo -n "$user:"
- mkdir -p solutions/$user
- for t in $@ ; do
- rm -rf solutions/$user/$t
- D=$MO_ROOT/eval/submit/solutions/$user/$t
- if [ -d $D ] ; then
- echo -n " $t"
- cp -a $D solutions/$user/$t
- fi
- done
- echo
-done
+++ /dev/null
-#!/bin/bash
-
-[ -f config ] || { echo "Missing config file, check cwd." ; exit 1 ; }
-set -e
-. config
-
-H=`pwd`
-
-# The eval directory
-cd $MO_ROOT
-rm -rf eval
-mkdir eval
-chgrp $EVAL_GROUP eval
-chmod 755 eval
-cd eval
-
-# mo-eval home
-( cd $H && bin/mo-create-eval )
-
-# testusers
-( cd eval && bin/mo-create-testusers )
-
-# mo-submit home
-if [ -n "$REMOTE_SUBMIT" ] ; then
- mkdir submit
- chmod 750 submit
- if [ -d ~/.ssh ] ; then echo "Copying SSH configuration from ~/.ssh" ; cp -a ~/.ssh submit/ ; fi
- ( cd $H && bin/mo-create-submit )
-fi
-
-# create public
-cd $MO_ROOT
-echo "Creating public"
-rm -rf public
-mkdir public
-
-# populate public
-( cd eval/eval ; bin/mo-create-public )
+++ /dev/null
-#!/bin/bash
-[ -f config ] || { echo "Missing config file, check cwd." ; exit 1 ; }
-set -e
-. config
-
-while IFS=" " read LOGIN FULL MACH ; do
- if [ -z "$1" -o "$1" == "$LOGIN" ] ; then
- echo "$LOGIN -> $MACH"
- D=/mo/users/$LOGIN/$LOGIN/
- rsync -av $D/.mo root@$MACH:$D/
- fi </dev/null
-done <userlist
+++ /dev/null
-#!/bin/bash
-set -e
-while IFS=" " read LOGIN FULL MACH ; do
- if [ -z "$1" -o "$1" == "$LOGIN" ] ; then
- echo "$LOGIN -> $MACH"
- D=/mo/users/$LOGIN/$LOGIN/
- rsync -av ~mo-eval/testing/$LOGIN root@$MACH:$D/results
- ssh root@$MACH "cd $D && chown -R $LOGIN.$LOGIN results"
- fi </dev/null
-done <userlist
+++ /dev/null
-#!/usr/bin/perl
-
-use strict;
-use warnings;
-use POSIX;
-
-foreach my $user (`cd testing && ls`) {
- chomp $user;
- print "$user:";
- open REP, ">testing/$user/REPORT" or die;
- print REP "Evaluation report for CEOI 2007 Day 2\n\n";
- my $total = 0;
- foreach my $task (@ARGV) {
- print REP "### Task $task ###\n\n";
- if (open PTS, "testing/$user/$task/points") {
- my %merged_pts = ();
- my %split_comm = ();
- while (<PTS>) {
- chomp;
- my ($test, $pts, $comm) = /(\S+)\s+(\S+)\s+(.*)/;
- my $merged = $test;
- $merged =~ s/[^0-9]//;
- if (!defined($merged_pts{$merged}) || $merged_pts{$merged} > $pts) {
- $merged_pts{$merged} = $pts;
- }
- $split_comm{$merged}{$test} = $comm;
- }
- close PTS;
- my $tt = 0;
- foreach my $merged (sort { $a <=> $b } keys %merged_pts) {
- printf REP "Test %2s: %2d points", $merged, $merged_pts{$merged};
- $tt += $merged_pts{$merged};
- my @k = sort keys %{$split_comm{$merged}};
- if (@k == 1) {
- print REP " -- ", $split_comm{$merged}{$k[0]}, "\n";
- } else {
- print REP " -- ";
- my $cc = 0;
- foreach my $t (@k) {
- $cc++ and print REP ", ";
- print REP "$t: $split_comm{$merged}{$t}";
- }
- print REP "\n";
- }
- }
- print REP "\nTOTAL: $tt points\n\n";
- $total += $tt;
- print " $tt";
- } else {
- print REP "No solution submitted.\n\n";
- print " -";
- }
- }
- print REP "### TOTAL FOR DAY 2 ###\n\n";
- print REP "$total points\n";
- print REP "\n\n(generated on ", strftime("%Y-%m-%d %H:%M:%S", localtime), ")\n";
- close REP;
- print " -> $total\n";
-}
+++ /dev/null
-#!/usr/bin/perl
-
-$debug = 0;
-$detail = 0;
-$html = 0;
-$tex = 0;
-$extras = 0;
-$alt = 0;
-$merged = 0;
-$usage = "Usage: mo-score [--detail] [--alt] [--extras] [--html] [--tex] [--merged] [<directory>/]<task> ...";
-while (($arg = $ARGV[0]) =~ /^--([a-z]+)$/) {
- shift @ARGV;
- $var = "\$$1";
- if (!eval "defined $var") { die $usage; }
- eval "$var = 1;";
-}
-@ARGV || die $usage;
-
-print STDERR "Scanning contestants... ";
-open (CT, "bin/mo-get-users --full |") || die "Cannot get list of contestants";
-while (<CT>) {
- chomp;
- ($u,$f) = split /\t/;
- ($u eq "somebody") && next;
- $users{$u}=$f;
-}
-close CT;
-print STDERR 0+keys %users, "\n";
-
-print STDERR "Scanning exceptions... ";
-if ($extras && open (EX, "exceptions")) {
- while (<EX>) {
- chomp;
- (/^$/ || /^#/) && next;
- @a = split /\s+/;
- $u = shift @a;
- defined $users{$u} || die "Unknown user $u";
- while (@a) { $extra{$u} += shift @a; }
- }
- close EX;
- print STDERR "OK\n";
-} else { print STDERR "none\n"; }
-
-print STDERR "Scanning task results... ";
-%messages = ();
-%error_codes = ();
-foreach $u (keys %users) {
- foreach $task (@ARGV) {
- my ($dir, $t) = ("testing", $task);
- if ($task =~ m@^(.*)/([^/]*)$@) {
- $dir = $1;
- $t = $2;
- }
- $known_tasks{$t} = 1;
- $tt = "$dir/$u/$t/points" . ($alt ? ".alt" : "");
- -f $tt || next;
- print STDERR "$u/$t ";
- open (X, $tt) || die "Unable to open $tt";
- while (<X>) {
- chomp;
- /^(\S+) (-?\d+)\s*(.*)/ || die "Parse error: $_";
- $ttest = $1;
- $tpts = $2;
- $trem = $3;
- $trem =~ s/\[.*//;
- ($ttest_merged = $ttest) =~ s/[^0-9]//g;
- $ttest = $ttest_merged if $merged;
- $known_tests{$t}{$ttest} = 1;
- $cmt = $tpts;
- if ($tpts == 0 && $trem ne "OK") {
- if ($trem =~ /^Compile /) { $cmt = "CE"; }
- elsif ($trem =~ /^Time limit exceeded/) { $cmt = "TO"; }
- elsif ($trem =~ /^Exited with error /) { $cmt = "RE"; }
- elsif ($trem =~ /^Caught fatal signal /) { $cmt = "SG"; }
- elsif ($trem =~ /^([A-Za-z])\S*\s+([A-Za-z])/) {
- ($cmt = "$1$2") =~ tr/a-z/A-Z/;
- }
- if (!defined $messages{$trem}) {
- $messages{$trem} = $cmt;
- if (!defined $error_codes{$cmt}) {
- $error_codes{$cmt} = $trem;
- } else {
- $error_codes{$cmt} .= ", $trem";
- }
- }
- }
- if (!defined($results{$u}{$t}{$ttest}) || $results{$u}{$t}{$ttest} > $tpts) {
- $results{$u}{$t}{$ttest} = $tpts;
- $comment{$u}{$t}{$ttest} = $cmt;
- }
- if (!defined($results_merged{$u}{$t}{$ttest_merged}) || $results_merged{$u}{$t}{$ttest_merged} > $tpts) {
- $results_merged{$u}{$t}{$ttest_merged} = $tpts;
- }
- }
- close X;
- }
- foreach my $t (keys %known_tasks) {
- $total{$u}{$t} = 0;
- foreach my $pts (values %{$results_merged{$u}{$t}}) { $total{$u}{$t} += $pts; }
- }
-}
-print STDERR "OK\n";
-
-print STDERR "Creating table template... ";
-@header = ("Rank","User","Name");
-@body = ('','$u','$users{$u}');
-@bodysums = ();
-@footer = ('"Total"','','');
-if (keys %extra) {
- push @header, "Extra";
- push @body, '$extra{$u}';
- $col = 0+@footer;
- push @bodysums, $col;
- push @footer, "sum($col)";
-}
-@tasks = ();
-foreach $task (@ARGV) {
- my $t = ($task =~ m@/([^/]*)$@) ? $1 : $task;
- defined $known_tasks{$t} || die "Unknown task $t";
- push @tasks, $t;
- push @header, substr($t, 0, 4);
- push @body, "(\$xx = \$total{\$u}{'$t'}) > 0 ? \$xx : 0";
- $col = 0+@footer;
- push @footer, "sum($col)";
- push @bodysums, $col;
- if ($detail) {
- foreach $s (sort { $a <=> $b } keys %{$known_tests{$t}}) {
- push @header, "$s";
- push @body, "\$comment{\$u}{'$t'}{'$s'}";
- $col = 0+@footer;
- push @footer, "sum($col)";
- }
- }
-}
-push @header, "Total";
-push @body, join('+', map { $_ = "\$$_" } @bodysums);
-$col = 0+@footer;
-push @footer, "sum($col)";
-print STDERR "OK\n";
-
-print STDERR "h: ", join(':',@header), "\n" if $debug;
-print STDERR "b: ", join(':',@body), "\n" if $debug;
-print STDERR "f: ", join(':',@footer), "\n" if $debug;
-
-print STDERR "Filling in results... ";
-@table = ();
-foreach $u (keys %users) {
- $row = [];
- foreach my $c (@body) {
- $c =~ s/\$(\d+)/\$\$row[$1]/g;
- $x = eval $c;
- push @$row, (defined $x ? $x : '-');
- }
- print STDERR "row: ", join(':',@$row), "\n" if $debug;
- push @table, $row;
-}
-print STDERR "OK\n";
-
-print STDERR "Sorting... ";
-$sortcol = @{$table[0]} - 1;
-$namecol = 2;
-@table = sort {
- my $p, $an, $bn;
- $p = $$b[$sortcol] <=> $$a[$sortcol];
- ($an = $$a[$namecol]) =~ s/(\S+)\s+(\S+)/$2 $1/;
- ($bn = $$b[$namecol]) =~ s/(\S+)\s+(\S+)/$2 $1/;
- $p ? $p : ($an cmp $bn);
-} @table;
-$i=0;
-while ($i < @table) {
- $j = $i;
- while ($i < @table && ${$table[$i]}[$sortcol] == ${$table[$j]}[$sortcol]) {
- $i++;
- }
- if ($i == $j+1) {
- ${table[$j]}[0] = "$i.";
- } else {
- ${table[$j]}[0] = $j+1 . ".-" . $i . ".";
- $j++;
- while ($j < $i) { ${table[$j++]}[0] = ""; };
- }
-}
-print STDERR "OK\n";
-
-print STDERR "Attaching headers and footers... ";
-sub sum { my $col=shift @_; my $t=0; foreach my $z (0..@table-1) { $t += ${$table[$z]}[$col]; } $t; }
-map { $_ = eval $_; } @footer;
-push @table, \@footer;
-unshift @table, \@header;
-print STDERR "OK\n";
-
-if ($debug) {
- foreach $r (@table) { print join(':',@$r), "\n"; }
-} elsif ($html) {
- print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html40/strict.dtd">', "\n";
- print "<HTML><HEAD><TITLE>Rank list</TITLE></HEAD><BODY>\n";
- print "<H1>Rank list</H1>\n";
-
- my @perm;
- &printHtmlHeader(\@perm);
- print "<tbody>";
-
- foreach $r (@table[1..($#table - 1)]) {
- &printHtmlRow(@{$r}[@perm]);
- }
-
- print "<tbody>";
- &printHtmlRow(@{$table[$#table]}[@perm]);
-
- print "</TABLE>\n";
- if ($detail) {
- print "<H2>Error codes</H2><UL>\n";
- foreach $r (sort keys %error_codes) { print "<LI>$r: $error_codes{$r}\n"; }
- print "</UL>\n";
- }
- print "</BODY></HTML>\n";
-} elsif ($tex) {
- print "\\error{TeX output not supported yet!}\n";
-} else {
- foreach $r (@table) { print join("\t",@$r), "\n"; }
- print "\n";
- foreach $r (sort keys %error_codes) { print "$r: $error_codes{$r}\n"; }
-}
-
-
-sub printHtmlRow {
- print "<TR>", join('',map {
- if ($hdr) { $_ = "<TH>$_"; }
- else { $_ = "<TD align=" . (/^[0-9A-Z-]+$/ ? "right" : "left") . (length($_) > 14 ? " width=150" : "") . ">$_"; }
- } @_), "\n";
-}
-
-
-sub printHtmlHeader {
-
- my ($perm) = @_;
-
- my $colspec = "<colgroup span=3>";
- my $hdr1;
- my $hdr2;
-
- @$perm = (0, 1, 2);
- my $p = 3;
-
- if ($detail) {
- $hdr1 = "<th rowspan=2>Rank<th rowspan=2>User<th rowspan=2>Name";
- $extras and $p++ and push @$perm, 3 and $hdr1.="<th rowspan=2>Extra" and $colspec.="<colgroup span=1>"; ##Extra hack
- for my $task (@tasks) {
-
- my $nSub = scalar(keys %{$known_tests{$task}});
-
- $p++;
- map { push @$perm, $p++ } (1..$nSub);
- push @$perm, $p - $nSub - 1;
-
- $colspec .= "<colgroup span='" . $nSub . "'>\n";
- $colspec .= "<colgroup span='1'>\n";
- $hdr1 .= "<th colspan='" . ($nSub + 1) . "' style='border-bottom:1px solid black;'>$task";
- $hdr2 .= join("", map { "<th>$_" } sort {$a <=> $b} keys %{$known_tests{$task}});
- $hdr2 .= "<th>Total";
- }
-
- $hdr1 .= "<th rowspan='2'>Total";
-
- } else { ## no detail
-
- $hdr1 = "<th>Rank<th>User<th>Name";
- $extras and $p++ and push @$perm, 3 and $hdr1.="<th>Extra" and $colspec.="<colgroup span=1>"; ##Extra hack
-
- for my $task (@tasks) {
- push @$perm, $p++;
- $hdr1 .= "<th>$task";
- }
- $hdr1 .= "<th>Total";
- $colspec .= "<colgroup span='" . scalar (@tasks) . "'>";
- }
-
- push @$perm, $p++;
-
- print "<TABLE rules=groups frame=all border='1' cellpadding='2'>\n";
- print "$colspec<colgroup span='1'>\n";
- print "<tr>$hdr1</tr>\n";
- print "<tr>$hdr2</tr>\n" if $detail;
-
-}
+++ /dev/null
-#!/usr/bin/perl
-
-$tex = 0;
-$usage = "Usage: mo-score-mop [--tex] theoretical_tasks_nr praxis_tasks_nr task1 task2 ...";
-while (($arg = $ARGV[0]) =~ /^--([a-z]+)$/) {
- shift @ARGV;
- $var = "\$$1";
- if (!eval "defined $var") { die $usage; }
- eval "$var = 1;";
-}
-@ARGV >=2 || die $usage;
-$theory=shift @ARGV;
-$praxis=shift @ARGV;
-@ARGV >= $praxis || die $usage;
-$pos_delim=$tex ? '--' : '-';
-
-print STDERR "Scanning contestants... ";
-open (CT, "bin/mo-get-users --full |") || die "Cannot get list of contestants";
-while (<CT>) {
- chomp;
- ($u,$f) = split /\t/;
- ($u eq "somebody") && next;
- $users{$u}=$f;
-}
-close CT;
-print STDERR 0+keys %users, "\n";
-
-print STDERR "Scanning teoretical results... ";
-if (open (EX, "mop/teorie.txt")) {
- while (<EX>) {
- chomp;
- (/^$/ || /^#/) && next;
- @a = split /\ *\t\ */;
- $u = shift @a;
- defined $users{$u} || die "Unknown user $u";
- $names{$u} = shift @a;
- $forms{$u} = shift @a;
- $addresses{$u} = "{". (shift @a) ."}";
- $i=0;
- while (@a) { $tasks{$u}{$i} = shift @a;$i++; }
- }
- close EX;
- print STDERR "OK\n";
-} else {die "none, cannot find file mop/teorie.txt!\n";}
-
-print STDERR "Scanning task results... ";
-$need_tasks = join("|", @ARGV);
-foreach $u (keys %users) {
- opendir (D, "testing/$u") or next;
- foreach $t (readdir(D)) {
- $t =~ /^\./ && next;
- $t =~ /$need_tasks/ || next;
-
- $t_num=$praxis;
- for (my $t_num2=0;$t_num2<@ARGV;$t_num2++) {if ($t eq $ARGV[$t_num2]) {$t_num=$t_num2;}}
- $t_num+=$theory;
-
- $tt = "testing/$u/$t/points";
- -f $tt || next;
- print STDERR "$u/$t ";
- open (X, $tt) || die "Unable to open $tt";
- while (<X>) {
- chomp;
- /^\S+ (-?\d+)/ || die "Parse error: $_";
- $tasks{$u}{$t_num} += $1;
- }
- close X;
- }
- closedir D;
-}
-print STDERR "OK\n";
-
-print STDERR "Creating table template... ";
-@body = ('','$names{$u}','$forms{$u}','$addresses{$u}');
-for ($a=0;$a<$theory+$praxis;$a++) {push @body,"\$tasks{\$u}{$a}";}
-print STDERR "OK\n";
-
-print STDERR "Filling in results... ";
-@table = ();
-foreach $u (keys %users) {
- next unless defined $names{$u}; # don't show any user not defined in teorie.txt
- $row = [];
- $row_index=0;
- $row_sum=0;
- foreach my $c (@body) {
- $c =~ s/\$(\d+)/\$\$row[$1]/g;
- $x = eval $c;
- push @$row, (defined $x ? $x : '-');
- if ($row_index>3) {
- if ((defined $x) && ($x>0)) {$row_sum+=$x;}
- }
- $row_index++;
- }
- push @$row, $row_sum;
- push @table, $row;
-}
-print STDERR "OK\n";
-
-print STDERR "Sorting... ";
-$sortcol = @{$table[0]} - 1;
-$namecol = 1;
-@table = sort {
- my $p, $an, $bn;
- $p = $$b[$sortcol] <=> $$a[$sortcol];
- ($an = $$a[$namecol]) =~ s/(\S+)\s+(\S+)/$2 $1/;
- ($bn = $$b[$namecol]) =~ s/(\S+)\s+(\S+)/$2 $1/;
- $p ? $p : ($an cmp $bn);
-} @table;
-$i=0;
-while ($i < @table) {
- $j = $i;
- while ($i < @table && ${$table[$i]}[$sortcol] == ${$table[$j]}[$sortcol]) {
- $i++;
- }
- if ($i == $j+1) {
- ${table[$j]}[0] = "$i.";
- } else {
- ${table[$j]}[0] = $j+1 . '.' . $pos_delim . $i . ".";
- $j_old=$j;
- $j++;
- while ($j < $i) { ${table[$j++]}[0] = $j_old+1 . '.' . $pos_delim . $i . "."; };
- }
-}
-print STDERR "OK\n";
-
-if ($tex) {
- open HDR,"mop/listina.hdr" or die "Cannot open file mop/listina.hdr with TeX template!";
- while (<HDR>) {print; }
- close HDR;
-
- foreach $r (@table) { print join('&',@$r), "\\cr\n";}
-
- open FTR,"mop/listina.ftr" or die "Cannot open file mop/listina.ftr with TeX template!";
- while (<FTR>) {print; }
- close FTR;
-} else {
- foreach $r (@table) { print join("\t",@$r), "\n"; }
-}
+++ /dev/null
-#!/bin/sh
-
-mop/mo-score-mop 3 2 policie rybka | column -c120 -ts" " | cstocs il2 ascii
+++ /dev/null
-bin/lib
-bin/box
-bin/iwrapper
+++ /dev/null
-#!/bin/bash
-# The Evaluator -- Public Checking Script
-# (c) 2001--2008 Martin Mares <mj@ucw.cz>
-
-set -e
-[ -n "$MO_ROOT" -a -d "$MO_ROOT" ] || { echo >&2 "MO_ROOT not set, giving up." ; exit 1 ; }
-. $MO_ROOT/bin/lib
-. $MO_ROOT/config
-
-function usage
-{
- die "Usage: check [-s <source-file>] <problem> [<test-number>]"
-}
-
-SRCFILE=
-while getopts "s:" opt ; do
- case $opt in
- s) SRCFILE="$OPTARG"
- ;;
- *) usage
- ;;
- esac
-done
-shift $(($OPTIND-1))
-[ -n "$1" ] || usage
-PROBLEM=$1
-TEST=
-shift
-if [ -n "$1" ] ; then
- TEST="$1"
- shift
-fi
-[ -z "$1" ] || usage
-
-public-setup
-. $PDIR/config
-
-function test-verdict
-{
- pend "$2"
- if [ $1 == 0 ] ; then
- exit 1
- else
- exit 0
- fi
-}
-
-if [ $TASK_TYPE == open-data ] ; then
- [ -n "$TEST" ] || die "You need to specify test number for open data problems."
- pstart "Checking $TEST: "
- test-config
- open-locate "$SRCFILE"
- try-ln "$SDIR/$SRCN" $TDIR/$TEST.out
- syntax-check
- test-result $POINTS_PER_TEST OK
-else
- [ -z "$TEST" ] || die "Test number should be given only for open data problems."
- locate-source "$SRCFILE"
- compile
- RC=0
- for TEST in $SAMPLE_TESTS ; do
- (
- pstart "Checking on sample input $TEST: "
- test-config
- test-run
- syntax-check
- output-check
- ) || RC=1
- done
- exit $RC
-fi
--- /dev/null
+#!/bin/bash
+# The Evaluator -- Public Checking Script
+# (c) 2001--2008 Martin Mares <mj@ucw.cz>
+
+set -e
+[ -n "$MO_ROOT" -a -d "$MO_ROOT" ] || { echo >&2 "MO_ROOT not set, giving up." ; exit 1 ; }
+. $MO_ROOT/bin/lib
+. $MO_ROOT/config
+
+function usage
+{
+ die "Usage: check [-s <source-file>] <problem> [<test-number>]"
+}
+
+SRCFILE=
+while getopts "s:" opt ; do
+ case $opt in
+ s) SRCFILE="$OPTARG"
+ ;;
+ *) usage
+ ;;
+ esac
+done
+shift $(($OPTIND-1))
+[ -n "$1" ] || usage
+PROBLEM=$1
+TEST=
+shift
+if [ -n "$1" ] ; then
+ TEST="$1"
+ shift
+fi
+[ -z "$1" ] || usage
+
+public-setup
+. $PDIR/config
+
+function test-verdict
+{
+ pend "$2"
+ if [ $1 == 0 ] ; then
+ exit 1
+ else
+ exit 0
+ fi
+}
+
+if [ $TASK_TYPE == open-data ] ; then
+ [ -n "$TEST" ] || die "You need to specify test number for open data problems."
+ pstart "Checking $TEST: "
+ test-config
+ open-locate "$SRCFILE"
+ try-ln "$SDIR/$SRCN" $TDIR/$TEST.out
+ syntax-check
+ test-result $POINTS_PER_TEST OK
+else
+ [ -z "$TEST" ] || die "Test number should be given only for open data problems."
+ locate-source "$SRCFILE"
+ compile
+ RC=0
+ for TEST in $SAMPLE_TESTS ; do
+ (
+ pstart "Checking on sample input $TEST: "
+ test-config
+ test-run
+ syntax-check
+ output-check
+ ) || RC=1
+ done
+ exit $RC
+fi
+++ /dev/null
-# The Evaluator -- Public Compilation Script
-# (c) 2001 Martin Mares <mj@ucw.cz>
-
-set -e
-[ -n "$MO_ROOT" -a -d "$MO_ROOT" ] || { echo >&2 "MO_ROOT not set, giving up." ; exit 1 ; }
-. $MO_ROOT/bin/lib
-. $MO_ROOT/config
-
-[ -n "$1" ] || die "Usage: compile (<problem> | <file> [<options>])"
-if [ "${1%%.*}" == "$1" ] ; then
- # Compiling problem
- PROBLEM=$1
- public-setup
- . $PDIR/config
- locate-source
- if compile ; then
- mv $TDIR/$PROBLEM .
- else
- echo >&2
- sed <check-log >&2 '1,/^Compiler output:/d;/^Compiler output files:/,$d;/^Exited /d'
- fi
-else
- SRC=$1
- [ -f $SRC ] || die "$SRC doesn't exist"
- EXE=${1%%.*}
- SRCEXT=${1/*./}
- shift
- EXTRA_CFLAGS="$@"
- CCMD=COMP_$SRCEXT
- [ -n "${!CCMD}" ] || die "Don't know how to compile $SRC"
- CCMD="`eval echo ${!CCMD}`"
- echo "$CCMD"
- $CCMD
-fi
--- /dev/null
+# The Evaluator -- Public Compilation Script
+# (c) 2001 Martin Mares <mj@ucw.cz>
+
+set -e
+[ -n "$MO_ROOT" -a -d "$MO_ROOT" ] || { echo >&2 "MO_ROOT not set, giving up." ; exit 1 ; }
+. $MO_ROOT/bin/lib
+. $MO_ROOT/config
+
+[ -n "$1" ] || die "Usage: compile (<problem> | <file> [<options>])"
+if [ "${1%%.*}" == "$1" ] ; then
+ # Compiling problem
+ PROBLEM=$1
+ public-setup
+ . $PDIR/config
+ locate-source
+ if compile ; then
+ mv $TDIR/$PROBLEM .
+ else
+ echo >&2
+ sed <check-log >&2 '1,/^Compiler output:/d;/^Compiler output files:/,$d;/^Exited /d'
+ fi
+else
+ SRC=$1
+ [ -f $SRC ] || die "$SRC doesn't exist"
+ EXE=${1%%.*}
+ SRCEXT=${1/*./}
+ shift
+ EXTRA_CFLAGS="$@"
+ CCMD=COMP_$SRCEXT
+ [ -n "${!CCMD}" ] || die "Don't know how to compile $SRC"
+ CCMD="`eval echo ${!CCMD}`"
+ echo "$CCMD"
+ $CCMD
+fi
+++ /dev/null
-#!/bin/bash
-# The Evaluator -- Public Status Script
-# (c) 2004 Martin Mares <mj@ucw.cz>
-
-set -e
-[ -n "$MO_ROOT" -a -d "$MO_ROOT" ] || { echo >&2 "MO_ROOT not set, giving up." ; exit 1 ; }
-. $MO_ROOT/bin/lib
-. $MO_ROOT/config
-
-[ -z "$1" ] || die "Usage: status"
-
-echo -e "Submitted tasks:\n"
-
-if [ -n "$REMOTE_SUBMIT" ] ; then
- exec $MO_ROOT/bin/remote-status
-fi
-
-for PROBLEM in `cd $MO_ROOT/problems/ ; echo *` ; do
- (
- PDIR=$MO_ROOT/problems/$PROBLEM
- SUBDIR=~/.submit/$PROBLEM
- [ -f $PDIR/config ] || exit 0
- echo -n "$PROBLEM: "
- . $PDIR/config
- if [ -d $SUBDIR ] ; then
- if [ $TASK_TYPE == open-data ] ; then
- for X in $TESTS ; do
- [ -f $SUBDIR/$X.out ] && echo -n "$X " || echo -n "- "
- done
- echo
- else
- C=0
- for X in $EXTENSIONS ; do
- if [ -f $SUBDIR/$PROBLEM.$X ] ; then
- echo -n `basename $SUBDIR/$PROBLEM.$X`
- C=$(($C+1))
- fi
- done
- if [ $C == 0 ] ; then
- echo ---
- elif [ $C == 1 ] ; then
- echo
- else
- echo "INCONSISTENT (you probably modified $SUBDIR manually)"
- fi
- fi
- else
- echo ---
- fi
- )
-done
--- /dev/null
+#!/bin/bash
+# The Evaluator -- Public Status Script
+# (c) 2004 Martin Mares <mj@ucw.cz>
+
+set -e
+[ -n "$MO_ROOT" -a -d "$MO_ROOT" ] || { echo >&2 "MO_ROOT not set, giving up." ; exit 1 ; }
+. $MO_ROOT/bin/lib
+. $MO_ROOT/config
+
+[ -z "$1" ] || die "Usage: status"
+
+echo -e "Submitted tasks:\n"
+
+if [ -n "$REMOTE_SUBMIT" ] ; then
+ exec $MO_ROOT/bin/remote-status
+fi
+
+for PROBLEM in `cd $MO_ROOT/problems/ ; echo *` ; do
+ (
+ PDIR=$MO_ROOT/problems/$PROBLEM
+ SUBDIR=~/.submit/$PROBLEM
+ [ -f $PDIR/config ] || exit 0
+ echo -n "$PROBLEM: "
+ . $PDIR/config
+ if [ -d $SUBDIR ] ; then
+ if [ $TASK_TYPE == open-data ] ; then
+ for X in $TESTS ; do
+ [ -f $SUBDIR/$X.out ] && echo -n "$X " || echo -n "- "
+ done
+ echo
+ else
+ C=0
+ for X in $EXTENSIONS ; do
+ if [ -f $SUBDIR/$PROBLEM.$X ] ; then
+ echo -n `basename $SUBDIR/$PROBLEM.$X`
+ C=$(($C+1))
+ fi
+ done
+ if [ $C == 0 ] ; then
+ echo ---
+ elif [ $C == 1 ] ; then
+ echo
+ else
+ echo "INCONSISTENT (you probably modified $SUBDIR manually)"
+ fi
+ fi
+ else
+ echo ---
+ fi
+ )
+done
+++ /dev/null
-#!/bin/bash
-# The Evaluator -- Public Submit Script
-# (c) 2001--2007 Martin Mares <mj@ucw.cz>
-
-set -e
-[ -n "$MO_ROOT" -a -d "$MO_ROOT" ] || { echo >&2 "MO_ROOT not set, giving up." ; exit 1 ; }
-. $MO_ROOT/bin/lib
-. $MO_ROOT/config
-
-function usage
-{
- die "Usage: submit [--force] [-s <source-file>] <problem> [<test-number>]"
-}
-
-FORCE=0
-if [ "$1" = --force ] ; then
- FORCE=1
- shift
-fi
-[ -n "$1" -a "$1" != "--help" ] || usage
-SRCFILE=
-while getopts "s:" opt ; do
- case $opt in
- s) SRCFILE="$OPTARG"
- ;;
- *) usage
- ;;
- esac
-done
-shift $(($OPTIND-1))
-[ -n "$1" ] || usage
-PROBLEM=$1
-PART=
-shift
-if [ -n "$1" ] ; then
- PART="$1"
- shift
-fi
-[ -z "$1" ] || usage
-public-setup
-. $PDIR/config
-
-function test-verdict
-{
- pend "$2"
- [ $1 == 0 ] && exit 1 || exit 0
-}
-
-FAILED=0
-if [ $TASK_TYPE == open-data ] ; then
- [ -n "$PART" ] || die "You need to specify test number for open data problems."
- TEST=$PART
- pstart "Test case $TEST: "
- open-locate "$SRCFILE"
- (
- [ -f $PDIR/$TEST.config ] && . $PDIR/$TEST.config
- try-ln "$SDIR/$SRCN" $TDIR/$TEST.out
- syntax-check
- test-result $POINTS_PER_TEST OK
- ) || FAILED=1
-else
- [ -z "$PART" ] || die "Test number should be given only for open data problems."
- locate-source "$SRCFILE"
- compile
- for TEST in $SAMPLE_TESTS ; do
- (
- pstart "Checking on sample input $TEST: "
- [ -f $PDIR/$TEST.config ] && . $PDIR/$TEST.config
- test-run
- syntax-check
- output-check
- die "How could I get there? It's a buuuuug!"
- ) || FAILED=$(($FAILED+1))
- done
-fi
-
-if [ $FAILED != 0 ] ; then
- if [ $FORCE != 0 ] ; then
- echo "Submit forced."
- pend "TESTS FAILED, but --force given, so submitting anyway."
- else
- pend "TESTS FAILED. Nothing has been submitted!"
- pend "Use submit --force if you really want to submit an obviously WRONG solution."
- exit 1
- fi
-fi
-
-if [ -n "$REMOTE_SUBMIT" ] ; then
- pstart "Submitting to the server... "
- $MO_ROOT/bin/remote-submit $PROBLEM $PART "$SDIR/$SRCN"
- pend "OK"
- exit 0
-fi
-
-pstart "Submitting... "
-mkdir -p ~/.submit
-if [ $TASK_TYPE == open-data ] ; then
- mkdir -p ~/.submit/$PROBLEM
- cp "$SDIR/$SRCN" ~/.submit/$PROBLEM/$PART.out
-else
- rm -rf ~/.submit/$PROBLEM
- mkdir -p ~/.submit/$PROBLEM
- cp "$SDIR/$SRCN" ~/.submit/$PROBLEM/
-fi
-pend "OK"
--- /dev/null
+#!/bin/bash
+# The Evaluator -- Public Submit Script
+# (c) 2001--2007 Martin Mares <mj@ucw.cz>
+
+set -e
+[ -n "$MO_ROOT" -a -d "$MO_ROOT" ] || { echo >&2 "MO_ROOT not set, giving up." ; exit 1 ; }
+. $MO_ROOT/bin/lib
+. $MO_ROOT/config
+
+function usage
+{
+ die "Usage: submit [--force] [-s <source-file>] <problem> [<test-number>]"
+}
+
+FORCE=0
+if [ "$1" = --force ] ; then
+ FORCE=1
+ shift
+fi
+[ -n "$1" -a "$1" != "--help" ] || usage
+SRCFILE=
+while getopts "s:" opt ; do
+ case $opt in
+ s) SRCFILE="$OPTARG"
+ ;;
+ *) usage
+ ;;
+ esac
+done
+shift $(($OPTIND-1))
+[ -n "$1" ] || usage
+PROBLEM=$1
+PART=
+shift
+if [ -n "$1" ] ; then
+ PART="$1"
+ shift
+fi
+[ -z "$1" ] || usage
+public-setup
+. $PDIR/config
+
+function test-verdict
+{
+ pend "$2"
+ [ $1 == 0 ] && exit 1 || exit 0
+}
+
+FAILED=0
+if [ $TASK_TYPE == open-data ] ; then
+ [ -n "$PART" ] || die "You need to specify test number for open data problems."
+ TEST=$PART
+ pstart "Test case $TEST: "
+ open-locate "$SRCFILE"
+ (
+ [ -f $PDIR/$TEST.config ] && . $PDIR/$TEST.config
+ try-ln "$SDIR/$SRCN" $TDIR/$TEST.out
+ syntax-check
+ test-result $POINTS_PER_TEST OK
+ ) || FAILED=1
+else
+ [ -z "$PART" ] || die "Test number should be given only for open data problems."
+ locate-source "$SRCFILE"
+ compile
+ for TEST in $SAMPLE_TESTS ; do
+ (
+ pstart "Checking on sample input $TEST: "
+ [ -f $PDIR/$TEST.config ] && . $PDIR/$TEST.config
+ test-run
+ syntax-check
+ output-check
+ die "How could I get there? It's a buuuuug!"
+ ) || FAILED=$(($FAILED+1))
+ done
+fi
+
+if [ $FAILED != 0 ] ; then
+ if [ $FORCE != 0 ] ; then
+ echo "Submit forced."
+ pend "TESTS FAILED, but --force given, so submitting anyway."
+ else
+ pend "TESTS FAILED. Nothing has been submitted!"
+ pend "Use submit --force if you really want to submit an obviously WRONG solution."
+ exit 1
+ fi
+fi
+
+if [ -n "$REMOTE_SUBMIT" ] ; then
+ pstart "Submitting to the server... "
+ $MO_ROOT/bin/remote-submit $PROBLEM $PART "$SDIR/$SRCN"
+ pend "OK"
+ exit 0
+fi
+
+pstart "Submitting... "
+mkdir -p ~/.submit
+if [ $TASK_TYPE == open-data ] ; then
+ mkdir -p ~/.submit/$PROBLEM
+ cp "$SDIR/$SRCN" ~/.submit/$PROBLEM/$PART.out
+else
+ rm -rf ~/.submit/$PROBLEM
+ mkdir -p ~/.submit/$PROBLEM
+ cp "$SDIR/$SRCN" ~/.submit/$PROBLEM/
+fi
+pend "OK"
--- /dev/null
+}}}
+
+\bye
--- /dev/null
+\language=\czech
+\frenchspacing
+\font\head=csr12 scaled \magstephalf
+\font\hexx=csti12
+\font\xxit=csti10
+\def\xit{\xxit\kern-0.1em\relax}
+\let\hb=\relax
+\parindent=0pt
+\nopagenumbers
+
+\centerline{\head Výsledková listina ústøedního kola 56. roèníku MO kategorie P}
+\bigskip
+\centerline{\hexx 21. -- 24. bøezna 2007 ve Zlínì}
+\bigskip
+\bigskip
+
+\hrule
+\bigskip
+
+\centerline{\vbox{\halign{%
+#\hfil &~~#\hfil &\quad #\hfil &~~#\hfil&\quad
+\hfil # &
+\hfil # &
+\hfil # & \kern0.4em
+\hfil # &
+\hfil # & \kern1em
+\hb\quad\hfil # \cr
+\noalign{\bigskip\bigskip\hbox{\xit Vítìzové}\bigskip}
+%\noalign{\bigskip\bigskip\hbox{\xit Úspì¹ní øe¹itelé}\bigskip}
+%\noalign{\bigskip\bigskip\hbox{\xit Ostatní úèastníci}\bigskip}
--- /dev/null
+#!/bin/sh
+
+mop/mo-score-mop 3 2 policie rybka | column -c120 -ts" " | cstocs il2 ascii
--- /dev/null
+#!/usr/bin/perl
+
+$tex = 0;
+$usage = "Usage: mo-score-mop [--tex] theoretical_tasks_nr praxis_tasks_nr task1 task2 ...";
+while (($arg = $ARGV[0]) =~ /^--([a-z]+)$/) {
+ shift @ARGV;
+ $var = "\$$1";
+ if (!eval "defined $var") { die $usage; }
+ eval "$var = 1;";
+}
+@ARGV >=2 || die $usage;
+$theory=shift @ARGV;
+$praxis=shift @ARGV;
+@ARGV >= $praxis || die $usage;
+$pos_delim=$tex ? '--' : '-';
+
+print STDERR "Scanning contestants... ";
+open (CT, "bin/mo-get-users --full |") || die "Cannot get list of contestants";
+while (<CT>) {
+ chomp;
+ ($u,$f) = split /\t/;
+ ($u eq "somebody") && next;
+ $users{$u}=$f;
+}
+close CT;
+print STDERR 0+keys %users, "\n";
+
+print STDERR "Scanning teoretical results... ";
+if (open (EX, "mop/teorie.txt")) {
+ while (<EX>) {
+ chomp;
+ (/^$/ || /^#/) && next;
+ @a = split /\ *\t\ */;
+ $u = shift @a;
+ defined $users{$u} || die "Unknown user $u";
+ $names{$u} = shift @a;
+ $forms{$u} = shift @a;
+ $addresses{$u} = "{". (shift @a) ."}";
+ $i=0;
+ while (@a) { $tasks{$u}{$i} = shift @a;$i++; }
+ }
+ close EX;
+ print STDERR "OK\n";
+} else {die "none, cannot find file mop/teorie.txt!\n";}
+
+print STDERR "Scanning task results... ";
+$need_tasks = join("|", @ARGV);
+foreach $u (keys %users) {
+ opendir (D, "testing/$u") or next;
+ foreach $t (readdir(D)) {
+ $t =~ /^\./ && next;
+ $t =~ /$need_tasks/ || next;
+
+ $t_num=$praxis;
+ for (my $t_num2=0;$t_num2<@ARGV;$t_num2++) {if ($t eq $ARGV[$t_num2]) {$t_num=$t_num2;}}
+ $t_num+=$theory;
+
+ $tt = "testing/$u/$t/points";
+ -f $tt || next;
+ print STDERR "$u/$t ";
+ open (X, $tt) || die "Unable to open $tt";
+ while (<X>) {
+ chomp;
+ /^\S+ (-?\d+)/ || die "Parse error: $_";
+ $tasks{$u}{$t_num} += $1;
+ }
+ close X;
+ }
+ closedir D;
+}
+print STDERR "OK\n";
+
+print STDERR "Creating table template... ";
+@body = ('','$names{$u}','$forms{$u}','$addresses{$u}');
+for ($a=0;$a<$theory+$praxis;$a++) {push @body,"\$tasks{\$u}{$a}";}
+print STDERR "OK\n";
+
+print STDERR "Filling in results... ";
+@table = ();
+foreach $u (keys %users) {
+ next unless defined $names{$u}; # don't show any user not defined in teorie.txt
+ $row = [];
+ $row_index=0;
+ $row_sum=0;
+ foreach my $c (@body) {
+ $c =~ s/\$(\d+)/\$\$row[$1]/g;
+ $x = eval $c;
+ push @$row, (defined $x ? $x : '-');
+ if ($row_index>3) {
+ if ((defined $x) && ($x>0)) {$row_sum+=$x;}
+ }
+ $row_index++;
+ }
+ push @$row, $row_sum;
+ push @table, $row;
+}
+print STDERR "OK\n";
+
+print STDERR "Sorting... ";
+$sortcol = @{$table[0]} - 1;
+$namecol = 1;
+@table = sort {
+ my $p, $an, $bn;
+ $p = $$b[$sortcol] <=> $$a[$sortcol];
+ ($an = $$a[$namecol]) =~ s/(\S+)\s+(\S+)/$2 $1/;
+ ($bn = $$b[$namecol]) =~ s/(\S+)\s+(\S+)/$2 $1/;
+ $p ? $p : ($an cmp $bn);
+} @table;
+$i=0;
+while ($i < @table) {
+ $j = $i;
+ while ($i < @table && ${$table[$i]}[$sortcol] == ${$table[$j]}[$sortcol]) {
+ $i++;
+ }
+ if ($i == $j+1) {
+ ${table[$j]}[0] = "$i.";
+ } else {
+ ${table[$j]}[0] = $j+1 . '.' . $pos_delim . $i . ".";
+ $j_old=$j;
+ $j++;
+ while ($j < $i) { ${table[$j++]}[0] = $j_old+1 . '.' . $pos_delim . $i . "."; };
+ }
+}
+print STDERR "OK\n";
+
+if ($tex) {
+ open HDR,"mop/listina.hdr" or die "Cannot open file mop/listina.hdr with TeX template!";
+ while (<HDR>) {print; }
+ close HDR;
+
+ foreach $r (@table) { print join('&',@$r), "\\cr\n";}
+
+ open FTR,"mop/listina.ftr" or die "Cannot open file mop/listina.ftr with TeX template!";
+ while (<FTR>) {print; }
+ close FTR;
+} else {
+ foreach $r (@table) { print join("\t",@$r), "\n"; }
+}
--- /dev/null
+mo04 Jakub Balhar 6/6 G J. Nerudy, Praha 1 1 1
+mo24 Roman Smr¾ 7/8 G E. Krásnohorské, Praha 6 3 10
+mo01 Tomá¹ Køen 4/4 G Ch. Dopplera, Praha 0 3 0
+mo12 Pavel John 4/4 G Arabská, Praha 0 1 7
+mo23 Martin Pokorný 4/4 G Arabská, Praha 3 2 9
+mo11 Matìj Korvas 8/8 G J. Seiferta, Praha 0 2 1
+mo28 Tomá¹ Pøaslièák 7/8 GOA Nádra¾ní, Sedlèany 0 3 1
+mo13 Zuzana Bure¹ová 8/8 Masarykovo G, Plzeò 0 1 1
+mo03 Roman Diba 3/4 VO© a SP©E Plzeò 0 0 1
+mo22 Libor Peltan 7/8 G Èeská, Èeské Budìjovice 0 0 10
+mo32 Roman Øíha 7/8 G Zlatá stezka, Prachatice 0 1 0
+mo31 Josef Pihera 8/8 G Máchova, Strakonice 7 4 10
+mo21 Michal Minaøík 4/4 G F. X. ©aldy, Liberec 0 0 0
+mo15 Jakub Kaplan 3/4 G J. K. Tyla, Hradec Králové 5 3 1
+mo06 Luká¹ Lánský 3/4 G J. K. Tyla, Hradec Králové 3 5 10
+mo36 Marek Scholle 8/8 G Da¹ická, Pardubice 6 1 0
+mo02 Pavel Klavík 8/8 G J. Ressla, Chrudim 0 4 10
+mo14 Petr Kratochvíl 4/4 G Sázavská, Svìtlá nad Sázavou 1 1 6
+mo16 Filip Dìchtìrenko 8/8 G J. Masaryka, Jihlava 0 1 1
+mo33 Martin Ve¹krna 4/4 G Vídeòská, Brno 0 3 1
+mo09 Ondøej Bouda 8/8 G Tø. Kpt. Jaro¹e, Brno 1 3 0
+mo30 Michal Novák 8/8 G Tø. Kpt. Jaro¹e, Brno 0 0 2
+mo27 Ondøej Piálek 4/4 G Masarykovo nám., Tøebíè 7 1 1
+mo34 Michal Pavelèík 8/8 G J. A. Komenského, Uherský Brod 0 0 0
+mo10 Martin Milata 8/8 G Hladnovská, Ostrava 0 2 8
+mo35 Libor Plucnar 4/6 G P. Bezruèe, Frýdek-Místek 0 1 1
+mo26 Pavel Motloch 6/6 G P. Bezruèe, Frýdek-Místek 0 7 10
+mo07 Miroslav Klimo¹ 2/4 G M. Koperníka, Bílovec 9 9 10
+mo25 Tomá¹ Toufar 3/4 G M. Koperníka, Bílovec 0 3 0
+mo08 Petr Dluho¹ 8/8 Mendelovo G, Opava 0 0 10
\ No newline at end of file
--- /dev/null
+\language=\czech
+\frenchspacing
+\font\head=csr12 scaled \magstephalf
+\font\hexx=csti12
+\font\xxit=csti10
+\def\xit{\xxit\kern-0.1em\relax}
+\let\hb=\relax
+\parindent=0pt
+\nopagenumbers
+
+\centerline{\head Výsledková listina ústøedního kola 56. roèníku MO kategorie P}
+\bigskip
+\centerline{\hexx 21. -- 24. bøezna 2007 ve Zlínì}
+\bigskip
+\bigskip
+
+\hrule
+\bigskip
+
+\centerline{\vbox{\halign{%
+#\hfil &~~#\hfil &\quad #\hfil &~~#\hfil&\quad
+\hfil # &
+\hfil # &
+\hfil # & \kern0.4em
+\hfil # &
+\hfil # & \kern1em
+\hb\quad\hfil # \cr
+\noalign{\bigskip\bigskip\hbox{\xit Vítìzové}\bigskip}
+%\noalign{\bigskip\bigskip\hbox{\xit Úspì¹ní øe¹itelé}\bigskip}
+%\noalign{\bigskip\bigskip\hbox{\xit Ostatní úèastníci}\bigskip}
+1.&Josef Pihera&8/8&{G Máchova, Strakonice}&7&4&10&15&15&51\cr
+2.&Pavel Klavík&8/8&{G J. Ressla, Chrudim}&0&4&10&15&12&41\cr
+3.&Roman Smr¾&7/8&{G E. Krásnohorské, Praha}&6&3&10&0&13&32\cr
+4.&Miroslav Klimo¹&2/4&{G M. Koperníka, Bílovec}&9&9&10&2&0&30\cr
+5.&Luká¹ Lánský&3/4&{G J. K. Tyla, Hradec Králové}&3&5&10&0&0&18\cr
+6.&Pavel Motloch&6/6&{G P. Bezruèe, Frýdek-Místek}&0&7&10&0&0&17\cr
+7.&Jakub Kaplan&3/4&{G J. K. Tyla, Hradec Králové}&5&3&1&7&0&16\cr
+8.&Martin Pokorný&4/4&{G Arabská, Praha}&3&2&9&1&-&15\cr
+9.&Martin Milata&8/8&{G Hladnovská, Ostrava}&0&2&8&0&4&14\cr
+10.&Libor Peltan&7/8&{G Èeská, Èeské Budìjovice}&0&0&10&3&-&13\cr
+11.&Ondøej Piálek&4/4&{G Masarykovo nám., Tøebíè}&7&1&1&0&3&12\cr
+12.&Petr Dluho¹&8/8&{Mendelovo G, Opava}&0&0&10&0&1&11\cr
+13.&Petr Kratochvíl&4/4&{G Sázavská, Svìtlá nad Sázavou}&1&1&6&1&-&9\cr
+14.&Pavel John&4/4&{G Arabská, Praha}&0&1&7&-&0&8\cr
+15.&Marek Scholle&8/8&{G Da¹ická, Pardubice}&6&1&0&0&-&7\cr
+16.&Ondøej Bouda&8/8&{G Tø. Kpt. Jaro¹e, Brno}&1&3&0&2&0&6\cr
+17.&Tomá¹ Toufar&3/4&{G M. Koperníka, Bílovec}&0&3&0&2&0&5\cr
+18.--19.&Tomá¹ Pøaslièák&7/8&{GOA Nádra¾ní, Sedlèany}&0&3&1&-&0&4\cr
+18.--19.&Martin Ve¹krna&4/4&{G Vídeòská, Brno}&0&3&1&-&-&4\cr
+20.--25.&Jakub Balhar&6/6&{G J. Nerudy, Praha}&1&1&1&-&0&3\cr
+20.--25.&Roman Diba&3/4&{VO© a SP©E Plzeò}&0&0&1&2&-&3\cr
+20.--25.&Filip Dìchtìrenko&8/8&{G J. Masaryka, Jihlava}&0&1&1&0&1&3\cr
+20.--25.&Matìj Korvas&8/8&{G J. Seiferta, Praha}&0&2&1&-&0&3\cr
+20.--25.&Tomá¹ Køen&4/4&{G Ch. Dopplera, Praha}&0&3&0&-&-&3\cr
+20.--25.&Michal Pavelèík&8/8&{G J. A. Komenského, Uherský Brod}&0&0&0&0&3&3\cr
+26.--28.&Zuzana Bure¹ová&8/8&{Masarykovo G, Plzeò}&0&1&1&0&-&2\cr
+26.--28.&Michal Novák&8/8&{G Tø. Kpt. Jaro¹e, Brno}&0&0&2&-&-&2\cr
+26.--28.&Libor Plucnar&4/6&{G P. Bezruèe, Frýdek-Místek}&0&1&1&0&-&2\cr
+29.&Roman Øíha&7/8&{G Zlatá stezka, Prachatice}&0&1&0&-&0&1\cr
+30.&Michal Minaøík&4/4&{G F. X. ©aldy, Liberec}&0&0&0&-&-&0\cr
+}}}
+
+\bye
--- /dev/null
+1. Josef Pihera 8/8 {G Machova, Strakonice} 7 4 10 15 15 51
+2. Pavel Klavik 8/8 {G J. Ressla, Chrudim} 0 4 10 15 12 41
+3. Roman Smrz 7/8 {G E. Krasnohorske, Praha} 6 3 10 0 13 32
+4. Miroslav Klimos 2/4 {G M. Kopernika, Bilovec} 9 9 10 2 0 30
+5. Lukas Lansky 3/4 {G J. K. Tyla, Hradec Kralove} 3 5 10 0 0 18
+6. Pavel Motloch 6/6 {G P. Bezruce, Frydek-Mistek} 0 7 10 0 0 17
+7. Jakub Kaplan 3/4 {G J. K. Tyla, Hradec Kralove} 5 3 1 7 0 16
+8. Martin Pokorny 4/4 {G Arabska, Praha} 3 2 9 1 - 15
+9. Martin Milata 8/8 {G Hladnovska, Ostrava} 0 2 8 0 4 14
+10. Libor Peltan 7/8 {G Ceska, Ceske Budejovice} 0 0 10 3 - 13
+11. Ondrej Pialek 4/4 {G Masarykovo nam., Trebic} 7 1 1 0 3 12
+12. Petr Dluhos 8/8 {Mendelovo G, Opava} 0 0 10 0 1 11
+13. Petr Kratochvil 4/4 {G Sazavska, Svetla nad Sazavou} 1 1 6 1 - 9
+14. Pavel John 4/4 {G Arabska, Praha} 0 1 7 - 0 8
+15. Marek Scholle 8/8 {G Dasicka, Pardubice} 6 1 0 0 - 7
+16. Ondrej Bouda 8/8 {G Tr. Kpt. Jarose, Brno} 1 3 0 2 0 6
+17. Tomas Toufar 3/4 {G M. Kopernika, Bilovec} 0 3 0 2 0 5
+18.-19. Tomas Praslicak 7/8 {GOA Nadrazni, Sedlcany} 0 3 1 - 0 4
+18.-19. Martin Veskrna 4/4 {G Videnska, Brno} 0 3 1 - - 4
+20.-25. Jakub Balhar 6/6 {G J. Nerudy, Praha} 1 1 1 - 0 3
+20.-25. Roman Diba 3/4 {VOS a SPSE Plzen} 0 0 1 2 - 3
+20.-25. Filip Dechterenko 8/8 {G J. Masaryka, Jihlava} 0 1 1 0 1 3
+20.-25. Matej Korvas 8/8 {G J. Seiferta, Praha} 0 2 1 - 0 3
+20.-25. Tomas Kren 4/4 {G Ch. Dopplera, Praha} 0 3 0 - - 3
+20.-25. Michal Pavelcik 8/8 {G J. A. Komenskeho, Uhersky Brod} 0 0 0 0 3 3
+26.-28. Zuzana Buresova 8/8 {Masarykovo G, Plzen} 0 1 1 0 - 2
+26.-28. Michal Novak 8/8 {G Tr. Kpt. Jarose, Brno} 0 0 2 - - 2
+26.-28. Libor Plucnar 4/6 {G P. Bezruce, Frydek-Mistek} 0 1 1 0 - 2
+29. Roman Riha 7/8 {G Zlata stezka, Prachatice} 0 1 0 - 0 1
+30. Michal Minarik 4/4 {G F. X. Saldy, Liberec} 0 0 0 - - 0
+++ /dev/null
-mo04 Jakub Balhar 6/6 G J. Nerudy, Praha 1 1 1
-mo24 Roman Smr¾ 7/8 G E. Krásnohorské, Praha 6 3 10
-mo01 Tomá¹ Køen 4/4 G Ch. Dopplera, Praha 0 3 0
-mo12 Pavel John 4/4 G Arabská, Praha 0 1 7
-mo23 Martin Pokorný 4/4 G Arabská, Praha 3 2 9
-mo11 Matìj Korvas 8/8 G J. Seiferta, Praha 0 2 1
-mo28 Tomá¹ Pøaslièák 7/8 GOA Nádra¾ní, Sedlèany 0 3 1
-mo13 Zuzana Bure¹ová 8/8 Masarykovo G, Plzeò 0 1 1
-mo03 Roman Diba 3/4 VO© a SP©E Plzeò 0 0 1
-mo22 Libor Peltan 7/8 G Èeská, Èeské Budìjovice 0 0 10
-mo32 Roman Øíha 7/8 G Zlatá stezka, Prachatice 0 1 0
-mo31 Josef Pihera 8/8 G Máchova, Strakonice 7 4 10
-mo21 Michal Minaøík 4/4 G F. X. ©aldy, Liberec 0 0 0
-mo15 Jakub Kaplan 3/4 G J. K. Tyla, Hradec Králové 5 3 1
-mo06 Luká¹ Lánský 3/4 G J. K. Tyla, Hradec Králové 3 5 10
-mo36 Marek Scholle 8/8 G Da¹ická, Pardubice 6 1 0
-mo02 Pavel Klavík 8/8 G J. Ressla, Chrudim 0 4 10
-mo14 Petr Kratochvíl 4/4 G Sázavská, Svìtlá nad Sázavou 1 1 6
-mo16 Filip Dìchtìrenko 8/8 G J. Masaryka, Jihlava 0 1 1
-mo33 Martin Ve¹krna 4/4 G Vídeòská, Brno 0 3 1
-mo09 Ondøej Bouda 8/8 G Tø. Kpt. Jaro¹e, Brno 1 3 0
-mo30 Michal Novák 8/8 G Tø. Kpt. Jaro¹e, Brno 0 0 2
-mo27 Ondøej Piálek 4/4 G Masarykovo nám., Tøebíè 7 1 1
-mo34 Michal Pavelèík 8/8 G J. A. Komenského, Uherský Brod 0 0 0
-mo10 Martin Milata 8/8 G Hladnovská, Ostrava 0 2 8
-mo35 Libor Plucnar 4/6 G P. Bezruèe, Frýdek-Místek 0 1 1
-mo26 Pavel Motloch 6/6 G P. Bezruèe, Frýdek-Místek 0 7 10
-mo07 Miroslav Klimo¹ 2/4 G M. Koperníka, Bílovec 9 9 10
-mo25 Tomá¹ Toufar 3/4 G M. Koperníka, Bílovec 0 3 0
-mo08 Petr Dluho¹ 8/8 Mendelovo G, Opava 0 0 10
\ No newline at end of file
+++ /dev/null
-cro1 Igor Canadi ceoi54
-cro2 Goran Zuzic ceoi47
-cro3 Domagoj Kusalic ceoi35
-cro4 Relja Medic ceoi66
-czk1 Pavel Klavík ceoi74
-czk2 Miroslav Klimo¹ ceoi68
-czk3 Josef Pihera ceoi34
-czk4 Roman Smr¾ ceoi62
-czk5 Jakub Kaplan ceoi39
-czk6 Luká¹ Lánský ceoi51
-czk7 Libor Peltan ceoi50
-czk8 Libor Plucnar ceoi45
-deu1 Daniel Grunwald ceoi71
-deu2 Ludwig Schmidt ceoi59
-deu3 Benito van der Zander ceoi46
-deu4 Martin Maas ceoi48
-hun1 András Eisenberger ceoi42
-hun2 Tamás Peregi ceoi63
-hun3 Balázs Szalkai ceoi53
-hun4 Gergely Nagy ceoi31
-pol1 Marcin Andrychowicz ceoi70
-pol2 Marcin Kurczych ceoi37
-pol3 Jakub Kallas ceoi43
-pol4 Tomasz Kulczy\'nski ceoi61
-rom1 Andrei Grigorean ceoi67
-rom2 Cosmin Gheorghe ceoi33
-rom3 Victor Rusu ceoi58
-rom4 Stefan-Alex. Filip ceoi73
-svk1 Vladimír Bo¾a ceoi41
-svk2 Peter Ondrú¹ka ceoi55
-svk3 Michal Danilák ceoi38
-svk4 Jozef Jirásek ceoi30
-brn1 Ondøej Bouda ceoi56
-brn2 Marek Bry¹a ceoi65
-zzz1 Sleepy Gandalf ceoi27
--- /dev/null
+cro1 Igor Canadi ceoi54
+cro2 Goran Zuzic ceoi47
+cro3 Domagoj Kusalic ceoi35
+cro4 Relja Medic ceoi66
+czk1 Pavel Klavík ceoi74
+czk2 Miroslav Klimo¹ ceoi68
+czk3 Josef Pihera ceoi34
+czk4 Roman Smr¾ ceoi62
+czk5 Jakub Kaplan ceoi39
+czk6 Luká¹ Lánský ceoi51
+czk7 Libor Peltan ceoi50
+czk8 Libor Plucnar ceoi45
+deu1 Daniel Grunwald ceoi71
+deu2 Ludwig Schmidt ceoi59
+deu3 Benito van der Zander ceoi46
+deu4 Martin Maas ceoi48
+hun1 András Eisenberger ceoi42
+hun2 Tamás Peregi ceoi63
+hun3 Balázs Szalkai ceoi53
+hun4 Gergely Nagy ceoi31
+pol1 Marcin Andrychowicz ceoi70
+pol2 Marcin Kurczych ceoi37
+pol3 Jakub Kallas ceoi43
+pol4 Tomasz Kulczy\'nski ceoi61
+rom1 Andrei Grigorean ceoi67
+rom2 Cosmin Gheorghe ceoi33
+rom3 Victor Rusu ceoi58
+rom4 Stefan-Alex. Filip ceoi73
+svk1 Vladimír Bo¾a ceoi41
+svk2 Peter Ondrú¹ka ceoi55
+svk3 Michal Danilák ceoi38
+svk4 Jozef Jirásek ceoi30
+brn1 Ondøej Bouda ceoi56
+brn2 Marek Bry¹a ceoi65
+zzz1 Sleepy Gandalf ceoi27
+++ /dev/null
-\language=\czech
-\frenchspacing
-\font\head=csr12 scaled \magstephalf
-\font\hexx=csti12
-\font\xxit=csti10
-\def\xit{\xxit\kern-0.1em\relax}
-\let\hb=\relax
-\parindent=0pt
-\nopagenumbers
-
-\centerline{\head Výsledková listina ústøedního kola 56. roèníku MO kategorie P}
-\bigskip
-\centerline{\hexx 21. -- 24. bøezna 2007 ve Zlínì}
-\bigskip
-\bigskip
-
-\hrule
-\bigskip
-
-\centerline{\vbox{\halign{%
-#\hfil &~~#\hfil &\quad #\hfil &~~#\hfil&\quad
-\hfil # &
-\hfil # &
-\hfil # & \kern0.4em
-\hfil # &
-\hfil # & \kern1em
-\hb\quad\hfil # \cr
-\noalign{\bigskip\bigskip\hbox{\xit Vítìzové}\bigskip}
-%\noalign{\bigskip\bigskip\hbox{\xit Úspì¹ní øe¹itelé}\bigskip}
-%\noalign{\bigskip\bigskip\hbox{\xit Ostatní úèastníci}\bigskip}
-1.&Josef Pihera&8/8&{G Máchova, Strakonice}&7&4&10&15&15&51\cr
-2.&Pavel Klavík&8/8&{G J. Ressla, Chrudim}&0&4&10&15&12&41\cr
-3.&Roman Smr¾&7/8&{G E. Krásnohorské, Praha}&6&3&10&0&13&32\cr
-4.&Miroslav Klimo¹&2/4&{G M. Koperníka, Bílovec}&9&9&10&2&0&30\cr
-5.&Luká¹ Lánský&3/4&{G J. K. Tyla, Hradec Králové}&3&5&10&0&0&18\cr
-6.&Pavel Motloch&6/6&{G P. Bezruèe, Frýdek-Místek}&0&7&10&0&0&17\cr
-7.&Jakub Kaplan&3/4&{G J. K. Tyla, Hradec Králové}&5&3&1&7&0&16\cr
-8.&Martin Pokorný&4/4&{G Arabská, Praha}&3&2&9&1&-&15\cr
-9.&Martin Milata&8/8&{G Hladnovská, Ostrava}&0&2&8&0&4&14\cr
-10.&Libor Peltan&7/8&{G Èeská, Èeské Budìjovice}&0&0&10&3&-&13\cr
-11.&Ondøej Piálek&4/4&{G Masarykovo nám., Tøebíè}&7&1&1&0&3&12\cr
-12.&Petr Dluho¹&8/8&{Mendelovo G, Opava}&0&0&10&0&1&11\cr
-13.&Petr Kratochvíl&4/4&{G Sázavská, Svìtlá nad Sázavou}&1&1&6&1&-&9\cr
-14.&Pavel John&4/4&{G Arabská, Praha}&0&1&7&-&0&8\cr
-15.&Marek Scholle&8/8&{G Da¹ická, Pardubice}&6&1&0&0&-&7\cr
-16.&Ondøej Bouda&8/8&{G Tø. Kpt. Jaro¹e, Brno}&1&3&0&2&0&6\cr
-17.&Tomá¹ Toufar&3/4&{G M. Koperníka, Bílovec}&0&3&0&2&0&5\cr
-18.--19.&Tomá¹ Pøaslièák&7/8&{GOA Nádra¾ní, Sedlèany}&0&3&1&-&0&4\cr
-18.--19.&Martin Ve¹krna&4/4&{G Vídeòská, Brno}&0&3&1&-&-&4\cr
-20.--25.&Jakub Balhar&6/6&{G J. Nerudy, Praha}&1&1&1&-&0&3\cr
-20.--25.&Roman Diba&3/4&{VO© a SP©E Plzeò}&0&0&1&2&-&3\cr
-20.--25.&Filip Dìchtìrenko&8/8&{G J. Masaryka, Jihlava}&0&1&1&0&1&3\cr
-20.--25.&Matìj Korvas&8/8&{G J. Seiferta, Praha}&0&2&1&-&0&3\cr
-20.--25.&Tomá¹ Køen&4/4&{G Ch. Dopplera, Praha}&0&3&0&-&-&3\cr
-20.--25.&Michal Pavelèík&8/8&{G J. A. Komenského, Uherský Brod}&0&0&0&0&3&3\cr
-26.--28.&Zuzana Bure¹ová&8/8&{Masarykovo G, Plzeò}&0&1&1&0&-&2\cr
-26.--28.&Michal Novák&8/8&{G Tø. Kpt. Jaro¹e, Brno}&0&0&2&-&-&2\cr
-26.--28.&Libor Plucnar&4/6&{G P. Bezruèe, Frýdek-Místek}&0&1&1&0&-&2\cr
-29.&Roman Øíha&7/8&{G Zlatá stezka, Prachatice}&0&1&0&-&0&1\cr
-30.&Michal Minaøík&4/4&{G F. X. ©aldy, Liberec}&0&0&0&-&-&0\cr
-}}}
-
-\bye
+++ /dev/null
-1. Josef Pihera 8/8 {G Machova, Strakonice} 7 4 10 15 15 51
-2. Pavel Klavik 8/8 {G J. Ressla, Chrudim} 0 4 10 15 12 41
-3. Roman Smrz 7/8 {G E. Krasnohorske, Praha} 6 3 10 0 13 32
-4. Miroslav Klimos 2/4 {G M. Kopernika, Bilovec} 9 9 10 2 0 30
-5. Lukas Lansky 3/4 {G J. K. Tyla, Hradec Kralove} 3 5 10 0 0 18
-6. Pavel Motloch 6/6 {G P. Bezruce, Frydek-Mistek} 0 7 10 0 0 17
-7. Jakub Kaplan 3/4 {G J. K. Tyla, Hradec Kralove} 5 3 1 7 0 16
-8. Martin Pokorny 4/4 {G Arabska, Praha} 3 2 9 1 - 15
-9. Martin Milata 8/8 {G Hladnovska, Ostrava} 0 2 8 0 4 14
-10. Libor Peltan 7/8 {G Ceska, Ceske Budejovice} 0 0 10 3 - 13
-11. Ondrej Pialek 4/4 {G Masarykovo nam., Trebic} 7 1 1 0 3 12
-12. Petr Dluhos 8/8 {Mendelovo G, Opava} 0 0 10 0 1 11
-13. Petr Kratochvil 4/4 {G Sazavska, Svetla nad Sazavou} 1 1 6 1 - 9
-14. Pavel John 4/4 {G Arabska, Praha} 0 1 7 - 0 8
-15. Marek Scholle 8/8 {G Dasicka, Pardubice} 6 1 0 0 - 7
-16. Ondrej Bouda 8/8 {G Tr. Kpt. Jarose, Brno} 1 3 0 2 0 6
-17. Tomas Toufar 3/4 {G M. Kopernika, Bilovec} 0 3 0 2 0 5
-18.-19. Tomas Praslicak 7/8 {GOA Nadrazni, Sedlcany} 0 3 1 - 0 4
-18.-19. Martin Veskrna 4/4 {G Videnska, Brno} 0 3 1 - - 4
-20.-25. Jakub Balhar 6/6 {G J. Nerudy, Praha} 1 1 1 - 0 3
-20.-25. Roman Diba 3/4 {VOS a SPSE Plzen} 0 0 1 2 - 3
-20.-25. Filip Dechterenko 8/8 {G J. Masaryka, Jihlava} 0 1 1 0 1 3
-20.-25. Matej Korvas 8/8 {G J. Seiferta, Praha} 0 2 1 - 0 3
-20.-25. Tomas Kren 4/4 {G Ch. Dopplera, Praha} 0 3 0 - - 3
-20.-25. Michal Pavelcik 8/8 {G J. A. Komenskeho, Uhersky Brod} 0 0 0 0 3 3
-26.-28. Zuzana Buresova 8/8 {Masarykovo G, Plzen} 0 1 1 0 - 2
-26.-28. Michal Novak 8/8 {G Tr. Kpt. Jarose, Brno} 0 0 2 - - 2
-26.-28. Libor Plucnar 4/6 {G P. Bezruce, Frydek-Mistek} 0 1 1 0 - 2
-29. Roman Riha 7/8 {G Zlata stezka, Prachatice} 0 1 0 - 0 1
-30. Michal Minarik 4/4 {G F. X. Saldy, Liberec} 0 0 0 - - 0