Соревнования по программированию

Добавление задачи в систему SPOJ. Примеры программ судей (Judges)

Программа судья (Judge) для задачи состоит из одного файла и может быть написана на любом языке поддерживаемым SPOJ. Большинство программ судей в системе написаны на C\C++. Ниже будут приведены примеры, которые написаны на языке программирования Cи. Стандартный проект судьи для запуска и проверки на локальной машине состоит из 3ёх файлов: spoj.c, spoj.h и judge.c. Первые два файла предоставлены разработчиками системы и выглядят следующим образом:

SPOJ.C

#include <spoj.h> #include <errno.h> #include <unistd.h> #include <string.h> #include <stdlib.h> /* file handles */ FILE *spoj_p_in, /* problem's input */ *spoj_p_out, /* problem's output */ *spoj_t_out, /* tested program's output */ *spoj_t_src, /* tested program's source */ *spoj_score, /* score for the program, for challenge problems */ *spoj_u_info, /* additional info - psetter only */ *spoj_p_info; /* additional info - psetter and solution's owner */ #define __WARN_IF_NULL(x) if (errno=0, (x)==NULL)\ fprintf(stderr, "warning: \"" #x "\" -> %s\n", strerror(errno)) #define __BUF_SIZE 1024*1024 static char buffer[__BUF_SIZE+1]; static void spoj_finalize(); void spoj_init() { __WARN_IF_NULL(spoj_p_in = fdopen(SPOJ_P_IN_FD,"r")); __WARN_IF_NULL(spoj_p_out = fdopen(SPOJ_P_OUT_FD,"r")); __WARN_IF_NULL(spoj_t_out = fdopen(SPOJ_T_OUT_FD,"r")); __WARN_IF_NULL(spoj_t_src = fdopen(SPOJ_T_SRC_FD,"r")); __WARN_IF_NULL(spoj_score = fdopen(SPOJ_SCORE_FD,"w")); __WARN_IF_NULL(spoj_p_info = fdopen(SPOJ_P_INFO_FD,"w")); __WARN_IF_NULL(spoj_u_info = fdopen(SPOJ_U_INFO_FD,"w")); atexit(spoj_finalize); } static void spoj_finalize() { fclose(spoj_p_in); fclose(spoj_p_out); fclose(spoj_t_out); fclose(spoj_t_src); fclose(spoj_score); fclose(spoj_p_info); fclose(spoj_u_info); } unsigned spoj_file_length(FILE *file) { int fd = fileno(file); unsigned size = 0; unsigned temp; while ((temp = read(fd, buffer, __BUF_SIZE))>0) size+=temp; return size; } void __spoj_assert_fail(char *s, int r) { if (!r) { fprintf(spoj_p_info, "%s\n", s); exit(SPOJ_RV_NEGATIVE); } }

Для отладки тестирующей программы на локальной машине рекомендуется слегка изменить функции spoj_init() и spoj_finalize() для своих нужд. Доступные потоки данных:
*spoj_p_in - входные данные для задачи
*spoj_p_out - выходные данные для задачи (эталонные выходные данные)
*spoj_t_out - выходные данные сгенерированные тестируемой программой (то, что вывела программа пользователя)
*spoj_t_src - исходный код тестируемой программы (то, что прислал пользователь через форму)
*spoj_score - счет (количество баллов) пользователя
*spoj_p_info - дополнительная информация для автора задачи (рекомендую пользоваться этой возможностью. Вы можете проверить какие то промежуточные данные в течение соревнования. Вся информация из этого потока видна только автору задачи).

SPOJ.H

#ifdef __cplusplus extern "C" { #endif #ifndef __SPOJ_H__ #define __SPOJ_H__ #include <stdio.h> /* return values */ #define SPOJ_RV_POSITIVE 0 #define SPOJ_RV_NEGATIVE 1 #define SPOJ_RV_IE 2 /* descriptor numbers */ #define SPOJ_P_IN_FD 0 #define SPOJ_P_OUT_FD 4 #define SPOJ_T_OUT_FD 3 #define SPOJ_T_SRC_FD 5 #define SPOJ_SCORE_FD 1 #define SPOJ_P_INFO_FD 6 #define SPOJ_U_INFO_FD 7 /* file handles */ extern FILE *spoj_p_in, /* problem's input */ *spoj_p_out, /* problem's output */ *spoj_t_out, /* tested program's output */ *spoj_t_src, /* tested program's source */ *spoj_score, /* score for the program, for challenge problems */ *spoj_p_info, /* additional info - problemsetter only */ *spoj_u_info; /* additional info - psetter and solution's owner */ /* must be called before using other functions or variables */ void spoj_init(); /* spoj "files" are really pipes, this is the recommended way to tell size */ /* the file's data is unaccessible later, so use it only if it doesn't matter */ unsigned spoj_file_length(FILE*); /* use spoj_assert()! */ /* usual assert() from assert.h will cause "judge's internal error" in the future! */ #define spoj_assert(x) __spoj_assert_fail(__FILE__ ":" __spoj_xstr(__LINE__) ": SPOJ assertion `" #x "' failed.", x) #define __spoj_str(x) #x #define __spoj_xstr(x) __spoj_str(x) void __spoj_assert_fail(char*, int); #endif #ifdef __cplusplus } #endif

Третий файл вам надо будет написать самому. Ниже приведены примеры судей для реальных задач из системы:

JUDGE.C (для задачи "Цифры Пи")

#include <cstdio> #include <spoj.h> #define LIMIT 1000000 #define mMin(a, b) (((a)<(b))?(a):(b)) char s[LIMIT], o[LIMIT]; int main() { int i; spoj_init(); int lo = fread (o, 1, LIMIT, spoj_t_out); int ls = fread (s, 1, LIMIT, spoj_p_out); while (lo>0 && o[lo-1]=='\n') lo--; while (ls>0 && s[ls-1]=='\n') ls--; spoj_assert(lo > 0); for (i = 0; i < mMin(lo, ls); i++) if (s[i]!=o[i]) break; fprintf (spoj_score, "%d\n", i); return 0; }

JUDGE.C (для задачи "Size Contest")

#include "spoj.h" #include <stdio.h> #include <string.h> int main() { int a, b, i; int score; int c; spoj_init(); /* Check for AC */ fscanf(spoj_p_out, "%d", &a); fscanf(spoj_t_out, "%d", &b); if (b != a) return 1; score = 0; for (i = 0; i < 10003; i++) { c = fgetc(spoj_t_src); if (c > 32) score++; } fprintf (spoj_score, "%d\n", score); return 0; }

Ненулевой код возврата из программы судьи интерпретируется системой SPOJ, как Wrong Answer.

<-- Часть 1. Структура и описание всех полей формы

Часть 3. Описание программы судьи высшего уровня (Master Judge) -->