<details class="red">
<summary>
**این سوال صرفاً برای آموزش کار با سیستم داوری است و هیچ تاثیری در نتیجهی مسابقه ندارد.**
</summary>
</details>
+ محدودیت زمان: ۱ ثانیه
+ محدودیت حافظه: ۲۵۶ مگابایت
----------
در این سوال به شما دو عدد صحیح مثل $a$ و $b$ داده میشود. از شما میخواهیم برنامهای بنویسید که مقدار $a$ و $b$ را دریافت کند و $a + b$ را چاپ کند.
# ورودی
در تنها سطر ورودی، دو عدد صحیح $a$ و $b$ که با یک فاصله از هم جدا شدهاند، داده میشود.
$$1 \leq a, b \leq 100$$
# خروجی
در تنها سطر خروجی، مقدار $a + b$ را چاپ کنید.
# مثالها
## ورودی نمونه ۱
```
3 5
```
## خروجی نمونه ۱
```
8
```
## ورودی نمونه ۲
```
1 1
```
## خروجی نمونه ۲
```
2
```
<details class="blue">
<summary>
**راهحل `Python 3.12`**
</summary>
```python code.py
a, b = map(int, input().split())
print(a + b)
```
</details>
### اشتباهات متداول
<details class="red">
<summary>
**چک کردن شرایط ورودی مسئله**
</summary>
نیازی نیست چک کنید شرایط گفته شده در ورودی برقرار است یا نه. توضیحات محدودیتها فقط برای آگاهی شما دربارهی تستها و محدودیتهای مسئله است و قطعاً در ورودیهای داده شده به برنامهی شما رعایت میشوند. پس نیازی نیست بنویسید:
```python
if 1 <= n <= 100:
# answer of problem
else:
# print('invalid input')
```
</details>
<details class="red">
<summary>
**ابتدا همهی ورودی را گرفتن و در نهایت همهی خروجی را چاپ کردن**
</summary>
شما میتوانید لابهلای دریافت ورودی، خروجی دهید. پس نیازی نیست ابتدا همهی ورودیها را دریافت کنید و در نهایت همهی خروجیها را چاپ کنید. مخصوصاً برای سوالاتی که باید به چندین سوال پاسخ دهید، میتوانید دو قسمت ورودی و خروجی را کاملاً مستقل در نظر بگیرید و مطمئن باشید تداخلی پیش نمیآید.
</details>
<details class="red">
<summary>
**چاپ کردن موارد اضافه برای دریافت ورودی**
</summary>
لطفاً از چاپ کردن موارد اضافه مثل `please enter a number` برای دریافت ورودی پرهیز کنید. برای مثال در زبان پایتون نباید بنویسید:
```python
input('please enter:')
```
</details>
<details class="red">
<summary>
**نحوهی دریافت ورودی و چاپ کردن خروجی**
</summary>
برای آشنایی بیشتر برای نحوهی دریافت ورودی و چاپ کردن خروجی این [لینک](https://quera.org/course/assignments/2693/problems/8774) را مطالعه کنید.
</details>
جمع دو عدد
+ محدودیت زمان: ۱ ثانیه
+ محدودیت حافظه: ۲۵۶ مگابایت
----------
در فایلهای شرکت شبکه الکترونیکی پرداخت کارت، که به نام شاپرک شناخته میشود، یک عبارت ریاضی نوشته شده بود. متأسفانه این عبارت بدون پرانتزگذاری بوده و به دلیل بهروزرسانی سیستمها، علامتهای ریاضی آن به $?$ تغییر کرده است.
اکنون با یک رشته به صورت $a?b?c$ مواجه هستیم که بهجای $a$، $b$ و $c$ اعداد طبیعی قرار گرفتهاند. هدف این است که به جای دو علامت $?$ در این عبارت، عملگرهای $\times$ یا $+$ را قرار دهیم و سپس با پرانتزگذاری مناسب، بیشترین مقدار ممکن از عبارت را به دست آوریم.
مقادیر $a$، $b$ و $c$ به شما داده میشود و باید برنامهای بنویسید که بیشترین مقدار ممکن برای این عبارت را محاسبه کند. برای درک بهتر خواستهی مسئله، توضیحات نمونه را مشاهده کنید.
# ورودی
در تنها سطر ورودی، یک رشته به صورت $a?b?c$ است که در آن به جای $a$، $b$ و $c$ اعداد طبیعی قرار دارند.
# خروجی
در تنها سطر خروجی، یک عدد صحیح برابر بیشترین مقدار ممکن برای عبارت داده شده را چاپ کنید.
# مثالها
## ورودی نمونه ۱
```
5?3?2
````
## خروجی نمونه ۱
```
30
````
برای عبارت $5?3?2$ اگر همهی $?$ را به $\times$ تغییر دهیم، حاصل عبارت $5 \times 3 \times 2 = 30$ میشود که این بیشترین مقدار ممکن است.
## ورودی نمونه ۲
```
14?100?1
````
## خروجی نمونه ۲
```
1414
````
برای عبارت $5?3?2$ اگر $?$ اول را به $\times$ و $?$ دوم را به $+$ تغییر دهیم، و عبارت
$14 \times (100 + 1)$
را به این صورت پرانتزگذاری کنیم، حاصل $1414$ میشود که این بیشترین مقدار ممکن است.
بیعملگر
+ محدودیت زمان: ۱ ثانیه
+ محدودیت حافظه: ۲۵۶ مگابایت
----------
شرکت شبکه الکترونیکی پرداخت کارت، که به نام شاپرک شناخته میشود، قصد دارد یک دیوار بزرگ از شرکت خود را رنگآمیزی کند. این دیوار از چندین ردیف آجری مربعی به اندازه $1 \times 1$ تشکیل شده است که به صورت عمودی روی هم قرار گرفتهاند.
![توضیح تصویر](https://quera.org/qbox/view/jKqG6gcEUi/B_1.png)
برای رنگآمیزی، یک نقاش حرفهای $n$ ردیف متوالی از این دیوار را انتخاب کرده و بازههایی از هر ردیف را رنگ کرده است. در ردیف $i$ام، نقاش آجرهای $l_i, l_i + 1, \dots, r_i - 1\,$ را رنگآمیزی کرده است.
![توضیح تصویر](https://quera.org/qbox/view/LC1Swz5HlU/B_2.png)
اکنون پس از پایان کار، نقاش میخواهد مرز بین قسمتهای رنگشده و رنگنشده را محاسبه کند تا بتواند حاشیههای این قسمتها را به دقت قلمگیری کند.
وظیفهی شما این است که با توجه به بازههای رنگشده، محیط کل قسمتهای رنگشده را محاسبه و گزارش کنید.
# ورودی
در سطر اول ورودی، یک عدد صحیح و مثبت $n$ داده میشود که تعداد ردیفهای رنگشده را نشان میدهد.
$$1 \leq n \leq 100$$
در $n$ سطر بعدی، در هر سطر دو عدد $l_i$ و $r_i$ داده میشود که ناحیهی رنگ شدهی ردیف $i$ام را نشان میدهد.
$$1 \leq l_i \lt r_i \leq 100$$
# خروجی
در تنها سطر خروجی، یک عدد صحیح که نشاندهندهی محیط کل قسمتهای رنگشده است، چاپ کنید.
# مثالها
## ورودی نمونه ۱
```
4
1 3
2 3
2 4
3 4
````
## خروجی نمونه ۱
```
14
````
![توضیح تصویر](https://quera.org/qbox/view/13VAAEasRy/B_3.png)
## ورودی نمونه ۲
```
3
2 5
3 6
1 2
````
## خروجی نمونه ۲
```
16
````
![توضیح تصویر](https://quera.org/qbox/view/K5TiNGKLEK/B_4.png)
دیوارهای شرکت
هلیا با مشکل کند بودن اجرای توابعش روبهرو شدهاست و میخواهد نتیجهی اجرای توابع را برای مدتی در حافظه نگه دارد تا هربار که تابع را با همان ورودیهای قبلی اجرا میکند، محاسبات تابع از نو اجرا نشوند. به او کمک کنید یک دکوراتور بنویسد که این کار را برای او انجام دهد.
دکوراتور شما (به نام `conditional_cache`) باید مدت زمان نگهداری نتایج، شرط نگهداری نتایج و بیشینهٔ حجم کش را ورودی بگیرد. در صورتی که شرط برقرار نبود، تابع موردنظر نباید اجرا شود. در غیر این صورت، اگر نتایج ذخیرهشده منقضی نشده بودند، مقدار ذخیرهشده برگردانده شود و در غیر اینصورت تابع اجرا شود و مقدار جدید آن برگردانده شود.
همچنین برای جلوگیری از دسترسی همزمان به مقادیر ذخیرهشده و ایجاد *Race Condition*، باید دسترسی به این مقادیر محدود شود و در هر لحظه تنها یک امکان دسترسی به آن وجود داشته باشد.
# نمونه
## اجرا
```python
import time
def is_positive(x):
return x > 0
@conditional_cache(<mark title="نگهداری کش به مدت ۵ ثانیه">expiry=5</mark>, condition=is_positive)
def compute_square(x):
print(f"Computing square of {x}")
return x * x
print(compute_square(3))
<mark title="۲ ثانیه از زمان ذخیرهسازی">time.sleep(2)</mark>
print(compute_square(3))
<mark title="۶ ثانیه از زمان ذخیرهسازی">time.sleep(4)</mark>
print(compute_square(3))
print(compute_square(-3))
```
## خروجی
```
Computing square of 3
9
9
Computing square of 3
9
None
```
# پروژهی اولیه
پروژهی اولیهی این سؤال را میتوانید از [این لینک](/contest/assignments/71157/download_problem_initial_project/251416/) دانلود کنید.
# نحوهی ارسال
این سؤال از نوع سؤالات تکفایل است. شما باید تابع `conditional_cache` موجود در فایل `main.py` را تکمیل و سپس این فایل را ارسال کنید.
کَش شرطی
برگزارکنندگان المپیک میخواهند سامانهای درست کنند که بهراحتی بتوانند اخبار برگزاری و وقایع هر رشته را به خبرگزاریهای مختلف ورزشی اطلاع دهند؛ به این صورت که یک سری پخشکنندهی اخبار دارند که وقایع را منتشر میکنند و یک سری دنبالکنندهی اخبار دارند که بهمحض دریافت خبر، آن را در خبرگزاریشان قرار میدهند. آنها از شما کمک خواستهاند تا در پیادهسازی این سامانه کمک کنید.
# پیادهسازی
شما باید سه کلاس `OlympicsServer`، `Publisher` و `Subscriber`را پیادهسازی کنید و همچنین توابع مشخصشدهی آنها را نیز پیادهسازی کنید. در صورت لزوم میتوانید توابع دیگری به کلاسهایتان اضافه کنید.
# تعاریف
### موضوع (topic)
هر خبری که منتشر میشود، یک موضوع دارد. بهطور مثال، `sports/basketball/groupstage` یک موضوع است؛ یعنی این خبر یک خبر ورزشی در رشتهی **بسکتبال** و در **دور گروهی** مسابقات است.
### پیام (message)
هر خبر یک پیام به همراه خود دارد. بهطور مثال، `Football match result: Team A won!` پیامی است که منتشرکننده آن را انتشار میدهد. پیامها بهصورت یک رشته (`string`) هستند.
### کیفیت سرویس (QoS)
کیفیت سرویس یعنی خبری که منتشر میشود، برای منتشرکننده چه میزان اهمیت دارد که به دست دنبالکنندهاش برسد. بهطور مثال، کیفیت سرویس سطح صفر یعنی برای منتشرکننده هیچ اهمیتی ندارد که پیامش به دنبال کنندهاش رسیده یا نه؛ یعنی پس از انتشار آن را فراموش میکند. ولی کیفیت سرویس سطح یک یعنی برای منتشر کننده مهم است که حداقل پیامش به یک مخاطبش رسیده باشد و رسیدن پیام را حداقل به یک دنبالکننده گارانتی میکند.
### منتشرکننده (publisher)
منتشرکننده یک کاربر *(client)* است که خبر را در یک موضوع مشخص، با یک پیام مشخص و یک کیفیت سرویس منتشر میکند. به طور مثال:
```python
client.publish('sports/handball', 'Match result: Team A won!', qos=1)
```
### دنبالکننده (subscriber)
دنبالکننده نیز یک کاربر است که یک موضوع مشخص را دنبال میکند و در صورت *match* شدن موضوعات، تابع `callback` را صدا میزند. بهطور مثال:
```python
client.subscribe('sports/football')
```
### تابع `callback`
تابع `callback` تابعی است که دنبالکننده پس از اینکه موضوع یک خبر با آن *match* میشود، آن تابع را صدا میزند. این تابع بهطور مثال میتواند پیام را چاپ کند یا در دیتابیس یا یک لیست اضافه کند. بهطور مثال این یک تابع `callback` است که پیام را صرفاً چاپ میکند:
```python
def message_callback(topic, message):
print(f"Received message on topic {topic}: {message}")
```
توجه داشته باشید که پیادهسازی این تابع را نیاز نیست انجام دهید و صرفا باید آن را هنگام *match* شدن تاپیک صدا بزنید.
### سطوح دسترسی موضوعات
- دسترسی صفرسطحی: در این دسترسی دنبالکنندگان باید کاملاً با تاپیک منطبق باشند. (بهطور مثال `/sports` به `sports/football` دسترسی ندارد.)
- دسترسی یکسطحی: در این دسترسی دنبالکنندگان تنها میتوانند در یک عمق با تاپیک اشتراک داشته باشند. (بهطور مثال `sports/+` به `sports/football` دسترسی دارد ولی به `sports/football/finals` دسترسی ندارد.)
- دسترسی چندسطحی: در این دسترسی دنبالکنندگان در چند عمق میتوانند با تاپیک اشتراک داشته باشند. (بهطور مثال `sports/#` به `sports/football` دسترسی دارد و همچنین به `sports/football/finals` نیز دسترسی دارد.)
### سرور
سرور به صورت چندنخی *(multi-thread)* کار میکند و هر خبر در یک نخ منتشر میشود. همچنین برای جلوگیری از *race condition* یک قفل *(lock)* در درون سرور قرار دارد که در جای لازم نخها را قفل میکند و همچنین دارای دو تابع اصلی `publish` و `subscribe` است. این دو تابع اکثر منطق برنامه را در خود جای میدهند و کلاس `Publisher` و `Subscriber` بهترتیب در خود `publish` و `subscribe` دارند که با استفاده از توابع متناظر خود در سرور عمل انتشار و دنبال کردن را انجام میدهند.
همچنین به این توجه داشته باشید که سرور باید برای دنبالکنندههایی که در حال حاضر آنلاین نیستند پیام را ذخیره کند. تاپیکها و پیامشان را به صورت آرایهای از تاپل و در فایل `messages.pkl` و بهصورت فایل `pickle` ذخیره کنید.
### کاربر (client)
این کلاس برای شما پیادهسازی شده است که صرفاً در توابع `publish` و `subscribe` با ساختن یک کلاس متناظر با آن و صدا کردن تابعش عمل انتشار و دنبال کردن خبر را انجام میدهد.
# مثال
## کد نمونه
```python
def message_callback(topic, message):
print(f"Received message on topic {topic}: {message}")
server = OlympicsServer()
client = Client(server)
client.subscribe('sports/#', message_callback)
client.publish('sports/football', 'Football match result: Team A won!', qos=1)
client.publish('sports/football/worldcup', 'World Cup result: Team Z won!', qos=1)
client.publish('sports/basketball/nba', 'NBA result: Team Y won!', qos=1)
```
## خروجی نمونه
```
Received message on topic sports/football: Football match result: Team A won!
Received message on topic sports/football/worldcup: World Cup result: Team Z won!
Received message on topic sports/basketball/nba: NBA result: Team Y won!
```
در اینجا دنبالکننده چون موضوع `sports/#` را دنبال کرده است، پس هر خبری که با `sports` شروع شود را دریافت و با صدا زدن تابع `callback` آن را چاپ میکند.
# پروژهی اولیه
پروژهی اولیهی این سؤال را میتوانید از [این لینک](/contest/assignments/71157/download_problem_initial_project/251417/) دانلود کنید.
# نحوهی ارسال
پس از تکمیل پروژه، فایلهای `client.py` و `server.py` را به صورت یک فایل `zip` را ارسال نمایید.
```
[your-zip-file-name].zip
├── client.py
└── server.py
```
اخبار المپیک
کوئرا تصمیم دارد تا برای کاربران فعال خود چالشی برگزار کند.
فرایند این چالش به این صورت است که هرروزه تعدادی مأموریت توسط کوئرا تعیین میشوند و کاربران با انجام دادن آنها، امتیاز و جایزه دریافت خواهند کرد. حال کوئرا برای پیادهسازی فرایند این چالش از شما میخواهد تا به کمکش بیایید.
# پروژهی اولیه
پروژهی اولیه را از [این لینک](/contest/assignments/71157/download_problem_initial_project/251415/) دانلود کنید. ساختار فایلهای این پروژه بهصورت زیر است.
```
quera_challenge/
├── manage.py
├── requirements.txt
├── app
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── migrations
│ │ ├── __init__.py
│ │ └── 0001_initial.py
│ ├── models
│ │ ├── __init__.py
│ │ ├── <mark class="yellow" title="این فایل را تغییر دهید"> > award.py < </mark>
│ │ ├── <mark class="yellow" title="این فایل را تغییر دهید"> > challenge.py < </mark>
│ │ └── <mark class="yellow" title="این فایل را تغییر دهید"> > user.py < </mark>
│ ├── <mark class="yellow" title="این فایل را تغییر دهید"> > serializers.py< </mark>
│ ├── <mark class="yellow" title="این فایل را تغییر دهید"> > signals.py < </mark>
│ ├── tests.py
│ ├── urls.py
│ └── <mark class="yellow" title="این فایل را تغییر دهید"> > views.py < </mark>
├── prj
│ ├── __init__.py
│ ├── asgi.py
│ ├── settings.py
│ ├── urls.py
│ ├── wsgi.py
│ └── auth.py
```
### پایگاهداده و مدلهایی که باید تکمیل شوند
**جایزه (`Award`)**
- **نام (رشته `name`)**: نام جایزه
- **شرح (رشته `description`)**: توضیحاتی درباره جایزه
**تراکنش جایزه (`AwardTransaction`)**
- **جایزه (کلید خارجی به `Award`)**: جایزه مرتبط با تراکنش
- **کاربر (کلید خارجی به `User`)**: کاربر دریافت کننده جایزه
- **تاریخ ایجاد (تاریخ و زمان `created_at`)**: تاریخ و زمان ایجاد تراکنش
**چالش (`Challenge`)**
- **عنوان (رشته `title`)**: عنوان چالش
- **شرح (رشته `description`)**: توضیحات چالش
- **امتیاز (عدد صحیح `point`)**: امتیاز چالش
- **جایزه (کلید خارجی به `Award`)**: جایزه مرتبط با چالش
**مورد چالش (`ChallengeItem`)**
- **چالش (کلید خارجی به `Challenge`)**: چالش مرتبط با مورد
- **عنوان (رشته `title`)**: عنوان مورد چالش
- **شرح (رشته `descritption`)**: توضیحات مورد چالش
- **تاریخ نمایش ( تاریخ و زمان `date_to_display`)**: تاریخی که چالش باید به کاربران نمایش داده شود.
**تراکنش چالش (`ChallengeTransaction`)**
- **مورد چالش (کلید خارجی به `ChallengeItem`)**: مورد چالش مرتبط با تراکنش
- **تاریخ ایجاد (تاریخ و زمان `created_at`)**: تاریخ و زمان ایجاد تراکنش
- **تاریخ بهروزرسانی (تاریخ و زمان `updated_at`)**: تاریخ و زمان بهروزرسانی تراکنش
- **کاربر (کلید خارجی به `User`)**: کاربر انجام دهنده تراکنش
**کاربر (`User`)**
- **نام کاربری (رشته)**: نام کاربری کاربر
- **ایمیل (رشته)**: ایمیل کاربر
- **رمز عبور (رشته)**: رمز عبور کاربر
- **نام (رشته)**: نام کوچک کاربر
- **نام خانوادگی (رشته)**: نام خانوادگی کاربر
- **تاریخ تولد (تاریخ)**: تاریخ تولد کاربر
- **امتیاز کسب شده (عدد صحیح مثبت `point_earned`)**: امتیاز کسب شده توسط کاربر
### توضیحات پیادهسازی پروژه
#### ۱. **لیست چالشها**
- **ویو**: `ChallengeListAPIView`
- **هدف**: این ویو به کاربران احرازهویتشده اجازه میدهد تا لیست تمام موارد چالش را مشاهده کنند.
- **نحوهی استفاده**: وقتی درخواست _GET_ به اندپوینت مربوط به `ChallengeListAPIView` ارسال شود، لیستی از چالشها بازگردانده میشود.
- **فیلد `is_done`**: بهطور داینامیک برای هر آیتم چالش تعیین میشود. اگر کاربر برای آیتم چالش خاصی، تراکنش داشته باشد، این فیلد `True` را نشان میدهد؛ در غیر این صورت، `False` است. این ویژگی به کاربران کمک میکند تا بهراحتی ببینند کدام چالشها را قبلاً تکمیل کردهاند و کدامها را هنوز باید انجام دهند.
- **تاریخ نمایش `jalali_date_to_display`**: تمامی چالشها براساس اینکه مقدار `date_to_display` آنها برابر تاریخ امروز باشد فیلتر و به کلاینت ارسال میشوند. و دقت کنید که این تاریخ با نام `jalali_date_to_display` **بهصورت شمسی** و فرمت `Y/m/d` در دیتا قرار میگیرد. **برای انجام اینکار حتما باید از کتابخانه `jdatetime` کمک بگیرید.**
#### ۲. **ایجاد تراکنش چالش**
- **ویو**: `CreateChallengeTransactionView`
- **هدف**: این ویو مسئول ایجاد تراکنش چالش است و به کاربران احرازهویتشده اجازه میدهد تا یک یا چند مورد از یک چالش را انجام دهند.
- **فرایند**:
1. **درخواست کاربر**: کاربر درخواست _POST_ با لیستی از `challenge_item_ids` در بدنهی درخواست ارسال میکند. فرمت کلی دیتای ارسالی بهصورت `{"challenge_item_ids": []}` است.
2. **اعتبارسنجی**: بررسی میکند که آیا `challenge_item_ids` ارائه شدهاست یا خیر. اگر ارائه نشده باشد، پاسخ `HTTP_400_BAD_REQUEST` برمیگرداند.
3. **اعتبارسنجی**: موارد `ChallengeItem` مربوط به `ID`های ارائهشده را بازیابی میکند و اطمینان حاصل میکند که کاربر قبلاً در این چالشها شرکت نکردهاست.
4. **ایجاد تراکنش**: برای هر مورد چالش معتبر، برای کاربر یک `ChallengeTransaction` ایجاد میشود.
5. **رسپانس**: اگر تراکنشها با موفقیت ایجاد شوند، پاسخ `HTTP_201_CREATED` بازگردانده میشود.
#### ۳. **مدیریت امتیاز و جوایز**
برنامه، پس از ذخیره شدن یک `ChallengeTransaction` بررسی میکند که آیا کاربر تمام موارد چالش مربوط به یک چالش خاص را تکمیل کردهاست یا خیر. در صورتی که کاربر **تمام** موارد یک چالش را گذرانده باشد به وی جایزه و امتیازی که در آبجکت آن چالش تعیین شده، تعلق خواهد گرفت.
اختصاص جایزه و امتیاز به این صورت است که یک `AwardTransaction` برای کاربر ایجاد میشود و امتیازهای کاربر **بهروزرسانی** میشود.
**نکته: استفاده از سیگنال در فرایند مدیریت امتیاز و اختصاص جوایز الزامیست.**
## نکات مهم
- شما تنها مجوز ایجاد تغییرات در فایلهای مدلها، `views.py`، `serializers.py` و `signals.py` را دارید و **تمامی تغییرات دیگر شما در فایلهای پروژه نادیده گرفته خواهند شد.**
- ویو `ChallengeListAPIView` باید **حداکثر دو کوئری** به پایگاه داده ارسال کند.
- سیستم احرازهویت در ویوها حتماً باید مبتنی بر **توکن _jwt_** باشد. در این خصوص بخشهای مرتبط با تنظیمات و `url`های آن از قبل پیادهسازی شدهاست.
- استفاده از سیگنال در فرایند مدیریت امتیاز و اختصاص جوایز الزامیست.
- برای اطمینان خاطر دربارهی فرایند تخصیص جوایز و امتیاز استفاده از `transaction.atomic` در سیگنال الزامیست.