مهدی برنامهنویس خفنی است و پروژههای خفنی انجام میدهد. دوستان او از نحوهی پیادهسازی سیستم داوری کوئرا در عجباند، اما مهدی به آنها میگوید پیادهسازی جاجی مثل کوئرا عین آب خوردنه! مهدی میخواهد این موضوع را به دوستانش اثبات کند، اما در حال حاضر مشغول انجام پروژههای خفن است و فرصت انجام این کار را ندارد.
از شما میخواهیم این موضوع را به دوستان مهدی اثبات کنید.
جزئیات پروژه
پروژهی اولیه را از این لینک دانلود کنید.
ساختار فایلها
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
خواهد بود.
%align_right_start%
endpoint های API
%align_end%
در این برنامه باید سه 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
را زیپ کرده و آپلود کنید.
ارسال پاسخ برای این سؤال