حمید پس از نوشتن صورت جلساتش در اسنپ به زبان انگلیسی، متوجه شده که همهی اعداد را شمارشی نوشته، اما باید ترتیبی باشند! برای مثال، بهجای 1
باید مینوشته 1st
و بهجای 22
باید مینوشته 22nd
. از آنجایی که تعداد صورت جلسات حمید بسیار زیاد است، او از شما خواسته تا این تبدیل را بهصورت خودکار برایش انجام دهید.
در تعدادی خط از ورودی استاندارد (stdin) که تعدادشان نامشخص است، یکی از صورت جلسات حمید وارد میشود که ممکن است شامل اعداد مختلفی باشد. اعداد حداکثر ۷ رقمی هستند.
متن صورت جلسه را پس از تغییر اعداد به اعداد ترتیبی چاپ کنید.
برنامهنویسان در شرکت اسنپ عادت دارند برای تشخیص اینکه ارور برگرداندهشده از متد چیست، کدهایی مثل کد زیر مینویسند:
در نتیجه انتظار دارند پکیج مربوطه، همه ارورهایی که ممکن است برگردانده شوند را به شکل فیلد در خود داشته باشد.
متاسفانه یا خوشبختانه یک کتابخانهی فوقالعاده مفید به دست تیم فنی اسنپ رسیده است. این کتابخانه اگرچه بسیار مفید است و کارهای آنها را راحت میکند، اما این قاعده در آن برقرار نیست.
حالا برنامهنویسان اسنپ میخواهند برخلاف عادت خود عمل نکنند، بنابراین نیاز به یک پکیج کمکی برای پکیج اصلی دارند که ارورها را در خودش داشته باشد.
خوشبختانه این کتابخانه، سورسکد قابل خواندن (و نه تغییر) دارد و میتوان از آن به منظور توسعهی پکیج کمکی استفاده کرد.
helper.go
در پکیج helper
را به گونهای تغییر دهید تا فیلدهای ارورها در آن مقداردهی شوند.helper
میتوانید به صورت زیر از کتابخانهی the_lib
استفاده کنید.فایل helper.go
تغییریافتهی خود را آپلود کنید.
اسنپ برای افزایش کارایی کد در سرورهای خود، میخواهد از تکنیک SIMD استفاده کند. این تکنیک به این صورت عمل میکند که به جای اینکه در آن واحد یک عملیات روی دیتای ۳۲ بیتی انجام شود، ۴ عملیات روی ۴ دیتای ۸ بیتی بدون علامت انجام میشود. به این ترتیب به Parallelism دست پیدا میکنیم. اما نکته مهم اینکه اینجا به جای استفاده از قابلیت سختافزاری پردازندهها برای SIMD، از امکانات همروندی زبان گو استفاده میکنیم.
پروژه اولیه را از این لینک دانلود کنید.
در این سوال شما باید تابع Simd
را پیاده سازی کنید. تابع شما ورودیهای زیر را دارد:
uint32
به عنوان ورودیuint32
به عنوان خروجی محاسباتپس از پیادهسازی موارد خواسته شده، فایل main.go
را آپلود کنید. در صورتی که از dependency خاصی استفاده کردهاید، فایلهای go.mod
و go.sum
را بههمراه فایل main.go
زیپ کرده و آن را آپلود کنید.
یکی از کارمندان شرکت اسنپ ، در آخرین دقیقه از آخرین ساعت از آخرین روز کاری خود قبل از مرخصی تابستانه خود، متوجه یک باگ در سیستم اعمال تخفیف اسنپ میشود. او که چند ثانیه بیشتر زمان نداشته یک گزارش ناقص از باگ مینویسد و در سامانه ثبت میکند و برای همیشه خارج میشود.
گزارش وی به شرح زیر است:
فوری فوری
باگ در ماژول تخفیف
این باگ میتواند منجر به ضرر شرکت شود
همانطور که میبینید، این باگ اهمیت زیادی دارد. او از شما خواسته شده که هرچه سریعتر با بررسی سورسکد، آن را پیدا و رفع کنید.
سورسکد باگدار (اولیه) را از این لینک دانلود کنید.
SnappSystem
از سمت سرور میآید و دیتای آن حتما صحیح است.TripRequest
را سیستم کاربر ارسال میکند و مستقیم به این متد میرسد.پس از پیادهسازی موارد خواسته شده، فایل main.go
را آپلود کنید.
تیم فنی اسنپ قصد دارد تا سیستم جدیدی برای مدیریت دستاوردهای کاربران و دادن امتیاز به آنها با بهرهگیری از gamification پیادهسازی کند، اما به دلیل درخواست این تیم برای جذب نیروی فنی، آنها این تسک را به برخی از افرادی سپردهاند که در مرحلهی اول مصاحبهی اسنپ قبول شدهاند. مهدی که سرش شلوغ است، اما میخواهد در اسنپ استخدام شود، از شما میخواهد تا این تسک را برایش انجام دهید. نسخهی اولیهی این سیستم قرار است یک API ساده باشد.
پروژهی اولیه را از این لینک دانلود کنید. ساختار فایلهای پروژه بهصورت زیر است:
در این پروژه از پایگاه دادهی PostgreSQL استفاده شده است. برنامه شامل جداول زیر است:
users
):نام ستون | نوع | تعریف | ملاحضات |
---|---|---|---|
id |
BIGSERIAL |
شناسهی کاربر | PRIMARY KEY |
name |
VARCHAR(255) |
نام | |
phone |
VARCHAR(255) |
شماره تلفن |
achievements
):نام ستون | نوع | تعریف | ملاحظات |
---|---|---|---|
id |
BIGSERIAL |
شناسهی دستاورد | PRIMARY KEY |
title |
VARCHAR(255) |
عنوان دستاورد |
user_achievements
):نام ستون | نوع | تعریف |
---|---|---|
user_id |
BIGINT |
شناسهی کاربر |
achievement_id |
BIGINT |
شناسهی دستاورد |
دسترسی به پایگاه داده از طریق تابع db.GetConnection
صورت میگیرد که به شکل singleton پیادهسازی شده است.
یک map[int](func(int) bool)
به شکل singleton در برنامه تعریف شده که از طریق تابع achievements.GetMap
قابل دسترسی است. این مپ، نگاشتی از شناسهی دستاوردها به توابعی است که با دریافت شناسهی یک کاربر، مشخص میکنند که آیا آن دستاورد توسط کاربر کسب شده است یا خیر.
نسخهی اولیهی این API شامل روتهای زیر است:
/is_achieved
: این روت به تابع handlers.IsAchieved
مپ شده است که با دریافت یک user_id
و یک achievement_id
از query string، مشخص میکند که آیا دستاورد توسط کاربر ذکرشده کسب شده است یا خیر.user_id
مقداردهی نشده باشد، کد پاسخ باید 400
و بدنهی پاسخ باید {"error": "no user id provided"}
باشد.user_id
مقداردهی شده باشد، اما پارامتر achievement_id
مقداردهی نشده باشد، کد پاسخ باید 400
و بدنهی پاسخ باید {"error": "no achievement id provided"}
باشد.user_id
عددی نباشد، کد پاسخ باید 400
و بدنهی پاسخ باید {"error": "invalid user id"}
باشد.user_id
عددی باشد، اما مقدار پارامتر achievement_id
عددی نباشد، کد پاسخ باید 400
و بدنهی پاسخ باید {"error": "invalid achievement id"}
باشد.user_id
در جدول users
موجود نباشد، کد پاسخ باید 404
و بدنهی پاسخ باید {"error": "user not found"}
باشد.user_id
در جدول users
موجود باشد، اما دستاوردی با شناسهی achievement_id
در جدول achievements
موجود نباشد، کد پاسخ باید 404
و بدنهی پاسخ باید {"error": "achievement not found"}
باشد.200
و بدنهی پاسخ باید {"is_achieved": true}
یا {"is_achieved": false}
باشد (بسته به این که کاربر دستاورد را کسب کرده است یا خیر)./get_achievements
: این روت به تابع handlers.GetAchievements
مپ شده است که با دریافت یک user_id
از query string، لیست دستاوردهای کاربر را برمیگرداند.user_id
مقداردهی نشده باشد، کد پاسخ باید 400
و بدنهی پاسخ باید {"error": "no user id provided"}
باشد.user_id
عددی نباشد، کد پاسخ باید 400
و بدنهی پاسخ باید {"error": "invalid user id"}
باشد.user_id
در جدول users
موجود نباشد، کد پاسخ باید 404
و بدنهی پاسخ باید {"error": "user not found"}
باشد.200
و بدنهی پاسخ باید به فرم {"achievements": ["achievement 1 name", "achievement 2 name"]}
باشد (نام دستاوردها باید بهترتیب صعودی شناسهشان باشد)./refresh_achievements
: این روت به تابع handlers.RefreshAchievements
مپ شده است که با دریافت یک user_id
از query_string، لیست دستاوردهای کاربر را بهروز میکند. در واقع، دستاوردهایی که تاکنون توسط کاربر کسب نشدهاند باید مجدداً بررسی شوند و در صورتی که دستاورد جدیدی کسب شده بود، در جدول user_achievements
درج شود./get_achievements
باشد، با این تفاوت که دستاوردهای کسبنشده مجدداً بررسی میشوند.توجه: مقدار هدر Content-Type
در پاسخ همهی درخواستها باید برابر با application/json
قرار داده شود.
پس از پیادهسازی برنامه، یک فایل زیپ آپلود کنید که وقتی آن را باز میکنیم، با ساختار زیر مواجه شویم:
کوئریهای شما باید روی PostgreSQL 13 قابل اجرا باشد.
طاها قصد دارد تا تصمیمهایش را از این پس به شکل دادهمحور بگیرد و صرفاً شهودی عمل نکند. برای این کار، او نیاز به اطلاعات مختلفی از کاربران اسنپ دارد؛ اما چون او SQL بلد نیست، از شما خواسته تا کوئریهای مربوط به اطلاعات موردنیازش را بنویسید.
ساختار جداول بهصورت زیر است:
users
):نام ستون | نوع | تعریف | ملاحضات |
---|---|---|---|
id |
BIGSERIAL |
شناسهی کاربر | PRIMARY KEY |
name |
VARCHAR(255) |
نام | |
phone |
VARCHAR(255) |
شماره تلفن |
trips
):نام ستون | نوع | تعریف | ملاحظات |
---|---|---|---|
id |
BIGSERIAL |
شناسهی سفر | PRIMARY KEY |
user_id |
BIGINT |
شناسهی مسافر | |
driver_id |
BIGINT |
شناسهی سفیر (جدول سفیران در این مسئله وجود ندارد) | |
started_at |
TIMESTAMP |
زمان شروع سفر | |
finished_at |
TIMESTAMP |
زمان پایان سفر |
invitations
):نام ستون | نوع | تعریف | ملاحظات |
---|---|---|---|
id |
BIGSERIAL |
شناسهی دعوت | PRIMARY KEY |
inviter_user_id |
BIGINT |
شناسهی کاربر دعوتکننده | |
invitee_user_id |
BIGINT |
شناسهی کاربر دعوتشده | |
invited_at |
TIMESTAMP |
زمان دعوت |
کوئریهای SQL خواستهشده از شما موارد زیر است (توجه کنید که هر کوئری امتیازی جداگانه دارد و اگر کوئری یک قسمت را نتوانستید بنویسید، کوئریهایی که حل کردید را بفرستید و قسمت مربوط به آن کوئری را خالی بگذارید):
1400
است، بهترتیب صعودی برحسب شناسهنکته: نام ستونهای خروجی مهم نیست، اما ترتیب آنها مهم است.
کوئریهای خود را در قالب زیر، در یک فایل با پسوند .sql
قرار داده و آن را ارسال کنید (فایل را زیپ نکنید):