چلنج باحال از سایت CodeWars شماره 1



سلام دوستان.

سری مقاله ها رو می خوام شروع کنم فیض ببریم از حل چلنج های وب سایت CodeWars.

خب کد وارز (Codewars) اصلا چی هست؟

کد وارز یه سایت آموزشیه که پر از چلنج های مختلف با درجه سختی های مختلفه که برنامه نویسا ازش برای آمادگی برای مسابقات یا یادگیری یه زبان جدید و یا هدف های دیگه استفاده می کنن.

درجه سختی های چلنجا توی سایت خیلی جالب درجه بندی شدن اینجوریه که از آسان به سخت با نمادی به اسم kyu از عدد ۸ که آسان ترین چلنج هاست تا ۱ که ۲۰ نفر هم به زور یکیشو حل نمیکنن D:

kyu 8 < kyu 7 < kyu 6 < kyu 5 < kyu 4 < kyu 3 < kyu 2 < kyu 1


حالا چرا ++C !?

اول بگم که اگه ++C بلد نیستید هیچ مشکلی نیست شما فقط روش حلشو نگاه کن سعی کن راه حل رو یاد بگیری چون برنامه نویس در اصل کارش حل مسءلس زبان برنامه نویسی فقط یه ابزاره.

دلیل اصلی که ++C رو انتخاب کردم اینه که سخته!!!

تو نگاه اول ممکنه خنده دار به نظر بیاد ولی یه شخصیت جالب دارم اونم اینه که همیشه دنبال سختی ها میرم.D:

خب ++C خیلی سریعه معمولا ازش توی کار ها پروژه ها بزرگ استفاده میشه مثل بازی ها و یا حتی همین photoshop خودمان ولی این به این معنی نیست که برای کارای دیگه نمیشه ازش استفاه کنیم ولی ++C قضیه اش فرق داره چون Object oriented یا همون شی گرا هست پس دست کمی از Java توی App Development یا توسعه نرم افزار نداره و به زیبایی از پس همچین چیزایی بر میاد در کل مثل یه آچر فرانسه میمانه.

چلنج شماره ۱

این چلنجی که الان میریم درجه سختیش توی سایت kyu 7 هست که زیاد سخت نیست معمولا با ۱ هفته تمرین مداوم و stackoverflow(سایت پرسش و پاسخ برنامه نویسا) میشه حل کرد اینارو XD

برای حل این چلنج به چه چیزایی نیازه؟

FUNDAMENTALS => چیزهای پایه ای

NUMBERS =>نحوه کارکردن با اعداد

MATHEMATICS =>فقط یه تیکه کوچیک قول میدم XD

BASIC LANGUAGE FEATURES =>قابلیت های پایه ای زبان

LOOPS => لوپ یا حلقه ها

CONTROL FLOW => همون ایف اِلس خودمان

حالا چلنج چیه؟

اسم چلنج: Balanced number

درجه سختی: kyu 7

میگه که یه function(تابع) بساز که هر عددی رو بهش میدی اگه جمع عدد های سمت چپ و سمت راست عدد برابر باشه به ما "Balanced" رو میده در غیر این صورت "Not balanced" رو میده.

اگه عدد ما فرد بود خب وسطش معلومه ولی اگه زوج بود ۲ تا عدد وسط رو وسط در نذر بگیر(با این توضیحی که من دادم XD)

بزار چنتا مثال بزنم: اول برای اون زوج و فرد و وسط اونها

اگه سایز یا بلندای عددمان فرد بود مثل ۶۴۵ که ۳رقمیه پس وسط عدد ۴ هست

ولی سایز عددمان زوج بود مثل ۱۳۷۰ که ۴رقمیه پس اینجا وسط عدد ۳۷ هست


بزار اول از جایی که همه ی برنامه نویسا شروع میکنن ما هم شروع کنیم سوالو که کامل فهمیدیم پس بریم سراغ چرک نویس

چرک نویس

