#!/usr/bin/perl

use Getopt::Std;
use strict;
our($opt_S, $opt_L);
getopts('SL') or die "bad opts\n";
if ($opt_S && $opt_L) { 
    die "-S and -L are incompatible\n";
}
my $short_program = $opt_S != 0;

local $/ = "";
my $line_no = 1;
my $n_judges = 9;
my @marknames = qw(technical presentation);
my (@who, @judges, @ord, @placements, @maj_judges, @final_place);
my %tied;

COMPETITOR:
while (<>) {
#  print "Paragraph $.\n";
  my $n_lines = (tr/\n//);
#  print "... has $n_lines lines.\n";
  chomp;
  my @lines = grep !/^\s*#/, grep /\S/, split /\n/;
  unless (@lines == 3) {
    my $fl = substr($lines[0], 0, 20);
    warn "Paragraph #$. '$fl' has the wrong number of lines at line $line_no\n";
    next COMPETITOR;
  }

  my ($who, $tech_l, $pres_l) = @lines;
  $who =~ s/\b(and|[&+])\b/\&/g;
  $who =~ s/\s+[&+]\s+/\&/g;
  my $cid = @who;
  my @marks = map [split /\s+/, $_], $tech_l, $pres_l;

  for (0,1) {
    unless (@{$marks[$_]} == $n_judges) {
      my $n = @{$marks[$_]};
      warn "Competitor $who has $n $marknames[$_] marks; s/b $n_judges.\n";
      next COMPETITOR;
    }
  }

  push @who, $who;
  for (0 .. $n_judges-1) {
    my $t = round($marks[0][$_]);
    my $p = round($marks[1][$_]);
    push @{$judges[$_]}, 
      [$cid, $t, $p, $t+$p];
  }
#  print "Bottom of loop $.\n";
}

# Assign ordinals for each judge
my $tb = $short_program ? 1 : 2;
my $i = 0;
for my $j (@judges) {
  ++$i;
    my @p = sort {
      if ($i == 2) { print "comparing $who[$a->[0]] $who[$b->[0]] $a->[3] $b->[3]\n" }
	$b->[3] <=> $a->[3]
     || (do{print ("Score from judge $i tied (@$a) (@$b)\n") ; 
            $b->[$tb] <=> $a->[$tb]})
     } @$j;
    for (0 .. $#$j) {
	$p[$_][4] = $_+1;
	push @{$ord[$p[$_][0]]}, $_+1;
    }
}

# $ord[3] is now the array of 9 ordinals for competitor #3
for (0 .. $#ord) {
  die "Competitor #$_ has wrong number of ordinals.\n"
    unless @{$ord[$_]} == $n_judges;
}

# Now find the majorities
# @ord[3] is the ordinals for competitor #3
for my $cid (0 .. $#ord) {      # loop over competitors
  my $maj_place ;
  my @m_judges;
  my $ords = $ord[$cid];
  for my $place (1 .. @ord) {   # up to number of competitors
    @m_judges = ();
    for my $jno (0 .. $n_judges-1) {
      my $ord = $ords->[$jno];
      push @m_judges, $jno if $ord <= $place;
    }
    $maj_place = $place, last if @m_judges > $n_judges / 2;
  }
  die "Couldn't find majority placement for competitor $cid $who[$cid]\n"
    unless $maj_place;
  push @{$placements[$maj_place]}, $cid;
  $maj_judges[$cid] = \@m_judges;
}

print "Computed majority placements.\n";

my $true_place = 1;
for my $place (@placements) {
  next unless defined $place && @$place > 0;
  if (@$place == 1) {
    $final_place[$place->[0]] = $true_place++;
  } else {  # break ties
    my @tied = map [scalar(@{$maj_judges[$_]}),
                    tom($_),
                    to($_),
                    $_
                   ], @$place;
    @tied = sort
      { $b->[0] <=> $a->[0]
     || $a->[1] <=> $b->[1]
     || $a->[2] <=> $b->[2]
     || ($tied{"$a->[3],$b->[3]"} = 1, 0)
      } @tied;
    for (@tied) {
      $final_place[$_->[3]] = $true_place++;
    }
  }
}

for (sort {$final_place[$a] <=> $final_place[$b]} 0 .. $#final_place) {
  my $who = $who[$_];
  my @ordinals = @{$ord[$_]};
  my $place = $final_place[$_];
  printf "%20.20s ", $who;
  for (@ordinals) { printf "%2d ", $_ }
  printf "--- %3d\n", $place;
}
  


exit ;

################################################################

sub tom {
  my $cid = shift();
  my $tom = 0;
  for my $j (@{$maj_judges[$cid]}) {
    $tom += $judges[$j][$cid][4];
  }
  print "TOM for $cid [$who[$cid]] = $tom\n";
  $tom;
}

sub to {
  my $cid = shift();
  my $to = 0;
  for my $o (@{$ord[$cid]}) {
    $to += $o;
  }
  print "TO for $cid [$who[$cid]] = $to\n";
  $to;
}

sub round {
  int ($_[0] * 10 + .5)
}
