يونيو 08، 2009

مشروع Euler project: المشكلة رقم 4

المشكلة رقم 4:
العدد البليندرومي (Palindromic number) هو العدد الذي يمكن فراءته من كلى الجهتين.

أكبر عدد بليندرومي ناتج من عددين مكونين من رقمين هو : 9009 = 91 x 99


المطلوب:
ابحث عن أكبر عدد بليندرومي ناتج من عددين مكونين من ثلاثة أرقام.


الحل الأول:
def palindromic():
    for i in range(999, 900, -1):
        for j in range(999, 900, -1):           
            n = i * j
            s = str(n)

            if s == s[::-1]:
                return n


print palindromic()

شرح الحل الأول:
1. سنقوم بكتابة دالة إسمها ()palindromic مستخدمين الكلمة المفتحية def المخصصة للتعريف الدوال.
2. نستخدم حلقتين متتاليتين تبدأ كل واحدة دورتها من العدد 999 نزولا إلى 900. لاحظ معي هنا أننا أضفنا -1 كمعيار للدالة ()range في كل من الحلقتين لتسمح لهما بالنزول من الأكبر إلى الأصغر.
3. المتغيرة n تساوي مجموع المتغيرة i x j. المتغيرة i تكتسب قيمتها من الحلقة الأولى و j من الحلقة الثانية.
4. نستخدم المتغيرة s لتعبر عن نتيجة المتغيرة n بصيغة نصية. بمعنى آخر نقوم بتحويل قيمة المتغير n من قيمة عددية إلى قيمة نصية. مثال إدا كانت قيمة n تساوي 998001 فإن قيمة s ستكون "998001". لاحظ إضافة "". هذه العملية تتم بواسطة الدالة ()str
5. نقوم بمقارنة قيمة المتغيرة s بقيمة عكسية. مثال: "998001" تصبح "100899". أية متغيرة نصية عندما تستخدم على الشكل s[::-1] ينتج عنها قيمة عكسية كما رأينا.
6. ثم في النهاية إدا عثرنا على عدد باليندرومي يتم الخروج به كنتيجة للدالة ()palindromic و من ثم  عرضه من طرف print


الحل الثاني:

print  max(x*y for x in range(999, 900, -1) for y in range(999, 900, -1) if str(x*y) == str(x*y)[::-1])

شرح الحل الثاني:
هنا نقوم بنفس الشيء كما الحل الأول لكن في سطر واحد فقط.
1. نقوم بإستخدام حلقة داخل حلقة. for x in range(999, 900, -1) for y in range(999, 900, -1)

هذا الإجراء يفترض أن يقوم بإنشاء قائمة مكونة من جميع قيم x*y
2. لكن نحن لا نريد قائمة بكل القيم بل فقط القيم التي يمكن أن تتطابق بصيغة عدد باليندرومي. يتم ذلك بإستخدام الجزء الشرطي if str(x*y) == str(x*y)[::-1])
3. عند تجميع كل الأعداد الياليندرومية في القائمة يتم عرض أعلى قيمة حصلنا عليها و ذلك بواسط الدالة max


هل من مبرمج بلغة روبي يمكن ان يكتب الحلول مستخدما تلك اللغة الجذابة؟

هناك 5 تعليقات:

  1. السلام عليكم
    أشكرك على هذه التدوينات الجميلة وخاصة تلك التي تحتوي مسائل برمجية تنشط ذاكرتنا وتعرفنا بطرق وخوارزميات جديدة.
    إليك الحل باستخدام السي شارب

    private bool IsSymmetric(string s)
    {
    for (int i = 0; i <= s.Length / 2; ++i)
    if (s[i] == s[s.Length - i - 1])
    {
    if (i == s.Length / 2)
    return true;
    }
    else
    return false;
    return false;
    }
    private string GetPalindromic()
    {
    int MaxSym = 0;
    for (int i = 100; i <= 999; ++i)
    {
    for (int j = i; j <= 999; ++j)
    {
    int k = i * j;
    string s = k.ToString();
    if (IsSymmetric(s) && MaxSym < k)
    MaxSym = k;
    }
    }
    return MaxSym.ToString();
    }

    ردحذف
  2. حلى البسيط

    is_palind=lambda x: x==x[::-1]
    max(
    int(x*y) for x in range(100, 999) for y in range(x, 999) if is_palind(str(x*y))
    )

    محمد بالمناسبة مش عارف اعمل paste هنا ؟ بضطر اعيد الكتابة تانى ؟؟

    ردحذف
  3. كتبت الحل.

    @محمد الجوهري: يبدوا أنني بدأت أعجب بلغة c# :)

    @Ahmed Youssef: بدون تعليق :)

    بخصوص تلك المشكلة مع اللصق، لأدري، أهي في كل مرة أم صادفت مشكلة على خدمة التعليقات؟

    ردحذف
  4. كله تمام كدا

    *راجع الحل التانى كدا

    ردحذف
  5. Ahmed Youssef@ حلك في المستوى يا صديقي :)

    ردحذف