/*  is it balanced or not
 left to middle == middle to right
if odd middle is a single number   34 5 7
if even midle is a two digit number 322 54 52
 number ----> string --> &quotBalanced&quot
                                |
                                 ---> &quotNot Balanced&quot
 for even or odd:
 devide string length by 2
  odd divide by 2 - 1 ==> 1234567 ->len 7 / 2 + 1 = 4 => middle
                                ==> 12345   ->len 5 / 2 + 1 = 3 => middle
even divide by 2 - 1 ==> 12345678 -> len 8 / 2 = 4 but for adding
                                                                                 right side start from + 1
                                ==> 1234     -> len 4 / 2 = 4 but for adding
                                                                             right side start from + 1
 if else statement --> if odd{...} else{...}
     for loop in if else
 adding begin to middle = left
adding middle to end   = right
 return left == right? &quotbalanced&quot : &quotNot Balanced&quot
string to number function
number % 2 ==0
 int sum function
 */

این چیه دیگه؟

اگه خوب دقت کنین این همون صورت سوالاس که توی ذهن خودم مرور کردمو خواستم چیزایی که فهمیدمو روی چرک نویس پیاده کنم

نظرتان چیه که اینقدر کشش ندمو جوابشو بزارم و بعدش توضیحش بدم.

کد رو کامل کامنت گذاری کردم کسایی که کار کردن کامل میفهمنش


جواب چلنج

#include <iostream>
#include <string>
#include <utility>
#include <sstream>
using namespace std;
// a function to convert strings to integers
int stringToInt(string str){
    int leftSideNum = 0;
    stringstream s(str);
    s >> leftSideNum;
    return leftSideNum;
}
// a function to add up the digits of an integer
int digitSum(int num){
    int sum = 0;
    while (num != 0) {
        sum = sum + num % 10;
        num = num / 10;
    }
    return sum;
}
/* the main function checks if the number is odd or even
and finds the middle of the number calls the other functions
and return the strings based on the instructions*/
string balancedNum (unsigned long long int number ){
    string str = to_string(number);
    long int middleIndex;
    long int strLength = str.length();
    //----------------------------------------------
    //the if else statement for finding the middle of the odd or the even number
    if(strLength % 2 == 0){
        middleIndex = strLength / 2 - 1;
    }
    else{
        middleIndex = strLength / 2;
    }

    int l, r;
    //---------------------------------------------
    // pulling left side and right side of the number as string
    string leftSide = str.substr(0, middleIndex);
    string rightSide = str.substr(strLength % 2 == 0 ? (middleIndex + 2) : (middleIndex + 1), str.length() - 1);
    // ---------------------------------------------
    // turning our left side and right side to integer
    l = stringToInt(leftSide);
    r = stringToInt(rightSide);
    // ---------------------------------------------
    // calculating the sum of both sides
    int leftSum = digitSum(l);
    int rightSum = digitSum(r);
    //---------------------------------------------
    return leftSum == rightSum ? &quotBalanced&quot : &quotNot Balanced&quot
}

اونجوری نگاه نکنید بزارید توضیح بدم کامل همه چی رو

خط هایی که با // شروع میشن رو کامنت میگن فقط برای توضیخ هستن

خب از خط ۱ به ترتیب اولین چیزی که میبینید خط هایی هستن که با # شروع میشن خب چی هستن اینا؟ به اینا میگن liberary یا کتابخانه

کتابخانه ها کد ها قابلیت های و ویژگی های از قبل نوشته شده ای هست که برای ما کسایی که از قبل زحمت کدشو کشیدن و ما فقط بالای صفحه اضافشون میکنیم که کارمان رو راحت میکنن

خب خط 5 چیه این ;using namespace std؟ وارد جزءیات نمیشم ولی اینو بدونید که بعضی از keyword ها نیاز دارند که یه ::std جلوشان بزاریم پس برای همین از namespace کمک میگیریم که کارمان راحت تر شه حالا دلایل دیگه ای هم داره ولی خب بمانه برای مقاله های دیگه.

خب همینجور که توی خط 6 گفتم توی خط 7 ما یه function ساختیم به اسم stringToInt که کار ش چیه

کارش اینه که یه string بگیره و به integer یا عدد تبدیلش کنه من از stringstream استفاده کردم.

خب الان که چی به چه درد چلنج ما میخوره؟ این function توی خط های بعدی به کمک ما میاد.

