مهدی برنامهنویس خفنی است و پروژههای خفنی انجام میدهد. دوستان او از نحوهی پیادهسازی سیستم داوری کوئرا در عجباند، اما مهدی به آنها میگوید پیادهسازی جاجی مثل کوئرا عین آب خوردنه! مهدی میخواهد این موضوع را به دوستانش اثبات کند، اما در حال حاضر مشغول انجام پروژههای خفن است و فرصت انجام این کار را ندارد.
از شما میخواهیم این موضوع را به دوستان مهدی اثبات کنید.
جزئیات پروژه
پروژهی اولیه را از این لینک دانلود کنید.
ساختار فایلها
judge-api
├── app
│ ├── Console
│ ├── Exceptions
│ ├── Http
│ ├── Jobs
│ │ └── JudgeSubmission.php
│ ├── Judge
│ │ ├── InputOutputJudge.php
│ │ ├── Judge.php
│ │ └── JudgeResult.php
│ ├── Models
│ │ ├── Submission.php
│ │ └── User.php
│ └── Providers
├── bootstrap
├── config
├── database
├── public
├── resources
├── routes
├── storage
├── tests
├── README.md
├── artisan
├── composer.json
├── composer.lock
├── package.json
├── phpunit.xml
├── server.php
└── webpack.mix.js
راهاندازی پروژه
برای اجرای پروژه، باید php و composer را از قبل نصب کرده باشید.
- ابتدا پروژهی اولیه را دانلود و از حالت فشرده خارج کنید.
- دستور
composer installرا در پوشهی اصلی پروژه برای نصب نیازمندیها اجرا کنید. - برای اجرای تستهای نمونه، میتوانید از دستور
php artisan testاستفاده کنید.
همانطور که میدانید، سیستم داوری کوئرا (در حالت ورودی/خروجی) به اینصورت است که یک رشته بهعنوان stdin به یک برنامه داده میشود و در انتها، نتیجهی اجرای برنامه دریافت میشود.
مدلها
علاوه بر مدل پیشفرض User، مدلی با نام Submission در برنامه تعریف شده است. مایگریشنها و روابط بین مدلها از قبل برقرار شدهاند. با مطالعهی این موارد، باید با ساختار مدلهای برنامه آشنا شوید.
کلاس App\Judge\JudgeResult
از این کلاس برای نگهداری اطلاعات مربوط به داوری ارسالها استفاده میشود.
class JudgeResult
{
const SUCCESS = 0;
const TIME_LIMIT_EXCEEDED = 1;
const RUNTIME_ERROR = 2;
const SYNTAX_ERROR = 3;
public function __construct(
public string $stderr,
public string $stdout,
public int $status
) {}
}
اینترفیس App\Judge\Judge
این اینترفیس شامل یک متد با نام run است که پارامترهای آن بهصورت زیر هستند:
code: متن کدtimeLimit: محدودیت زمان برحسب میلیثانیهstdin: ورودی برنامه
interface Judge
{
public function run(string $code, int $timeLimit, string $stdin = ''): JudgeResult;
}
کلاس App\Judge\InputOutputJudge
این کلاس یک پیادهسازی از اینترفیس App\Judge\Judge است که باید کدهای PHP را اجرا کند و نتیجه را در قالب آبجکتی از کلاس App\Judge\JudgeResult برگرداند. مقدار پراپرتیهای آبجکت خروجی باید مطابق توضیحات زیر باشد:
- اگر کد سینتکس ارور داشته باشد، مقدار
statusباید برابر باJudgeResult::SYNTAX_ERRORباشد و مقدارstderrوstdoutباید برابر با رشتهی خالی باشد. - اگر اجرای برنامه در زمان مشخصشده خاتمه یابد و دادهای توسط برنامه در
stderrنوشته نشده باشد، مقدارstatusباید برابر باJudgeResult::SUCCESSباشد، مقدارstderrباید برابر با رشتهی خالی باشد و مقدارstdoutباید برابر با خروجی برنامه باشد. - اگر اجرای برنامه در زمان مشخصشده خاتمه یابد و دادهای توسط برنامه در
stderrنوشته شده باشد، مقدارstatusباید برابر باJudgeResult::RUNTIME_ERRORباشد، مقدارstderrباید برابر با محتویاتstderrباشد و مقدارstdoutباید برابر با رشتهی خالی باشد. - اگر اجرای برنامه در زمان مشخصشده خاتمه نیابد، فارغ از این که دادهای توسط در
stdoutیاstderrنوشته شده باشد، مقدارstatusباید برابر باJudgeResult::TIME_LIMIT_EXCEEDEDباشد و مقدارstderrوstdoutباید برابر با رشتهی خالی باشد.
جاب JudgeSubmission
این جاب شناسهی یک Submission را دریافت میکند. وظیفهی این جاب، داوری یک Submission است. متد handle این جاب را طوری پیادهسازی کنید که ابتدا مقدار ستون status مربوط به Submission را به judging تغییر دهد، سپس داوری را با استفاده از کلاس InputOutputJudge انجام دهد و در نهایت، status، stderr و stdout را مقداردهی کند و تغییرات را در دیتابیس ذخیره کند.
احراز هویت
پکیج laravel/sanctum در این پروژه نصب شده و از آن میتوانید برای احراز هویت استفاده کنید. توکنهای احراز هویت هنگام داوری توسط این پکیج تولید میشوند. هنگام ارسال درخواستها، مقدار header برابر با یک توکن Bearer قرار داده میشود و مقدار هدر Accept برابر با application/json خواهد بود.
endpoint های API
در این برنامه باید سه endpoiont بهصورت زیر تعریف کنید. همهی این endpoint باید نیازمند احراز هویت کاربر باشند. در غیر اینصورت، کد پاسخ 401 باید برگردانده شود:
GET /api/submissions: با ارسال این درخواست، کاربر باید لیست ارسالهایش را در قالب یک آرایه ببیند (باید کالکشنی ازSubmissionها را به JSON تبدیل کرده و آن را برگردانید). کد پاسخ باید برابر با200باشد.POST /api/submissions: با ارسال این درخواست، باید یکSubmissionبهSubmissionهای کاربر اضافه شود. تضمین میشود که مقادیرcode،time_limitوstdinدر بدنهی درخواست موجود خواهند بود. همچنین، جابJudgeSubmissionمربوط بهSubmissionارسالشده باید به صفی با عنوانjudgeاضافه شود. کد پاسخ باید برابر با201باشد.GET /api/submissions/{submission_id}: با ارسال این درخواست، کاربر باید اطلاعاتSubmissionبا شناسهیsubmission_idرا مشاهده کند (باید آبجکتSubmissionرا به JSON تبدیل کرده و آن را برگردانید). اگرSubmissionوجود نداشته باشد یا متعلق به کاربر نباشد، کد پاسخ باید برابر با404باشد. در غیر اینصورت، کد پاسخ باید برابر با200باشد.
نکات
- داوری در یک سیستم لینوکسی صورت میگیرد. بنابراین میتوانید از امکانات خط فرمان آن استفاده کنید.
- شما تنها مجاز به اعمال تغییرات در پوشههای
appوroutesهستید (میتوانید فایلهای جدیدی نیز در این پوشهها ایجاد کنید).
آنچه باید آپلود کنید
پس از پیادهسازی موارد خواستهشده، پوشههای app و routes را زیپ کرده و آپلود کنید.
ارسال پاسخ برای این سؤال