/* holidays-validator.c

   validates the answer to the holidays problem */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

//MODIFY THIS TO MATCH THE STRING IN reject.ini
#define WRONG_OUTPUT "Wrong Answer"

static int m, n, k;
static int **lifts, **slopes;
static char strdesc[900];

long mylrint(double d)
{
  return (long)floor(d + 0.5);
}

void *malloc2(int size)
{
  void *v = malloc(size);
  if (!v) 
  {
    perror("malloc()");
    abort();
  }
  return v;
}

/* read one case from the standard input */
void read_input(FILE *f)
{
  int i, j, a, b;

  fscanf(f, "%d%d%d", &n, &m, &k);
  lifts = (int **) malloc2((n + 1) * sizeof(int *));
  slopes = (int **) malloc2((n + 1) * sizeof(int *));

  for (i = 1; i <= n; i++)
  {
    lifts[i] = (int *) malloc2((n + 1) * sizeof(int));
    slopes[i] = (int *) malloc2((n + 1) * sizeof(int));

    for (j = 1; j <= n; j++)
      lifts[i][j] = slopes[i][j] = -1;
  }

  for (i = 0; i < m; i++)
  {
    fscanf(f, "%d%d", &a, &b);
    fscanf(f, "%d", &slopes[a][b]);
  }

  for (i = 0; i < k; i++)
  {
    fscanf(f, "%d%d", &a, &b);
    fscanf(f, "%d", &lifts[b][a]);
  }
}

/* release memory allocated for one case */
void free_graphs()
{
  int i;
 

  for (i = 1; i <= n; i++)
  {
    free(lifts[i]);
    free(slopes[i]);
  }
  free(lifts);
  free(slopes);
}

void generate_result(FILE *f, char *str1, char *resfile, char *str2)
{
  fprintf(f, "<?xml version=\"1.0\"?>\n");
  fprintf(f, "<result outcome=\"%s\" security=\"%s\"> %s </result>\n", str1, resfile, str2);
  fclose(f);
}

int check_answer(FILE *outfile, FILE *ansfile)
{
  char ln[10000];
  double rans, rout;
  long lifttime, slopetime;
  char *p;
  int i, first, last;
  static const char *whitespace = "\x0d\x0a \t";

  fgets(ln, 9999, ansfile);
  if (!fgets(ln, 9999, outfile))
  {
    sprintf(strdesc, "output file does not contain all cases");
    return 0;
  }
  fscanf(ansfile, "%lf\n", &rans);
  if (!fscanf(outfile, "%lf\n", &rout))
  {
    sprintf(strdesc, "output file does not contain all cases");
    return 0;
  }

  if (rout != rans) 
  {
    sprintf(strdesc, "the ratio does not match");
    return 0;
  }

  /* remove trailing whitespace */
  i = strlen(ln);
  while (strpbrk(ln + i - 1, whitespace)) ln[--i] = '\0';

  /* parse the path in the string ln */
  p = strtok(ln, whitespace);
  lifttime = 0; slopetime = 0; 
  i = 0;
  while (p) {
    last = i;
    sscanf(p, "%d", &i);
    if (last == 0) first = i;
    else if (lifts[i][last] >= 0) lifttime += lifts[i][last];
    else break;
    p = strtok(0, whitespace);
  } 
  while (p) {
    sscanf(p, "%d", &i);
    if (slopes[last][i] >= 0 ) slopetime += slopes[last][i];
    else break; 
    p = strtok(0, whitespace);
    last = i;
  }
  if (p) {
    sprintf(strdesc, "trailing numbers, first=%d, last=%d", first, i);
    return 0;  /* trailing numbers */
  }
  if (i != first) 
  {
    sprintf(strdesc, "did not return to the beginning, first=%d, last=%d", first, i);
    return 0;  /* did not return to the beginning */
  }
  if (abs(mylrint(1000.0 * (double)slopetime/(double)lifttime) / 1000.0 - rout) > 0.0001)
  {
    sprintf(strdesc, "incorrect ratio, first=%d, last=%d, your specified ratio=%lf, your real ratio=%lf, correct ratio=%lf", first, i, rout, mylrint(1000.0 * (double)slopetime/(double)lifttime) / 1000.0 , rans);
    return 0;  /* incorrect ratio */
  }
  return 1;  /* path ok */
}

int main(int argc, char **argv)
{
  FILE *infile, *outfile, *ansfile, *resfile;
  int i, ncases;
  char string2[1000];

  resfile = stdin;

  infile = fopen(argv[1], "r");
  if (!infile) {
    perror("holidays-validator: Error opening input data file:");
    generate_result(resfile, "fatal", argv[4], "error openning input data file");
    return 1;
  }
    
  outfile = fopen(argv[2], "r");
  if (!outfile) {
    perror("holidays-validator: Error opening output data file:");
    generate_result(resfile, "fatal", argv[4], "error openning output data file");
    return 1;
  }

  ansfile = fopen(argv[3], "r");
  if (!ansfile) {
    perror("holidays-validator: Error opening answers file:");
    generate_result(resfile, "fatal", argv[4], "error openning answers file");
    return 1;
  }

  fscanf(infile, "%d", &ncases);
  for (i = 1; i <= ncases; i++)
  {
    read_input(infile);
    if (!check_answer(outfile, ansfile))
    {
      sprintf(string2, "case %d [indexed from 1], %s", i, strdesc);
      generate_result(resfile, WRONG_OUTPUT, argv[4], string2);
      return 1;
    }
  }

  //generate_result(resfile, "accepted", argv[4], "accepted");
  generate_result(resfile, "Yes", argv[4], "Yes");
  return 0;
}