خب توی خط ۱۴ میریم سراغ ساخت یه function به اسم digitSum همینجور که از اسمش معلومه برای جمع عددهاس و ساختارش اینجوریه که از عددمان % میگیریم و هرچی باقی ماند رو به یه عدد که تعیین کردیم که صفر باشه(int sum = 0) میکنیم و در ادامه عددو بر ۱۰ تقسیم میکنیم که از عدد اصلی ما رقمی رو که جمع کردیم کم شه که دوباره با % به سراغ رقم بعدی بریم و این همینجوری ادامه داره تا همه ی رقم ها با هم جمع شن و در پایان هم عدد رو به ما میده

خب توی خط 25 با function آخر رو داریم به اسم balancedNum که تمام محاسبات قراره اینجا انجام میشه اول function ما یه string به اسم str می سازیم که عددمان رو به string تبدیل میکنه

1234 => &quot1234&quot

بعدش یه integer می سازیم به اسم strLength با استفاده از ()str.length ما سایز string رو داخلش قرار میدیم

خب اینجاس که سراغ چپ و راست میایم با یه if else statement میگیم که اگه % سایز string(که همون strLength بود) مساوی با ۲ بود(یعنی اگه ذوج بود) یه سایز جدید میسازیم و string که داشتیم تقسیم بر ۲ منهای ۱ میکنیم(middleIndex = strLength / 2 - 1;)

و یا اگه مساوی ۲ نبود پس فرده و string رو فقط تقسیم بر ۲ میکنیم(middleIndex = strLength / 2;)

خب حالا ما میدونیم وسط عددمان کجاس حالا باید تعیین کنیم که از کجا تا کجا میشه سمت چپ و از کجا تا کجا میشه سمت راست(خط 41 تا 42)

خب حالا توی خط 46 و 47 اینجاست که ما از function که قبلا ساخته بودیم استفاده میکنیم همون stringToInt صداش میزنیم و سمت چپ رو میزاریم توش که کارشو بسازه و بعد نتیجه رو توی یه integer دیگه ذخیره میکنیم و همین کار رو برای سمت راست هم انجام میدیم

حالا اینجا جالب میشه نتیجه های function های قبلی رو توی function دومی که ساخته بودیم (digitSum)میزاریم همون function جمع اعداد

و در آخر هم نتیجه نتیجه function جمع اعداد رو مقایسه میکنیم اگه برابر بودن "Balanced" رو پرینت کنه و گر نه "Not Balanced" رو پرینت کنه

خب تمام شد نمیتانم بگم کم بود یا سخت نبود ولی روند لذت بخشی بود منکه از نوشتن ++C لذت میبرم

حالا برای کسایی که علاقه دارن بدونن که ممکنه به روش های دیگه حل شه چند تا روش دیگه میزارم

روش هایی دیگه برای حل چلنج

const char* balancedNum(unsigned long long int n)
{
    auto str = std::to_string(n);
    int balance = 0;
    for (size_t i = 0, j = str.size() / 2 + 1; j < str.size(); ++i, ++j)
    {
        balance += str[i];
        balance -= str[j];
    }
    return (balance == 0)? &quotBalanced&quot : &quotNot Balanced&quot


#include <numeric>

using namespace std;

template<typename T, T s, typename I1,typename I2,typename F>
auto acc(I1 b,I2 e,F f){
    return accumulate(b,e,(T)s, f);
}

string balancedNum (unsigned long long int number )
{
    if (number < 100) return &quotBalanced&quot
    auto s = to_string(number);
    auto l = s.length();
    auto f = [](size_t a, char c){return a + (c-'0');};
    auto a = acc<size_t,0>(s.begin(), s.end() - l/2-1, f);
    auto b = acc<size_t,0>(s.begin() + l/2+1, s.end(), f);
    return a == b ? &quotBalanced&quot : &quotNot Balanced&quot ;


std::string balancedNum (unsigned long long int n)
{
    int i[18], d, l=0, s=0, c=-1;
    while (n) {i[d=++c]=n%10; n/=10;}
    while (c-l>(d&1)) s+=i[c--]-i[l++];
    return s?&quotNot Balanced&quot:&quotBalanced&quot
}

و جمله آخر که خیلی دوستش دارم

If you think you can do a thing or think you can't do a thing, you're right.

Henry Ford

یا علی.