+ محدودیت زمان: ۱ ثانیه
+ محدودیت حافظه: ۲۵۶ مگابایت
----------
گاوصندوقی $k$ تا چرخانه دارد که روی هرکدام، ترتیبی از اعداد ۱ تا ۹ قرار دارد. زیر هر چرخانه یک نشان وجود دارد که به یکی از اعداد چرخانه اشاره میکند و با چرخاندن چرخانه، این عدد تغییر میکند. حال یک عدد $k$ رقمی بعنوان رمز داده شده، حداقل تعداد چرخاندن چرخانهها برای این که اعداد اشاره شده برابر عدد رمز باشد چقدر است؟
# ورودی
در خط اول $k$ آمده است. در خط دوم رمز که یک رشتهی $k$ رقمی متشکل از ارقام ۱ تا ۹ است آمده است.
در خط $i$اُم از $k$ خط بعدی در هر خط ترتیب ارقام روی چرخانهی $i$اُم به ترتیب ساعتگرد آمده است. اولین رقم رقم اشاره شده است.
$$1 \le k \le 300\ 000$$
# خروجی
حداقل تعداد چرخاندن چرخانهها برای این که اعداد اشاره شده برابر عدد رمز باشد را چاپ کنید.
# مثال
## ورودی نمونه
```
3
123
241356789
987546231
956874231
```
## خروجی نمونه
```
7
```
**توضیح:**
میتوان با این چرخشها در ۷ حرکت به رمز هدف رسید:
- دو بار چرخاندن چرخانهی اول در جهت ساعتگرد
- سه بار چرخاندن چرخانهی دوم در جهت پادساعتگرد
- دو بار چرخاندن چرخانهی سوم در جهت پادساعتگرد
الگوریتمی - رمز
+ محدودیت زمان: ۱ ثانیه
+ محدودیت حافظه: ۲۵۶ مگابایت
----------
یک دنباله داریم. اختلاف هر دوعدد پشت سر هم (راستی منهای چپی!) را بدست میآوریم، در نتیجه یک دنبالهی دیگر به وجود میآید که طولش از دنبالهی اولیه یکی کمتر است. دوباره این کار را انجام میدهیم. این عمل را تکرار میکنیم تا دنبالهی نهایی تک عنصری شود. مقدار باقیماندهی آن عدد پس از تقسیم بر $10^9 + 7$ را خروجی دهید. دقت کنید که ممکن است عدد نهایی منفی شود، اما مقدار باقیماندهی عدد نهایی بر $10^9 + 7$ همیشه عددی نامنفی است.
# ورودی
در خط اول ورودی عدد $n$ آمده است. در خط بعد دنباله داده شده است.
$$1 \le n \le 300\ 000$$
اعداد دنباله، نامنفی و حداکثر $10^9$ هستند.
# خروجی
باقیماندهی عدد نهایی پس از انجام این پروسه بر $10^9 + 7$ را چاپ کنید.
# مثال
## ورودی نمونه ۱
```
4
1 2 3 4
```
## خروجی نمونه ۱
```
0
```
$$1, 2, 3, 4$$
$$1, 1, 1$$
$$0, 0$$
$$0$$
## ورودی نمونه ۲
```
2
1 2
```
## خروجی نمونه ۲
```
1
```
$$1, 2$$
$$1$$
## ورودی نمونه ۳
```
2
2 1
```
## خروجی نمونه ۳
```
1000000006
```
$$2, 1$$
$$-1$$
الگوریتمی - دنباله
* محدودیت زمان: ۱ ثانیه
* محدودیت حافظه: ۲۵۶ مگابایت
------------------------------
به تعداد $ n $ بادکنک در یک ردیف قرار دارند. رنگ بادکنک $ i $ام $a_i$ است. در ابتدای هر روز همزمان بادکنکهای هر دسته از بادکنکهای پشت سر هم و هم رنگ که شامل حداقل ۳ بادکنک باشد میترکند و در پایان هر روز بادکنکهای باقیمانده دوباره در یک ردیفِ پیوسته با همان ترتیب قرار میگیرند. میخواهیم بدانیم هر بادکنک در چه روزی میترکد.
# ورودی
در خط اول ورودی عدد $ n $ آمده است که تعداد بادکنکها را نشان میدهد.
$$1 \le n \le 300\ 000$$
$$1 \le a_i \le 10^9$$
# خروجی
به ازای هر بادکنک روز ترکیدنش را چاپ کنید، اگر یک بادکنک هیچگاه نمیترکد `-1` را چاپ کنید.
# مثال
## ورودی نمونه
```
7
1 2 2 3 3 3 2
```
## خروجی نمونه
```
-1 2 2 1 1 1 2
```
## ورودی نمونه
```
20
2 2 2 1 1 2 2 1 2 1 2 1 1 2 2 2 1 2 2 2
```
## خروجی نمونه
```
1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 2 2 1 1 1 2 1 1 1
```
الگوریتمی - بادکنکها
+ محدودیت زمان: ۴ ثانیه
+ محدودیت حافظه: ۲۵۶ مگابایت
----------
در یک جدول $n$ در $n$، روی هر خانه یک عدد نوشته شده. خانهی $(r, c)$ میخواهیم شروع کنیم و در جدول حرکت کنیم و در مسیر حرکت از بیشترین تعداد خانهی ممکن عبور کنیم (یمررر)، با رعایت کردن این شرایط:
1. در مسیر حرکت، عدد نوشته شده روی هر خانه باید اکیداً کمتر از عدد نوشته شده روی خانهی بعدی آن باشد.
2. در هر حرکت به سطر یا ستون مجاور حرکت میکنیم و حداقل ۳ خانه جابجا شویم. به بیان ریاضی، اگر در یک حرکت از $(r, c)$ به $(r2, c2)$ رفتیم، باید یکی از شرایط زیر برقرار باشد:
1. $|r2 - r| = 1$ و $|c2 - c| > 1$
2. $|c2 - c| = 1$ و $|r2 - r| > 1$
# ورودی
در خط اول ورودی عدد $n$ آمده است که اندازهی جدول را نشان میدهد. در خط بعد $r$ و $c$ آمده است. در $n$ خط بعدی جدول آمده است.
$$2 \le n \le 2\ 000$$
$$0 \le a_{i, j} \le 10^9$$
# خروجی
بیشترین تعداد خانهای که میتوان با رعایت شروط گفته شده از آنها یمررر کرد (عبور کرد) را چاپ کنید.
# زیرمسئلهها
| زیرمسئله | نمره | محدودیت |
|:-------:|:----------:|:-----------:|
|۱ | ۸۰ | $n \le 200$ |
|۲| ۱۰۰ | بدون محدودیت اضافی |
# مثال
## ورودی نمونه
```
4
2 1
5 2 5 5
1 2 5 4
5 2 5 5
5 3 4 5
```
## خروجی نمونه
```
3
```
مسیر مورد نظر به این شکل است:
$$(2, 1) - (4, 2) - (3, 4)$$
الگوریتمی - یمررر
**کد شما باید روی MySQL قابل اجرا باشد.**
پایگاه دادهای با Schema زیر در اختیار شما قرار گرفته است:
```
CREATE TABLE Person(
id VARCHAR(50) PRIMARY KEY,
name VARCHAR(50)
);
CREATE TABLE Coach(
id VARCHAR(50) PRIMARY KEY,
team VARCHAR(50) ,
FOREIGN KEY (id) REFERENCES Person(id)
);
CREATE TABLE Player(
id VARCHAR(50) PRIMARY KEY,
team VARCHAR(50) ,
age INT ,
FOREIGN KEY (id) REFERENCES Person(id)
);
CREATE TABLE Refree(
id VARCHAR(50) PRIMARY KEY,
fifa_grade VARCHAR(50) ,
FOREIGN KEY (id) REFERENCES Person(id)
);
CREATE TABLE Team(
name varchar(30) PRIMARY KEY
);
```
توجه کنید:
+ هر شخص میتواند داور،بازیکن و مربی باشد.
+ هر مربی میتواند بازیکن باشد یا بالعکس اما هیچ داوری مربی یا بازیکن نیست.
# مطلوبات
کوئریهای sql خواستهشده از شما موارد زیر است:
(توجه کنید که هر کوئری نمرهای جداگانه دارد و اگر کوئری یک قسمت را نتوانستید بزنید، کوئریهایی که حل کردید را بفرستید و قسمت آن کوئری را خالی بگذارید.)
1. در جدول `Person` افرادی وجود دارند که در هیچکدام از جداول `Refree` , `Player` , `Coach` وجود ندارند، اینگونه افراد را به جدول `Player` اضافه کنید و تیم همه آنها را `Chelsea` و سن همه آنها را `24` در نظر بگیرید.
2. `name` و `id` تمام مربیانی که بازیکن نیز هستند اما تیمی که مربیگری میکنند با تیمی که درآن بازی میکنند متفاوت است.
3. در تعریف بالا، ستون `Team` از جدول `Player` به جدول `Team` کلید خارجی ندارد، از شما میخواهیم کوئری بزنید که این کلید خارجی را ایجاد کند به گونه ای که پس از حذف تیمی از جدول `Team` تمام بازیکنانی که در آن تیم بازی میکردند نیز از جدول `Player` حذف شوند.
(راهنمایی: میتوانید از `ALTER TABLE` استفاده کنید)
# روش پیادهسازی
در یک فایل با نام `code.sql` کد خود را قرار دهید و آن را فشرده (`zip` ) کنید و در سایت بارگذاری نمایید.
کد شما باید به صورت زیر باشد(نام فایل zip مهم نیست).
```
-- Section1
your first query here
-- Section2
your second query here
-- Section3
your third query here
```
پایگاه داده - فیفا
**کد شما باید روی MySQL قابل اجرا باشد.**
در این سوال پایگاه داده یک شرکت حمل و نقل آنلاین که وظیفه سرویسدهی به تماشاچیان جامجهانی را دارد، در اختیار شما قرار گرفته است.
مقصد همه سفرهای این شرکت، حتما یک ورزشگاه است.
جداول این پایگاهداده به صورت زیر است:
جدول مسافر `Passenger`:
| اسم ستون | نوع | تعریف | ملاحظات|
|:------------------:|:----------:|:----------:|:-----------:|
| $name$ | $varchar$ | اسم مسافر | $primary key$ |
| $email$ | $varchar$ | ایمیل مسافر | یکتا |
| $balance$ | $int$ | اعتبار فعلی مسافر | $$ |
جدول راننده `Driver`:
| اسم ستون | نوع | تعریف | ملاحظات|
|:------------------:|:----------:|:----------:|:-----------:|
| $name$ | $varchar$ | اسم راننده | $primary key$ |
| $email$ | $varchar$ | ایمیل راننده | یکتا |
جدول ورزشگاه`Stadium`:
| اسم ستون | نوع | تعریف | ملاحظات|
|:------------------:|:----------:|:----------:|:-----------:|
| $name$ | $varchar$ | اسم ورزشگاه | $primary key$ |
| $address$ | $varchar$ | آدرس ورزشگاه | $$ |
| $capacity$ | $int$ | ظرفیت ورزشگاه | $$ |
جدول سفر`Travel`:
| اسم ستون | نوع | تعریف | ملاحظات|
|:------------------:|:----------:|:----------:|:-----------:|
| $id$ | $varchar$ | شناسه یکتای سفر | $primary key$ |
| $destination$ | $varchar$ | اسم ورزشگاه مقصد | کلید خارجی به جدول ورزشگاه |
| $driver\_name$ | $varchar$ | اسم راننده | کلید خارجی به جدول راننده |
| $passenger\_name$ | $varchar$ | اسم مسافر | کلید خارجی به جدول مسافر |
| $price$ | $int$ | هزینه سفر | عددی بین ۱ تا ۱۰۰ |
# مطلوبات
در این سوال از شما خواسته شده تا دستور ساخت`procedure` های زیر را پیاده سازی کنید و بفرستید.
(توجه کنید که هر `procedure` نمرهای جداگانه دارد و اگر `procedure` یک قسمت را نتوانستید بزنید، `procedure`هایی که حل کردید را بفرستید و قسمت آن `procedure` را خالی بگذارید.)
1. `procedure`ای که ظرفیت همه ورزشگاهها را ۱۰۰ واحد کم کند.
نام `procedure` شما باید `proc1` باشد و به طور مثال به شکل `CALL proc1();` فراخوانی میشود.
2. `procedure`ای که یک ورودی عددی میگیرد و ایمیل رانندههایی که بیش از این مقدار درآمد داشتهاند را برمیگرداند.
نام `procedure` شما باید `proc2` باشد و به طور مثال به شکل `CALL proc2(1000);` فراخوانی میشود.
2. `procedure` ای که دو ورودی میگیرد که اولی تعداد سفر و دومی ایمیل راننده تاکسی است و نام مسافرانی که بیشتر از عدد اول سفر با این راننده تاکسی داشتهاند را برمیگرداند.
نام `procedure` شما باید `proc3` باشد و به طور مثال به شکل `CALL proc3(2,'milad@example.com');` فراخوانی میشود
**توجه کنید که دستوراتی که شما میفرستید باید صرفا برای ساخت `procedure` باشد.**
***همچنین کدی که برای ما میفرستید نباید به هیچ وجه delimiter داشته باشد.***
# روش پیادهسازی
در یک فایل با نام `code.sql` کد خود را قرار دهید و آن را فشرده (`zip` ) کنید و در سایت بارگذاری نمایید.
کد شما باید به صورت زیر باشد(نام فایل zip مهم نیست).
```
-- Section1
your first query here
-- Section2
your second query here
-- Section3
your third query here
```
پایگاه داده - مسافر قزان
میخواهیم یک برنامه ساده برای مدیریت task بنویسیم.
برای این کار از شما میخواهیم یک اسکریپت Bash با نام `task.sh`
بنویسید. میتوانید با پیادهسازی بخشی از خواستهها،
بخشی از نمره را بگیرید.
# جزئیات
هر task یکی از ۳ اولویت پایین (L)، متوسط (M) و بالا (H) را دارد.
لیست task ها در فایل متنی `tasks.txt` ذخیره میشود.
ممکن است هنگام اجرا، این فایل وجود نداشته باشد. در این صورت
برنامه شما باید آن را ایجاد کند.
در هر سطر از این فایل یک task به این صورت ذخیره میشود:
ابتدا اولویت (یکی از حروف `H, M, L`)، سپس یک کاراکتر فاصله و سپس
عنوان task میآید.
شماره task ها بر اساس ترتیب آنها در این فایل مشخص میشود.
اولین سطر این فایل task شماره ۱ است.
یک مثال:
```
L Plan for summer
M Prepare presentation (important)
```
اسکریپت باید توانایی اجرای دستورات `add, list, done`
را به صورت زیر داشته باشد:
$ bash task.sh add <task_title>
$ bash task.sh list
$ bash task.sh done <task_number>
در ادامه توضیح دقیق هریک از این دستورات آمده است. در انتهای متن
نیز مثالی آمده که همه چیز را روشنتر میکند.
## دستور `add`
این دستور، task با عنوان دادهشده را به انتهای لیست اضافه میکند.
در صورتی که در انتهای عنوان، عبارت `(important)` یا `(very important)` باشد
(بدون توجه به بزرگی و کوچکی حروف)،
اولویت به ترتیب `M` و `H` خواهد بود. در غیر این صورت اولویت `L` است.
پس از اضافه کردن، باید پیام زیر در خروجی استاندارد نوشته شود:
Added task <task_number> with priority <task_priority>
## دستور `list`
این دستور لیست task ها را مانند مثالهای زیر نمایش میدهد.
```
$ bash task.sh list
1 * Plan for summer
2 ***** Fix bug #73 (very important)
3 *** Prepare presentation (Important)
```
```
$ bash task.sh list
1 * Write a letter
```
برای اولویت پایین، ۱ ستاره، برای اولویت متوسط ۳ ستاره و
برای اولویت بالا ۵ ستاره نمایش داده میشود.
به فاصلههای هر خط توجه کنید.
در صورت خالی بودن لیست، عبارت `No tasks found...`
را در خروجی استاندارد بنویسید.
## دستور `done`
این دستور task با شمارهی داده شده را حذف میکند و پیام زیر
را در خروجی استاندارد مینویسد:
Completed task <task_number>: <task_title>
## پیامهای خطا
در صورتی که دستوری به جز دستورهای بالا داده شد، برنامه باید با کد ۱
خارج شود و پیام خطای زیر را در stderr بنویسد:
[Error] Invalid command
همچنین اگر در ادامهی دستورهای `add` و `done` هیچ آرگومانی داده نشد،
برنامه باید با کد ۱ خارج شود و این پیام را در stderr بنویسد:
[Error] This command needs an argument
# مثال
نمونهای از عملکرد اسکریپت را در زیر میبینید:
```
$ bash task.sh hello
[Error] Invalid command
$ bash task.sh add
[Error] This command needs an argument
$ bash task.sh list
No tasks found...
$ bash task.sh add Plan for summer
Added task 1 with priority L
$ bash task.sh add Buy CLRS book
Added task 2 with priority L
$ bash task.sh add "Fix bug #73 (very important)"
Added task 3 with priority H
$ bash task.sh add Prepare presentation "(Important)"
Added task 4 with priority M
$ bash task.sh list
1 * Plan for summer
2 * Buy CLRS book
3 ***** Fix bug #73 (very important)
4 *** Prepare presentation (Important)
$ bash task.sh done 2
Completed task 2: Buy CLRS book
$ bash task.sh list
1 * Plan for summer
2 ***** Fix bug #73 (very important)
3 *** Prepare presentation (Important)
$ bash task.sh done 2
Completed task 2: Fix bug #73 (very important)
$ bash task.sh list
1 * Plan for summer
2 *** Prepare presentation (Important)
```
# نکات
- یک فایل Zip شامل اسکریپت `task.sh` را آپلود کنید.
لینوکس - مدیریت کارها
وبسرور
[Nginx](http://nginx.org/en/)
یکی از بهترین وبسرورهای متنباز با کارایی بالا و
امکانات زیاد است که اولین بار در سال ۲۰۰۴ منتشر شد.
این وبسرور به دلیل کارایی بالا، در بسیاری سایتهای پرترافیک
مانند Dropbox و Netflix استفاده شده است.
بله! وبسرور مورد استفاده Quera نیز Nginx است.
در این سؤال میخواهیم تنظیماتی در این وبسرور (در لینوکس) انجام دهیم.
# جزئیات
در سرور موردنظر فایل `nginx.conf` به صورت زیر تنظیم شده است:
```
worker_processes 1;
events {
worker_connections 200;
}
http {
# Basic Settings
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Logging Settings
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# Include Other Configs
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
```
از شما میخواهیم فایل `/etc/nginx/conf.d/mysite.conf` را ایجاد کنید
و طبق نیازمندیهای زیر تنظیمات مورد نیاز را در آن انجام دهید.
## نیازمندی اول
میخواهیم با رسیدن درخواست به `http://localhost/static/`، فایلهای
پوشه `/usr/share/nginx/static` سرو (serve) شود. مثلاً در صورتی که محتوای این
پوشه به شکل زیر باشد، با مراجعه به آدرس
`http://localhost/static/style/style.css`
باید فایل `style.css` ارسال شود.
/usr/share/nginx/static
├── image.jpg
├── style
│ ├── style.css
│ └── bootstrap.min.css
└── js
├── utils.js
└── bootstrap.min.js
## نیازمندی دوم
میخواهیم از بین فایلهای قسمت قبل، فایلهای CSS و JS با gzip فشرده شوند.
توجه کنید که سایر فایلها نباید فشرده شوند.
## نیازمندی سوم
میخواهیم هر درخواستی که به `http://localhost/blog` رسید به
`https://blog.quera.ir`
منتقل (redirect) شود.
چند مثال:
| آدرس درخواست | انتقال به |
| -------------- | ---------------- |
| `http://localhost/blog` | `https://blog.quera.ir` |
| `http://localhost/blog/` | `https://blog.quera.ir/` |
| `http://localhost/blog/category/feature/` | `https://blog.quera.ir/category/feature/` |
برای انتقال از کد
[۳۰۲](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/302)
یا
[۳۰۷](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/307)
(انتقال موقت) استفاده کنید.
## نیازمندی چهارم
میخواهیم فایلهای پوشه static (که در نیازمندی اول serve شد) تا ۲۴ ساعت
در مرورگر cache شوند.
## نیازمندی پنجم
میخواهیم درخواستهایی که از طرف curl ارسال میشود با پاسخ ۴۰۳ مواجه شود.
# نکات
- توجه کنید که در این مسئله امکان تغییر فایل اصلی
تنظیمات (`nginx.conf`) وجود ندارد.
- یک فایل Zip شامل فایل `mysite.conf` را آپلود کنید.
لینوکس - تنظیم Nginx
در یک اپ ورزشی، میخواهیم بروزرسانی مخصوص جام جهانی را منتشر کنیم. در این بروزرسانی (که البته قبل از شروع جام جهانی قرار بود منتشر شود!)، میخواهیم بتوانیم رتبهبندی تیمها در مرحله گروهی را شبیهسازی کنیم. ساختار اولیهی کدی که قرار است این شبیهسازی را انجام دهد به شما داده میشود و شما باید آن را تکمیل کنید.
# قوانین رتبهبندی گروهی جام جهانی
(منبع : [دیجیکالا مگ](https://www.digikala.com/mag/%D8%AC%D8%A7%D9%85-%D8%AC%D9%87%D8%A7%D9%86%DB%8C-%DA%AF%D8%B1%D9%88%D9%87-%D8%AA%D8%B3%D8%A7%D9%88%DB%8C-%D8%A7%D9%85%D8%AA%DB%8C%D8%A7%D8%B2%D8%A7%D8%AA-%D8%B5%D8%B9%D9%88%D8%AF/))
1. **بیشترین امتیازات**
به طور کلی، تیمی از یک گروه صعود پیدا میکند که امتیازات بیشتری نسبت به حریفان خود داشته باشد. این بند شامل جمع امتیازات برد (۳ امتیاز)، مساوی (۱ امتیاز) و باخت (۰ امتیاز) است.
2. **تفاضل گل**
از بین تیمهای همامتیاز، تیمی صعود میکند که تفاضل گل بیشتری داشته باشد. تفاضل گل یعنی اختلاف گلهای زده شده با خورده شدهی یک تیم.
3. **بیشترین گل زده**
بند سوم قانون فیفا بر این اساس است که تیمی که بیشترین گل زده را دارد مستحق صعود است. پس بین دو تیمی که امتیازشان برابر است و تفاضل گلشان نیز برابر است، تیمی که بیشتر گل زده رتبهی بهتری میگیرد.
4. **تعداد کارتهای هر تیم**
حالا نوبت به نحوهی بازی این تیمها میرسد. فیفا در این شرایط ویژه که امتیاز، تفاضل گل، و تعداد گل زده دو تیم برابر باشد، به تیمی اجازهی صعود میدهد که کمترین کارت را در بازیها گرفته باشد. البته هر کارت امتیازات منفی مشخصی دارد، ولی برای سادهتر شدن صورت این سوال فرض میکنیم تیمی که تعداد کمتری کارت در بازیها دریافت کرده در رتبهی بهتری قرار میگیرد.
اگر دو تیم در مرحلهای از بازی در هر ۴ مورد بالا مشابه هم باشند، فرض میکنیم رتبهشان برابر است. مثلاً در ابتدای جام که هیچ بازیای صورت نگرفته رتبهی همهی ۴ تیم در یک گروه برابر ۱ است، و امسال در گروه تیم ملی کشورمان پس از بازی پرتغال - اسپانیا و ایران - مراکش، ایران صدرنشین گروه بود و رتبهی هر دو پرتغال و اسپانیا برابر ۲ بود و مراکش که امتیازش از آنها کمتر بود، رتبهی ۴ را داشت.
----------
# فایلهای اولیه:
فایل مربوط به خود را دانلود کرده و محتوای آنرا ببینید:
**فایل مربوط به زبان Java : ** [QorldCup.java](http://bayanbox.ir/download/6006581750868782787/QorldCup.java)
**فایل مربوط به زبان Python3: ** [QorldCup.py](http://bayanbox.ir/download/6542306507967080048/QorldCup.py)
**فایل مربوط به زبان ++C : ** [qorld_cup.cpp](http://bayanbox.ir/download/4611160333708180502/qorld-cup.cpp)
**فایل مربوط به زبان #C (با کامپایلر #Mono C):** [QurldCup.cs](https://www.dropbox.com/s/eluogpqqaby5gdh/QorldCup.cs?)
----------
# ساختار کد
پروژهی اولیه شامل کلاس *qorld_cup* است که در آن توابع زیر را باید تکمیل کنید. شما میتوانید در این کلاس هر تعداد متغیر اضافی که خواستید تعریف کنید، اما متغیر خارج از کلاس بصورت *global* نباید تعریف کنید. (در صورت تعریف کردن ممکن است نمرهای دریافت نکنید.)
1. تابع *initial* که لیست نام کوتاه ۳۲ کشور حاضر در این دوره از جام جهانی را ورودی میگیرد، که ۴ تای اول در گروه ۱، ۴ تای دوم در گروه ۲، و همینطور تا ۴ تای هشتم که در گروه ۸ هستند. نام کوتاه هر کشور یک رشته از حروف بزرگ انگلیسی حداکثر ۳ حرفی است. مثلا ایران `IRN` است و چین `CHN` است.
2. تابع *add_game_result* که ۶ پارامتر ورودی میگیرد: به ازای هر یک از ۲ تیم: نام کوتاه تیم، تعداد گلهای زده در این بازی، و تعداد کارتهای دریافت کرده در این بازی.
3. تابع *get_score* که نام کوتاه یک تیم را ورودی میگیرد و امتیازش را برمیگرداند.
4. تابع *get_rank* که نام کوتاه یک تیم را ورودی میگیرد و رتبهاش در گروه خودش را برمیگرداند.
----------
# نحوهی تست کردن کد
میتوانید کد خود را بوسیلهی *stdin* و *stdout* در کنسول تست کنید. پس از اجرا کردن کد، ابتدا تعداد دستوراتی که میخواهید به برنامه بدهید را بنویسید. سپس نام کوتاه ۳۲ تیم را وارد کنید تا به تابع *initial* داده شود، و سپس میتوانید به شکل زیر با توابع ارتباط داشته باشید:
1. ورودی دادن به تابع *add_game_result*:
```
add_game_result TeamName1 Score1 #Cards1 TeamName2 Score2 #Cards2
```
2. ورودی دادن به تابع *get_score*:
```
get_score TeamName
```
3. ورودی دادن به تابع *get_rank*:
```
get_rank TeamName
```
و بعد از ورودی دادن به توابع *get_rank* و *get_score*، خروجی تابع را برنامه در *stdout* مینویسد.
----------
# مثال
فرض کنید ورودی `initial` مانند جام جهانی امسال بوده باشد. این ۱۰ تعامل با کد نمایانگر ۲ بازی ابتدایی در گروه تیم ملی کشورمان میباشد، و وضعیت گروه پس از این ۲ بازی را نشان میدهد:
```
10
IRN MAR SPN PRT
A B C D
E F G H
I J K L
M N O P
Q R S T
U V W X
AA BB CC DD
add_game_result IRN 1 3 MAR 0 1
add_game_result PRT 3 1 SPN 3 1
get_score IRN
get_score SPN
get_score PRT
get_score MAR
get_rank IRN
get_rank SPN
get_rank PRT
get_rank MAR
```
و خروجیهای برنامه چنین میشود:
```
3
1
1
0
1
2
2
4
```
----------
# فرمت فایل ارسالی برای داوری
فایل ابتدایی مربوطه را دریافت کرده و توابع گفته شده را تکمیل کرده و ارسال کنید. **تنها کلاس مربوطه را تغییر دهید!**
پروژهای - جام کهانی
برای یک فروشگاه موبایل، با کمک شما قصد داریم برنامه مدیریت این فروشگاه را طراحی کنیم.
کالاهای این فروشگاه موبایل های با برند Apple ،htc و Samsung هستند.
----------
# فایل های اولیه
**در صورت سوال نام توابع برای python توضیح داده شده برای بقیه زبانها نیز مشابه میباشد.**
ابتدا فایل مربوط به خود را دانلود کرده و محتوای آن را ببینید (همچنین ورودی ها و خروجی های توابع) :
**فایلهای مربوط به زبان python : ** [دریافت](http://bayanbox.ir/download/6672722507619215381/initial-python-2.zip)
**فایلهای مربوط به زبان java: ** [دریافت](http://bayanbox.ir/download/5624849933454820033/initial-java-2.zip)
**فایلهای مربوط به زبان C#: ** [دریافت](http://bayanbox.ir/download/991252906425990967/MobileStore-csharp-2.zip)
----------
# امکانات فروشگاه
+ در بعضی از ماه های سال این فروشگاه بر روی کل محصولات خود درصدی تخفیف میدهد.
+ **علاوه بر تخفیف کلی** هر کدام از برند ها هم تخفیف مخصوص خود را دارند.
+ این فروشگاه بعد از فروختن بعضی از گوشی ها، درصورتی که مشتری یکسری شرایط را داشته باشد آنها را پس میگیرد.
----------
# ساختار کلاس ها
برای هر کدام از کلاسها تعدادی از تابعهایی که نیاز به توضیح داشته باشند توضیح آمده است.
**ویژگی های کلاس Mobile :** نام، قیمت
+ `can_purchase`: چک میکند که آیا کاربر مشخص شده در ماه مشخص شده قادر به خرید این موبایل هست یا خیر. توجه کنید اگر این تابع `True` برگرداند یعنی امکان خرید این محصول توسط کاربر وجود دارد و بلافاصله میتوان عملیات خرید را انجام داد.
+ `reverse_payment_price`: قیمتی که قرار است در حالت بازگشت محصول برگردانده شود را برمیگرداند. این تابع توسط کلاس `Shop` فراخوانی میشود.
+ `get_final_price`: قیمت موبایل را با احتساب تخفیفهای مختلف محاسبه کرده، برمیگرداند. توجه کنید اگر دو تخفیف به یک محصول تعلق بگیرد تخفیفها در هم ضرب میشوند مثلا جنس ۱۰۰۰ تومانی پس از دو تخفیف ۱۰ درصدی ۸۱۰ تومان خواهد بود. تست ها طوری طراحی میشوند که مقادیر پس از تخفیف اعشاری نباشند.
**ویژگی های کلاس Shop :** موبایل های موجود فروشگاه، درآمد فروشگاه (موجودی)
+ `get_available_mobile_count`: تعداد mobile هایی که فروشگاه دارد را برمیگرداند.
+ `get_available_mobile_of_type`: تعداد mobile هایی از نوع ورودی که در فروشگاه وجود دارد را برمیگرداند.
+ `add_number_of_mobile`: به تعداد ورودی به موجودی موبایلی که در ورودی آمده است به فروشگاه اضافه میکند.
+ `remove_one_mobile`: یکی از موجودی موبایلهای از نوع ورودی فروشگاه کم میکند.
+ `buy_mobile_request`: موبایل مورد نظر به کاربر فروخته میشود. باید موجودی کاربر کم شده، موبایل مورد نظر از لیست دارایی های فروشگاه حذف شود و به لیست موبایل های خریده شده کاربر اضافه شود. اگر درست انجام شود `True` وگرنه `False` برمیگرداند.
+ `giveback_request`: فروشگاه موبایل مورد نظر را پس میگیرد. موبایل بازگشته شده باید از موبایل های خریداری شده کاربر حذف شده و به موجودی فروشگاه اضافه شود. همچنین موجود (پول) کاربر و فروشگاه نیز باید به درستی تغییر کند. اگر درست انجام شود `True` وگرنه `False` برمیگرداند.
+ `get_instance`: کلاس Shop باید singleton باشد و تنها نمونهی آن، از طریق این تابع بازگردانده میشود.
**ویژگی های کلاس User :** نام، موبایل های خریده شده، سن، مقدار پول
+ `get_mobile_count`: تعداد موبایلهای فرد را برمیگرداند.
+ `get_mobiles`: یک dict برمیگرداند که کلید آن موبایل و مقدار هر کدام تعداد از این نوع موبایل است.
+ `purchase`: درخواست خرید موبایل مورد نظر را به فروشگاه میدهد.
+ `refund`: مبلغ مشخص شده را به کاربر بازمیگرداند.
+ `has_mobile_in_month`: اگر کاربر اکنون موبایلی از نوع ورودی دارد که در ماه ورودی خریده باشد مقدار `True` وگرنه `False` برمیگرداند.
----------
## شرایط تخفیف کلی فروشگاه
در سه ماه تابستان این فروشگاه ۱۰ درصد به مشتریان تخفیف میدهد.
----------
## گوشی های htc
+ اگر مشتری اکنون گوشی اپل نداشته باشد این فروشگاه گوشی htc را پس میگیرد و تمام پول مشتری را پس میدهد.
+ اگر مشتری اکنون هیچ گوشی ای نداشته باشد و الان برندی که میخرد htc باشد این فروشگاه 15 درصد به او تخفیف میدهد.
+ اگر کلمه `iran` در اسم فرد باشد (به همین صورت و با حروف کوچک) این شرکت به او گوشی نمیفروشد. مثلا اگر کسی اسمش `moiraniom` باشد این شرکت به او گوشی نمیفروشد. چون شاید با گوشی اورانیم غنی کند!
## گوشی های Samsung
+ اگر تمام گوشی های خریده شده مشتری از سامسونگ باشد این فروشگاه گوشی Samsung را پس میگیرد و تمام پول مشتری را پس میدهد. توجه کندی که باید در لحظه پس دادن همه گوشیها از نوع سامسونگ باشند.
+ این فروشگاه در ماه های اسفند و فروردین ۱۰ درصد به مشتری تخفیف میدهد.
## گوشی های Apple
+ این برند در هر صورتی گوشی مشتری را پس میگیرد ولی ۹۰ درصد پول آن را به مشتری برمیگرداند.
+ اگر مشتری تا به حال گوشی Samsung و htc نخریده باشد این فروشگاه به او 10 درصد تخفیف میدهد.
+ اگر سن مشتری کوچکتر مساوی 15 سال باشد این فروشگاه به او گوشی Apple نمیفروشد!!!
----------
# نکات و راهنمایی ها
+ هنگام فروش موبایل باید حواستان به موجودی حساب فروشگاه و موجودی حساب مشتری باشد!
+ برای راحتی مسئله گوشی دست دوم نداریم و گوشی ای که پس گرفته میشود فرقی با گوشی ای تا به حال فروخته شده ندارد.
+ فروشگاه وقتی گوشی را پس میگیرد به اندازه قیمتی که مشتری داده به مشتری پول میدهد مثلا اگر قیمت گوشی ۲۰۰۰ (دلار!) باشد و مشتری با تخفیف آن را ۱۶۰۰ خریده هنگام پس دادن ۱۶۰۰ دریافت میکند (البته برای گوشی های Apple نود درصد قیمت یعنی ۱۴۴۰ دریافت میکند)
+ مثال برای تخفیف دومرحله ای این گونه است: فرض کنید در ماه تابستان قرار داریم و همچنین مشتری تا به حال گوشی samsung و htc نخریده و قصد خرید apple دارد؛ در این صورت فروشگاه باید یکبار ۱۰ درصد و بار دیگر از قیمت بدست آمده ۱۰ درصد تخفیف دهد. مثلا جنس ۱۰۰۰ تومانی پس از دو تخفیف ۱۰ درصدی ۸۱۰ تومان خواهد بود. تست ها طوری طراحی میشوند که مقادیر پس از تخفیف اعشاری نباشند.
+ نکته مهم آنکه هرگاه فرد بخواهد گوشی را پس بدهد با وضعیت فعلی او گوشی پس گرفته میشود یعنی مثلا برای گوشیهای سامسونگ در لحظه پس دادن باید تمام گوشیهای فرد از نوع سامسونگ باشد.
# نکات پیاده سازی
+ کلاس Shop باید singleton باشد و تنها نمونهی آن، از طریق متد get_instance قابل دسترس باشد.
+ تمامی توابع مشخص شده در کلاس ها باید پیاده سازی شوند.
+ برای پیاده سازی این سوال لازم است خودتان فیلد هایی را به کلاس های کاربر و فروشگاه اضافه کنید. نام این فیلد ها و نوعشان مهم نیست. تنها برنامه در مجموع باید کارا باشد.
+ نام موبایل مشخص کننده مدل آن است. برند موبایل را نوع کلاس های فرزند مشخص میکنند.
# نکات ارسال
توجه داشته باشید که تمام فایلها باید در ریشه فایل zip باشند برای c# بایستی `MobileStore.csproj` در ریشه فایل zip قرار گیرد. یعنی پس از باز کردن فایل zip تمامی فایل کلاسها قابل مشاهده باشد.
پروژهای - موبایل استور!
میخواهیم به کمک شما قسمت سرور یک پیام رسان را طراحی کنیم.
این سرور قابلیت عضو شدن (یا register)، و برای افرادی که عضو شده اند قابلیت ورود (یا login) و برای افرادی که وارد شده قابلیت خروج (یا logout) را داشته باشد. همچنین این سرور قابلیت ارسال پیام از یک کاربر به کاربر دیگر را نیز دارد و همچنین برای هر کاربر قابلیت دریافت همه پیام های ارسالی را داشته باشد.
برای برقراری ارتباط کلاینت ها پیام ها را به `port` شماره `1234` میفرستند و سرور باید به این port گوش بدهد تا کلاینت ها به آن متصل شوند.
بعد از برقراری ارتباط کلاینت با سرور هر بار که کلاینت یک درخواست میکند، سرور نیز یک یا چند پیام (بسته به نوع پیام فرستاده شده) ارسال میکند.
منظور از یک پیام یک رشته از هر کاراکتری (حتی فاصله) است.
----------
# درخواست register
این پیام حاوی دو رشته است که به ترتیب نشان دهنده نام کاربری (یا username) و کلمه عبور (یا password) است. درصورت عدم وجود کاربری با این نام کاربری، این سرور یک حساب کاربری جدید ایجاد میکند و پیام `"you registered successfully"` را به کلایت ارسال میکند.
فرمت درخواست:
`register username password`
مثال درخواست:
`register mohammad pa3word`
در صورت وجود کاربری با نام کاربری مشابه، این درخواست انجام نمیشود و سرور پیام `"this username registered"` را به کلاینت ارسال میکند.
تضمین میشود دو رشته نام کاربری یا username و رمزعبور یا password شامل حداقل 3 کاراکتر و حداکثر 10 کاراکتر از حروف کوچک و بزرگ انگلیسی و ارقام باشد.
----------
# درخواست login
این پیام حاوی دو رشته است که به ترتیب نشان دهنده نام کاربری (یا username) و رمز عبور (یا password) است. در صورت ثبت نام (یا register) بودن این نام کاربری و مطابق بودن رمزعبور با آن، سرور باید یک رشته به نام session که تاکنون برای هیچ کاربری ارسال نشده است را ایجاد و برای کلاینت ارسال کند. توجه کنید که رشته session باید شامل 30 کاراکتر از ارقام باشد.
فرمت درخواست:
`login username password`
مثال درخواست:
`login mohammad pa3word`
در صورت عدم تطابق نام کاربری با رمزعبور یا عدم ثبت نام این نام کاربری سرور پیام `"wrong username or password"` را به کلاینت ارسال میکند.
----------
# درخواست logout
این پیام حاوی یک رشته است که نشان دهنده session است. در صورت وجود کاربری با آن session فعال (یعنی این session را login کرده و هنوز logout نکرده است.) این session را از مجموعه session های فعال این کاربر خارج میکند و سرور پیام `"your session logout successfully"` را به کلاینت ارسال میکند.
فرمت درخواست:
`logout session`
مثال درخواست:
`logout 987654321098765432109876543210`
در صورت عدم وجود چنین session سرور پیام `"invalid session"` را به کلاینت ارسال میکند.
----------
# درخواست send
این پیام حاوی سه رشته session و username و message است و در صورت معتبر session و وجود یک کاربر با نام کاربری username ، پیام message را به همه session های فعال آن کاربر ارسال کند.
فرمت درخواست:
`send session_of_sender contact_username message`
مثال درخواست:
`send 987654321098765432109876543210 ali salam baraadar`
فرمت پیامی که باید برای کلاینت ارسال کنید:
`sender: message`
مثال فرمت پیام:
`ali: salam baraadar`
در صورت معتبر نبودن session سرور پیام `"invalid session"` را به کلاینت اسال میکند.
در صورت عدم وجود کاربردی با نام کاربری username باید پیام `"your contact did not register"` توسط سرور ارسال شود.
و در صورت موفقیت آمیز بودن ارسال پیام `"your message send successfully"` ارسال شود.
----------
# درخواست receive
این پیام حاوی یک رشته session است و در صورت معتبر بودن session، ابتدا تعداد پیام هایی که به این کاربر ارسال شده ولی این session هنوز دریافت نکرده است را به او ارسال میکند. سپس به همان تعداد پیام برای کلاینت ارسال می شود.
فرمت این درخواست:
`receive 987654321098765432109876543210`
فرمت پیام هایی که برای کلاینت ارسال میشود:
`number_of_message$sender: message_1$sender: message_2`
مثال پیام هایی که برای کلاینت ارسال می شود:
`2$mahdi: salam$mahdi: khubi?`
(هر رشته بین `$` یک پیام ارسال شده است.)
توجه کنید حتی در صورت وجود یک پیام هم باید تعداد پیام ها ارسال شود.
در صورت معتبر نبودن session سرور پیام `"invalid session"` را به کلاینت اسال میکند.
----------
# محدودیت
تضمین می شود حداکثر 20 کاربر به سرور متصل خواهد شد و حداکثر 50 درخواست داده میشود و طول پیام ها حداکثر 20 کاراکتر است.
----------
# نحوه ارسال
اگر به زبان python میفرستید تعدادی فایل که فایل اصلی که اجرا میشود `server.py` است. برای این کار پروژه خود را zip کرده به صورتی که `server.py` در ریشه فایل zip قرار گیرد.
اگر به زبان java میفرستید تعدادی فایل که فایل اصلی که اجرا میشود `server.java` است. برای این کار پروژه خود را zip کرده به صورتی که `server.java` در ریشه فایل zip قرار گیرد.
اگر به زبان c++ میفرستید تعدادی فایل که فایل اصلی که اجرا میشود `server.cpp` است. برای این کار پروژه خود را zip کرده به صورتی که `server.cpp` در ریشه فایل zip قرار گیرد. توجه کنید که قبل از اجرا دستور `make` صدا زده میشود و فایل `server.cpp` باید به فایل اجرایی `server` تبدیل شود.
اگر به زبان c# میفرستید یک پروژه باید داشته باشیم که نام این پروژه `server` است این پروژه را به صورتی zip کنید که فایل `server.csproj` در ریشه فایل zip قرار گیرد.
فایل zip را ارسال کنید.