cms-dev / cms

Contest Management System
http://cms-dev.github.io/
GNU Affero General Public License v3.0
877 stars 357 forks source link

Problems with Communicaion Task type #359

Closed ashikoff closed 9 years ago

ashikoff commented 9 years ago

Hello there. I've started to dig in CMS recently (want to implement it in all inside Bulgarian informatics contests). One of main reasons to do it is the support of communication task types. I'm trying to configure a task which uses communication between contestant's solution and judge's manager program. The task is - bookshelf from Russian Olympiad in Informatics 2014. I've created a manager (which reads the input and sends the input to the fifo) also created a stub.cpp which gets the input from the manager and implements special function ask(x,y) used by the contestant to send requests to the manager during solving. Here is the manager source:

#include <cstdio>
#include <cstdlib>
#include <string>

long long n, m;
int p[100005], start[100005], ans[100005];
long long InvCount;
int swaps;

int main(int argc, char **argv) {

    int i, j, x, y, t;
    char st[10];
    FILE *fin, *fout, *fifo_in, *fifo_out;
    fin = fopen("input.txt", "r");
    fout = fopen("output.txt", "w");
    fifo_in = fopen(argv[1], "w");
    fifo_out = fopen(argv[2], "r");

    fscanf(fin, "%lld", &n);
    for (i=0; i < n; i++)
    {
        fscanf(fin, "%d", &p[i]);
        start[i] = p[i];
    }

    InvCount = 0;
    for (i = 0; i < n; i++)
        for (j = i+1; j < n; j++)
            if (p[i] > p[j])
                InvCount++;

    fprintf(fifo_in, "%lld %lld\n", n, InvCount);
    fflush(fifo_in);
    swaps = 0;
    while (true)
    {
        fscanf(fifo_out, "%s", st);
        if (st == "answer")
        {
            for (i=0; i<n; i++)
            {
                fscanf(fifo_out, "%d", &ans[i]);
                if (ans[i] != start[i])
                {
                    fprintf(stderr, "Wrong number on position %d!\n", i);
                    printf("0.0\n");
                    break;
                }
            }

            for (i=0; i<n; i++)
                fprintf(fout, "%d", ans[i]);
            fprintf(fout, "\n");
            fflush(fout);

            fprintf(stderr, "Number of queries:  %d!\n", swaps);
            printf("1.0\n");
            break;
        }

        if (st == "swap")
        {
            fscanf(fifo_out, "%d %d", &x, &y);
            x--; y--;
            swaps++;
            if ((x==y) || (x < 0) || (y < 0) || (x >= n) || (y >= n))
            {
                fprintf(stderr, "Invalid swap query %d %d!\n", x, y);
                printf("0.0\n");
                break;
            }

            if (x >  y)
            {
                t = x; x=y; y=t;
            }

            for (int i = x + 1; i < y; i++)
            {
                if (p[x] > p[i]) InvCount--;
                if (p[x] < p[i]) InvCount++;
                if (p[i] > p[y]) InvCount--;
                if (p[i] < p[y]) InvCount++;
            }
            fprintf(fifo_in, "%lld\n", InvCount);
            fflush(fifo_in);
        }
    }
    fclose(fin);
    fclose(fout);
    fclose(fifo_in);
    fclose(fifo_out);

}

The idea is simple - the manager sends the required number to the fifo and then awaits requests. When answer is received it checks if it is the correct one and gives results (0 or 1) to the standard output.

The stub is even simpler:

#include <stdio.h>
#include <cstdlib>

FILE *fifo_in, *fifo_out;

long long n, inv;
long long answer[100005];

void bookshelf(long long n, long long inv, long long answer[]);

int ask(long long x, long long y)
{
  long long newInv;

  fprintf(fifo_out, "%lld %lld", x, y);
  fflush(fifo_out);
  fscanf(fifo_in, "%lld", &newInv);
  return newInv;
}

int main(int argc, char **argv)
{

  fifo_in = fopen(argv[2], "r");
  fifo_out = fopen(argv[1], "w");

  int i;

  fscanf(fifo_in, "%lld %lld", &n, &inv);
  fprintf(stderr, "%lld %lld", n, inv);
  fflush(stderr);
  bookshelf(n, inv, answer);
  fprintf(fifo_out, "answer");
  for (int i = 0; i < n; i++)
    fprintf(fifo_out, " %lld", answer[i]);
  fprintf(fifo_out, "\n");
  fflush(fifo_out);

  fclose(fifo_in);
  fclose(fifo_out);

  return 0;
}

It receives the input from the manager, calls users function and then prints the answer to the manager. It also provides function Ask to contestant in order to make possible communication between contestant's program and judge's manager program.

The submissions compiles fine within the stub and then evaluates without errors. However there are no point awarded and when I click "details"for the evaluation all test cases got result "N/A". I see how the worker is grading each one of the 5 testcases I've configured...

Help please with resolving this situation. Anyone experienced with communication task type feel free to mail me - anton@opcosys.com or contact me on skype - a_shikoff. Thank you in advance!

stefano-maggiolo commented 9 years ago

Did you manage to find the problem? Otherwise I can take a look into this, but I'd like to have some input/output example too :)

ashikoff commented 9 years ago

We've managed to isolate the problem. The problem is not with the communication task type - we configured simple task and everything was fine. Seems the issue arises when we try to write a function in the stup.cpp which the competitor should call in his function. Then the grader just stops at the call to that function and nothing happens (the sandbox cuts the process when the time limit has passed). So the correct question here is - is it possible (and if it is how) to supply an author function in the stub which can be called by the contestant function. I'll open another issue with that one because it is different than the statement in the title here :)

stefano-maggiolo commented 9 years ago

Sorry for the long time, I answered to this in #361