علی که خیلی به کسب و کار اهمیت میدهد به تازگی در دو بانک کار میکند. او باید روزهای زوج به بانک «پرسپولیس» و روزهای فرد به بانک «بهمن» برود.
میدانیم روزهای «شنبه»، «دوشنبه» و «چهارشنبه» یک روز زوج و روزهای «یکشنبه»، «سهشنبه» و «پنجشنبه» یک روز فرد است. همچنین روز «جمعه» تعطیل است.
به شما یک رشته داده میشود که یکی از روزهای هفته را نشان میدهد. از شما میخواهیم نام بانکی که علی باید در آن روز، آنجا کار کند را چاپ کنید یا اینکه اعلام کنید این روز تعطیل است.
shanbe
) یک روز زوج است، پس باید در بانک پرسپولیس (perspolis
) کار کند.yekshanbe
) یک روز فرد است، پس باید در بانک بهمن (bahman
) کار کند.doshanbe
) یک روز زوج است، پس باید در بانک پرسپولیس (perspolis
) کار کند.seshanbe
) یک روز فرد است، پس باید در بانک بهمن (bahman
) کار کند.chaharshanbe
) یک روز زوج است، پس باید در بانک پرسپولیس (perspolis
) کار کند.panjshanbe
) یک روز فرد است، پس باید در بانک بهمن (bahman
) کار کند.jome
) یک روز تعطیل (tatil
) است و لازم نیست جایی کار کند.در تنها سطر ورودی یکی از ۷ رشته shanbe
، yekshanbe
، doshanbe
، seshanbe
، chaharshanbe
، panjshanbe
یا jome
داده میشود.
در تنها سطر خروجی در صورتی که روز کار در بانک پرسپولیس است perspolis
و در صورتی که روز کار در بانک بهمن است bahman
و در صورت تعطیل بودن tatil
را چاپ کنید.
شنبه یک روز زوج است، پس باید در بانک «پرسپولیس» کار کند.
سهشنبه یک روز فرد است، پس باید در بانک «بهمن» کار کند.
جمعه یک روز تعطیل است و نیازی نیست جایی کار کند.
علی به سه کشور امارات، فرانسه و آمریکا سفر کرده و به تازگی به ایران برگشته است.
او برای هزینههای این سفر از دوستش محمد ریال قرض گرفته بود و حالا که از سفر برگشته میخواهد این قرض را به محمد پس بدهد.
علی با خود اسکناس یک درهمی از امارات، اسکناس یک یورویی از فرانسه و اسکناس یک دلاری از آمریکا آورده است.
میدانیم در روز پرداخت، قیمت یک درهم ریال، قیمت یک یورو ریال و قیمت یک دلار ریال است.
علی میخواهد بداند به چند طریق میتواند اسکناس یک درهمی، اسکناس یک یورویی، اسکناس یک دلاری به محمد بدهد به طوری که ارزش آنها دقیقاً ریال باشد.
به عبارت دیگر تعداد راههای مشخص کردن سه عدد صحیح ، و به طوری که: چقدر است؟
در سطر اول ورودی تنها عدد صحیح آمده که نشاندهنده مبلغی (به ریال) است که علی باید به محمد پرداخت کند. در سطر دوم ورودی سه عدد صحیح ، و با فاصله آمده که به ترتیب نشاندهنده تعداد اسکانسهای درهم، یورو و دلار است. در سطر سوم ورودی سه عدد صحیح ، و با فاصله آمده که به ترتیب نشاندهنده قیمت یک درهم، یورو و دلار بر حسب ریال است.
در تنها سطر خروجی یک عدد صحیح که نشاندهنده پاسخ مسئله یعنی تعداد روشهای پرداخت ریال به محمد است را چاپ کنید.
دو روش برای پرداخت ممکن است:
چهار روش برای پرداخت ممکن است:
مجموع ارزش پولی که علی دارد کمتر از پولی است که باید به محمد بدهد. پس هیچ راهی برای پرداخت ندارد.
محمدرضا و تیمش مشغول طراحی سامانهای برای مدیریت کیف پول دیجیتال بهنام دیجیوالِت هستند. در نسخهی اولیهی این سامانه قرار است قابلیتهای زیر وجود داشته باشد:
تیم محمدرضا ساختار برنامه را طراحی کردهاند و از شما میخواهند تا پیادهسازی آن را انجام دهید.
پروژهی اولیه را از این لینک دانلود کنید.
Wallet
)String
است.AdminWallet
)Wallet
ارثبری میکند و هیچ پیادهسازی اضافهای نسبت به مدل Wallet
ندارد.TransactionType
): این کلاس یک enum
است که بهترتیب شامل دو مقدار DEPOSIT
و WITHDRAWAL
است.DEPOSIT
هستند، بیانگر واریزهایی هستند که مقصد آنها، کیف پول فعلی است.WITHDRAWAL
هستند، بیانگر برداشتهایی هستند که از کیف پول به حساب بانکی صاحب کیف پول منتقل میشوند.TransactionStatus
): این کلاس یک enum
است که بهترتیب شامل سه مقدار CANCELED
، PENDING
و ACCEPTED
است.Transaction
)long id
: شناسهی تراکنشWallet wallet
: کیف پول مربوط به تراکنشTransactionType type
: نوع تراکنشBigDecimal amount
: مبلغ تراکنشDate createdAt
: زمان ایجاد تراکنشTransactionStatus status
: وضعیت تراکنش با مقدار اولیهی PENDING
Date updatedAt
: زمان تغییر وضعیت تراکنشupdatedAt
در کانستراکتور مقداردهی میشوند.setStatus
را طوری پیادهسازی کنید که با دریافت یک TransactionStatus
، وضعیت تراکنش را به وضعیت واردشده تغییر داده و مقدار پراپرتی updatedAt
را برابر با یک آبجکت جدید از نوع Date
قرار دهد.CrudRepository<T, ID>
T
(نوع مدل) و ID
(نوع شناسهی مدل) است.boolean add(T t)
: این متد، مدل را به مخزن اضافه میکند؛ به شرط آن که مدل از قبل در مخزن وجود نداشته باشد. اگر مدل از قبل در مخزن موجود باشد، مقدار false
و در غیر اینصورت، مقدار true
را برمیگرداند.List<T> getAll()
: این متد، لیست همهی مدلهای ذخیرهشده را بهترتیب درج برمیگرداند.T get(ID id)
: این متد، مدلی که شناسهی آن برابر با id
است را برمیگرداند. اگر چنین مدلی یافت نشود، مقدار null
را برمیگرداند.List<T> get(Predicate<T> predicate)
: این متد، لیست مدلهایی که شرایط دادهشده در predicate
را دارند بهترتیب درج برمیگرداند.TransactionRepository
CrudRepository
ارثبری میکند و صرفاً نوع تراکنشها (که Transaction
است) و نوع شناسهی آنها (که Long
است) را مشخص میکند.TransactionRepositoryImpl
TransactionRepository
را پیادهسازی میکند و تراکنشهای مربوط به همهی کیف پولها در آن ذخیره میشود.CrudRepository
پیادهسازی کنید.add
اگر مبلغ تراکنش کوچکتر یا مساوی صفر باشد، یک IllegalArgumentException
باید پرتاب شود.WalletService
addTransaction
را طوری پیادهسازی کنید که با دریافت یک تراکنش، با فراخوانی متد add
از transactionRepository
، آن را به لیست تراکنشها اضافه کند. این متد در صورتی که تراکنش از قبل موجود باشد، باید مقدار false
و در غیر اینصورت، باید مقدار true
را برگرداند.getTransactions(Wallet wallet)
را طوری پیادهسازی کنید که لیست همهی تراکنشهایی که مربوط به کیف پول ورودی هستند را بهترتیب درج برگرداند.getTransactions(Wallet wallet, Predicate<Transaction> predicate)
را طوری پیادهسازی کنید که لیست همهی تراکنشهایی که مربوط به کیف پول ورودی هستند و شرایط دادهشده در predicate
را دارند بهترتیب درج برگرداند.getBalance
را طوری پیادهسازی کنید که با دریافت یک کیف پول، موجودی حساب کیف پول را در قالب یک BigDecimal
برگرداند. موجودی حساب برابر با مجموع مبلغ DEPOSIT
های ACCEPTED
منهای مجموع مبلغ WITHDRAWAL
های ACCEPTED
است.setTransactionStatus
را طوری پیادهسازی کنید که با دریافت یک تراکنش و وضعیت جدید، در صورتی که وضعیت تراکنش PENDING
نبود یا وضعیت جدید برابر با PENDING
بود، مقدار false
را برگرداند. در غیر اینصورت، اگر تراکنش از نوع WITHDRAWAL
بود و موجودی کیف پول به اندازهی مبلغ تراکنش نبود، یک IllegalArgumentException
پرتاب شود. در غیر اینصورت، وضعیت تراکنش به وضعیت جدید تغییر کند، مقدار پراپرتی updatedAt
تراکنش بهروز شود و مقدار true
برگردانده شود.AdminWalletService
WalletService
ارثبری میکند.getTransactions(Predicate<Transaction> predicate)
را طوری پیادهسازی کنید که لیست همهی تراکنشهای مربوط به همهی کیف پولها که شرایط دادهشده در predicate
را دارند بهترتیب درج برگرداند.getAllTransactions
را طوری پیادهسازی کنید که لیست همهی تراکنشهای مربوط به همهی کیف پولها (همهی تراکنشهای موجود در مخزن) را بهترتیب درج برگرداند.Application
) اضافه کنید.با اجرای متد main
موجود در کلاس Application
، خروجی زیر مورد انتظار است:
پس از پیادهسازی موارد خواستهشده، یک فایل زیر آپلود کنید که وقتی آن را باز میکنیم، با ساختار زیر مواجه شویم (از سایر فایلها صرفنظر میشود):
چند ماهی است که احمد یک وبسرویس پرداخت با نام بپرداز پیادهسازی کرده است. این وبسرویس اخیراً شاهد ترافیک سنگین درخواستها بوده است. احمد برای رفع این مشکل، تصمیم گرفت تا از چند سرور مختلف برای پردازش درخواستها استفاده کند. این سرورها با یکدیگر sync هستند؛ اما هماکنون برخی از آنها همچنان به دلیل ترافیک بالای درخواستها کند شدهاند. از آنجایی که احمد هنوز راهحل درستی برای این مسئله پیدا نکرده، میخواهد یک تغییر موقتی روی SDK ای که در اختیار توسعهدهندگان قرار داده است اعمال کند.
احمد میخواهد SDK جاوای وبسرویسش را طوری پیادهسازی کند که درخواست تأیید یک تراکنش بهصورت همزمان به همهی سرورهای موجود ارسال شود و به محض اولین پاسخی که از یکی از سرورها دریافت میشود، این پاسخ برگردانده شود. همچنین، او میخواهد قابلیت ست کردن timeout وجود داشته باشد تا اگر پس از واحد زمانی هیچ پاسخی دریافت نشد، برنامه یک Exception
پرتاب کند.
پروژهی اولیه را از این لینک دانلود کنید.
TransactionVerifier
🔗این کلاس در کانستراکتور خود لیستی از URL
های مربوط به درخواست تأیید تراکنش را دریافت میکند.
URL
ها خالی بود، یک IllegalArgumentException
پرتاب شود.setTimeout
را طوری پیادهسازی کنید که با دریافت یک واحد زمانی از نوع Duration
، حداکثر زمان انتظار برای دریافت پاسخ را مشخص کند. همچنین، مقدار پیشفرض timeout را برابر با ۳ ثانیه قرار دهید.verify
را طوری پیادهسازی کنید که با دریافت شناسهی یک تراکنش (که از نوع String
است)، درخواست تأیید تراکنش را بهصورت همروند به همهی آدرسها ارسال کند و به محض دریافت اولین پاسخ، آن را در قالب یک رشته برگرداند. این متد باید حداکثر به اندازهی timeout ست شده منتظر پاسخ بماند. اگر timeout رخ دهد، این متد باید یک TimeoutException
پرتاب کند. درخواستها باید از نوع POST
باشند و مقدار پارامتر transaction_id
باید برابر با شناسهی تراکنش قرار داده شود. بدنهی درخواست باید از نوع JSON باشد.getFastestServer
را طوری پیادهسازی کنید که URL
سروری که تاکنون بیشترین پاسخها از آن دریافت شده است را برگرداند. اگر تعداد دفعات دریافت زودترین پاسخ از چند سرور یکسان بود، URL
یکی از آنها را به دلخواه برگردانید.با اجرای متد main
، یکی از سه خروجی زیر مورد انتظار است:
توجه: برنامهی شما نباید resource leak داشته باشد.
پس از پیادهسازی کلاس TransactionVerifier
، فایل TransactionVerifier.java
را آپلود کنید.
تیم انبوهفروشان مشرقزمین قصد دارد سامانهای تحتوب برای مدیریت آسانتر فروشگاهشان راهاندازی کند. آنها تصمیم گرفتهاند تا وبسرویسشان را با استفاده از Spring Boot پیادهسازی کنند. نیازمندیها از قبل بهطور دقیق مشخص شدهاند، اما هنوز برنامهنویسی به تیم آنها اضافه نشده است. از شما میخواهیم تا نسخهی اولیهی این وبسرویس را پیادهسازی کنید.
پروژهی اولیه را از این لینک دانلود کنید.
ir.digipay.bulkshop
شامل موجودیتهای JPA برنامه است که مطابق با schema دیتابیس طراحی شدهاند. شناسه (id
) موجودیتها بهصورت خودکار توسط Hibernate تولید میشود.CustomerEntity
: از این کلاس برای نگهداری اطلاعات هر مشتری استفاده میشود.ProductEntity
: از این کلاس برای نگهداری اطلاعات هر محصول استفاده میشود.OrderEntity
: از این کلاس برای نگهداری اطلاعات هر سفارش استفاده میشود.ir.digipay.bulkshop.api
شامل کلاسهایی برای مدیریت ورودیها و خروجیهای API است.ir.digipay.bulkshop.rest
شامل REST controller های برنامه است. کنترلر مربوط به آدرس /
برای تست برنامه در کلاس IndexRestEnpoint
پیادهسازی شده است. سایر کنترلرها را در این بسته پیادهسازی کنید.تعدادی وبسرویس REST مطابق نیازمندیهای زیر باید پیادهسازی شود:
آدرس | عنوان |
---|---|
GET /api/products |
دریافت اطلاعات محصولات |
POST /api/products |
ایجاد محصول |
GET /api/products/{id} |
دریافت اطلاعات یک محصول |
PUT /api/products |
ویرایش اطلاعات یک محصول |
GET /api/customers |
دریافت اطلاعات مشتریان |
POST /api/customers |
ایجاد مشتری |
GET /api/customers/{id} |
دریافت اطلاعات یک مشتری |
PUT /api/customers |
ویرایش اطلاعات یک مشتری |
GET /api/orders |
دریافت اطلاعات سفارشات |
POST /api/orders |
ایجاد سفارش |
GET /api/orders/{id} |
دریافت اطلاعات یک سفارش |
اطلاعات همهی محصولات در قالب یک آرایه برگردانده میشود:
یک محصول با اطلاعات اولیهی دادهشده ایجاد میشود و شناسهی آن برگردانده میشود:
شناسهی محصول بهعنوان ورودی داده میشود و اطلاعات محصول برگردانده میشود:
اگر محصولی با شناسهی واردشده موجود نباشد، پاسخ باید بهصورت زیر باشد:
اطلاعات جدید محصول داده میشود و پس از بهروزرسانی اطلاعات محصول، پاسخی با کد 204
برگردانده میشود:
اگر محصولی با شناسهی واردشده موجود نباشد، پاسخ باید بهصورت زیر باشد:
اطلاعات همهی مشتریان در قالب یک آرایه برگردانده میشود:
یک مشتری با اطلاعات اولیهی دادهشده ایجاد میشود و شناسهی آن برگردانده میشود:
اگر مشتریای با نام کاربری دادهشده از قبل موجود باشد، پاسخ باید بهصورت زیر باشد:
شناسهی مشتری بهعنوان ورودی داده میشود و اطلاعات مشتری برگردانده میشود:
اگر مشتریای با شناسهی واردشده موجود نباشد، پاسخ باید بهصورت زیر باشد:
اطلاعات جدید مشتری داده میشود و پس از بهروزرسانی اطلاعات مشتری، پاسخی با کد 204
برگردانده میشود:
اگر مشتریای با شناسهی واردشده موجود نباشد، پاسخ باید بهصورت زیر باشد:
اطلاعات همهی محصولات در قالب یک آرایه برگردانده میشود:
یک سفارش با اطلاعات دادهشده ایجاد میشود، مقدار موجودی محصول به اندازهی تعداد واردشده کم میشود و شناسهی سفارش برگردانده میشود:
اگر مشتری یا محصولی با شناسهی واردشده موجود نباشد، پاسخ باید بهصورت زیر باشد:
اگر مقدار فیلد count
کوچکتر یا مساوی صفر باشد، پاسخ باید بهصورت زیر باشد:
اگر مقدار count
بزرگتر از موجودی فعلی محصول باشد، پاسخ باید بهصورت زیر باشد:
شناسهی سفارش بهعنوان ورودی داده میشود و اطلاعات سفارش برگردانده میشود:
اگر سفارشی با شناسهی واردشده موجود نباشد، پاسخ باید بهصورت زیر باشد:
ir.digipay.bulkshop
هستید.پس از پیادهسازی موارد خواستهشده، پوشهی src
پروژه را زیپ کرده و ارسال کنید. توجه داشته باشید که فقط تغییرات اعمالشده در پوشهی src/main/java/ir.digipay.bulkshop
در نظر گرفته میشوند.