‏إظهار الرسائل ذات التسميات مشروع Project Euler. إظهار كافة الرسائل
‏إظهار الرسائل ذات التسميات مشروع Project Euler. إظهار كافة الرسائل

يونيو 14، 2009

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

المشكلة رقم 10:
مجموع العداد الأولية تحت 10 هو: 2 + 3 + 5 + 7 = 17

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

الحل:
import math

def isPrime(n):
    nbrs = [2] + range(3, int(math.sqrt(n))+1, 2)   
    for i in nbrs:
        if n % i == 0:
            return False
    return True

def sumPrimes(n):
    primes = [2] + [x for x in range(3, n, 2) if isPrime(x)]
    return sum(primes)

print sumPrimes(2000000)

الشرح:
1. نستدعي وحدة الرياضيات math بواسطة التعليمة import
2. نكتب دالة isPrime وظيفتها إختبار العدد الذي تتوصل به كمعيار n هل هو أولي أم لا. ذاخل هذه الذالة ننشئ قائمة بكل العداد بداية من 2 حتى جدع تربيع العدد n مع تفادي كل مضاعفات العدد 2
3. نكتب دالة وظيفتها إنشاء قائمة primes بكل الأعداد من 2 حتى n مع إجتناب مضاعفات العدد 2 و بشرط أن يكون أوليا، ثم بعد ذلك نستخدم الدالة sum حتى تحسب مجموع أعداد هذه القائمة.
4. يتم عرض النتيجة بإستخدام print

يونيو 13، 2009

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

المشكلة رقم 9:
تتألف ثلاثية فيثاغورس من الأعداد الصحيحة a < b < c بحيث تحقق العلاقة a2 + b2 = c2
مثال: 3^2 + 4^2 = 9 + 16 = 25 = 5^2

المطلوب:
توجد تحديدا ثلاثية فيثاغورس واحدة تكون فيها a + b + c = 1000
أجد abc

الحل الأول:
def pytha_Triplet(n):
    for a in range(1, n+1):
        for b in range(a+1, n+1):
            for c in range(n-a-b, b, -1):
                if a + b + c == n:
                    if (a**2) + (b**2) == (c**2):
                        return a*b*c

print pytha_Triplet(1000)

الشرح:
1. نقوم بتحديد دالة pytha_Triplet و تأخذ المعيار n. بداخلها يوجد حلقة تسلسلية تبدأ من 1 حتى آخر عدد (قيمة n). بداخلها توجد حلقة أخرى تبدأ من قيمة المتغيرة a+1 (الممثلة للمرحلة التي وصلت إليها الحلقة السابقة) و حتى آخر عدد ( وهو 1000 المعبر عنه ب n). و في داخل هذه الحلقة توجد حلقة أخرى تبدأ تنازليا من قيمة n-a-b حتى تصل إلى قيمة المتغيرة b (الممثلة للمرحلة التي وصلت إليها الحلقة الثانية). ثم بعد ذلك يتم إختبار مجموع a+b+c هل يتساوى مع n. إذا كان الشرط صحيحا يتم إجراء إختبار ثاني لمعرفة هل قيمة المتغيرتين a أُس 2 + b أُس 2 يتساوين مع قيمة المتغيرة c أُس 2. إدا كان الشرط صحيحا تخرج الدالة بنتيجة قيمة a*b*c
2. يتم عرض نتيجة الدالة pytha_Triplet

> كما تلاحظون هذه الحل يعتمد على طريقة تقليدية للعثور على ما نريد و هو يهدر الكثير من وقت المعالج.

الحالي الثاني (أسرع):
def pytha(n):
    a, b, c = 1, 2, n-3
    while (a < n/3):
        if a**2 + b**2 == c**2:
            return a*b*c
        elif c-1 > b+1:
            a, b, c = a, b+1, c-1
        else:
            a, b, c = a+1, a+2, n-(a+1)*2-1

print pytha(1000)

الشرح:
1. نكتب ذالة pytha و تأخد n كمعيار. بذاخلها يوجد:
2.1. يتم تعين قيمة 1 للمتغيرة a، و قيمة 2 للمتغيرة 2 و قيمة n-2 للمتغيرة c في آن واحد.
2.2. نحتاج إلى حلقة شرطية تبقى تدور ما دامت قيمة المتغيرة a أصغر من ثلث قيمة n. لماذ!؟ لأن ثلث قيمة n هو 333 و إدا كانت a = 333 فإن بالضرورة على b أن تكون أكبر من a بمعنى أنها على الأقل يجب أن تكون 334 و إذا كانت b = 334 فبالضرورة أن تكون قيمة c أكبر من b و بذلك فإن أصغر قيمة ممكنة ل c في هذه الحالة هو 335. و إذا قمنا بحساب مجموع a+b+c سنحصل على 1002 و بذلك فإدا وصلت قمية المتغيرة إلى ثلث قيمة n على الحلقة الشرطية بالخروج.
2.3. يتم إختبار قوة a في 2 + قوة b في 2 هل تتساوى مع قوة c في 2. إدا كان الشرط صحيح تخرج الدالة بمجموع ضرب قيمة a*b*c
2.4 إدا كان الشرط خاطئا يتم إختبار هل c-1 ما زالت أكبر من قيمة b+1. إدا كان الشرط صحيحا تبقى قيمة المتغيرة على حالها و تزيد قيمة b بـ 1 و تنقص قيمة c بـ 1 ثم تمر الحلقة إلى الدورة التالية.
2.5 أما إذا كان الشرطين السابقين خاطئين يتم تحديث قيمة a لتساوي a+1. ثم تصير b تساوي قيمة a+2 و قيمة c تساوي n ناقص قيمة (a+b) المعبر عنها بـ (a+1 مضروبة في 2) ناقص 1
3. يتم عرض نتيجة الدالة pytha بواسطة print

يونيو 12، 2009

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

المشكلة رقم 8:
أجد أكبر قيمة عددية مكونة من خمسة أرقام متتابعة في هذه السلسلة المكونة من 1000 رقم:

73167176531330624919225119674426574742355349194934
96983520312774506326239578318016984801869478851843
85861560789112949495459501737958331952853208805511
12540698747158523863050715693290963295227443043557
66896648950445244523161731856403098711121722383113
62229893423380308135336276614282806444486645238749
30358907296290491560440772390713810515859307960866
70172427121883998797908792274921901699720888093776
65727333001053367881220235421809751254540594752243
52584907711670556013604839586446706324415722155397
53697817977846174064955149290862569321978468622482
83972241375657056057490261407972968652414535100474
82166370484403199890008895243450658541227588666881
16427171479924442928230863465674813919123162824586
17866458359124566529476545682848912883142607690042
24219022671055626321111109370544217506941658960408
07198403850962455444362981230987879927244284909188
84580156166097919133875499200524063689912560717606
05886116467109405077541002256983155200055935729725
71636269561882670428252483600823257530420752963450

الحل:
nbrs = """73167176531330624919225119674426574742355349194934
96983520312774506326239578318016984801869478851843
85861560789112949495459501737958331952853208805511
12540698747158523863050715693290963295227443043557
66896648950445244523161731856403098711121722383113
62229893423380308135336276614282806444486645238749
30358907296290491560440772390713810515859307960866
70172427121883998797908792274921901699720888093776
65727333001053367881220235421809751254540594752243
52584907711670556013604839586446706324415722155397
53697817977846174064955149290862569321978468622482
83972241375657056057490261407972968652414535100474
82166370484403199890008895243450658541227588666881
16427171479924442928230863465674813919123162824586
17866458359124566529476545682848912883142607690042
24219022671055626321111109370544217506941658960408
07198403850962455444362981230987879927244284909188
84580156166097919133875499200524063689912560717606
05886116467109405077541002256983155200055935729725
71636269561882670428252483600823257530420752963450"""

nbrs = nbrs.replace('\n','')
product = 0

for i in range(len(nbrs)-4):
    p = 1

    for i in nbrs[i:i+5]:
        p *= int(i)

    if p > product:
        product = p

print product

الشرح:
1. المتغيرة nbrs تحتوي علة كل الأرقام لكن بصفة نصية. لاحظ أنها بين """. كما أن الأرقام كتبت موزعة على عدد من الأسطر و بالتالي في إن كل سطر يعبر عنه بحرف خفي يعبر عنه ب '\n' و يجب التخلص منه.
2. نتخلص من حرف '\n' من خلال تعويضه بالفراغ nbrs.replace('\n','')
3. نقوم بأخد و إختبار قيمة كل خمسة أرقام متتالية في تلك السلسلة من الأرقام. ثم نحتفظ بأعلى قيمة ناتج عملية ضرب تلك الارقام في بعضها البعض في المتغيرة product
4. بعد الإنتهاء من تلك السلسلة يتم عرض أعلة قيمة ناتج عثرنا عليها.

يونيو 11، 2009

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

المشكلة رقم 7:
من خلال عرض قائمة بالأعداد الأولية الستة الأولى: 2 ، 3 ، 5 ، 7 ، 11 و 13، نرى أن العدد السادس في القائمة هو العدد الأولي 13.

المطلوب:
ما هو العدد الأولي المرتب 10001 في قائمة الأعداد الأولية؟

الحل:
import math

def isPrime(n):
    nbrs = [2] + range(3, int(math.sqrt(n))+1, 2)   
    for i in nbrs:
        if n % i == 0:
            return False
    return True

def findPrime(position):
    i = 1
    counter = 1 # 1 instead of 0 because 2 won't be tested
    while True:
        i += 2
        if isPrime(i):
            counter += 1
        if counter == position:
            return i

print findPrime(10001)

الشرح:
1. نقوم بإستدعاء الوحدة math  التي تضم دوال العمليات الرياضية.
2. نقوم بتحديد دالة isPrime التي ستقوم بإختبار العدد المعطي في المعيار (n) هل هو اولي أم لا. و تقوم بذلك من خلال إنشاء قائمة بكل الأعدد التي هي أصغر من قيمة (n) حتى تجري عملية القسمة علىها باحثتا عن عدد لا يقبل القسمة إلا على نفسه. و حتى يتم تسرع عملية البحث يتم إستخدام جدع تربيع قيمة العدد (n) بالإضافة إلى تخطي كل العداد التي تقبل القسمة على 2
3. إنشاء دالة findPrime لإيجاد العدد الاولي صاحب الرتبة 10001 في قائمة الأعداد الأولية. تقوم هذه الدالة بالبحث عن العدد صاحب الرتبة المطلوبة (position) و ذلك من خلال الدوران في الحلقة الشرطية while. في كل دورة يتم إختبار عدد جديد، إذا كان أولي يتم تحديث العداد counter ثم إختبار الرتية اتي وصلنا إليها، و إذا كانت هي الرتبة المناسبة يتم الخروج من الدالة بالنتيجة المخزنة في المتغيرة i.
4. يتم عرض النتيجة بواسطة print


كما تلاحظون فقد إستخدمت ما تعلمناه في تجربتنا الأخيرة في تحسين كود بايثون، حيث إستخدمنا الدوال بدلا من كتابة الكود في الجزء العام بالإضافة إنشاء القوائم range خارج الحلاقات التسلسلية.

يونيو 10، 2009

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

المشكلة رقم 6:
مجموع مربع الأعداد الطييعية العشرة الأولى هو:
1^2 + 2^2 + ... + 10^2 = 385

و مربع مجموع الأعداد العشرة الطبيعية الأولى هو:
(1 + 2 + ... + 10)^2 = 55^2 = 3025

و الفرق بين النتيجتين هو:  3025 - 385 = 2640


المطلوب:
أجد الفرق بين مجموع مربع الأعداد الطبيعية المئة الأولى و مربع جمعها.


الحل الأول:
def sumSquares(n):
    r = 0
    for i in range(1, n+1):
        r = r + (i ** 2)
    return r

def squaresSum(n):
    r = 0
    for i in range(1, n+1):
        r = r + i
    return (r**2)

print  squaresSum(100) - sumSquares(100)
الشرح:
1. نخصص دالة لحساب مجموع مربع كل عدد إسمها sumSquares() بحيث تأخد المعيار (Parameter) n و تستخدم قيمته كأعلى عدد في سلسلة الأعداد 1 إلى n. ثم بعد ذلك نستخدم حلقة تسلسلية لحساب تربيع كل عدد (i**2) في السلسلة ثم إضافة الخارج على المجموع r. و بعد الإنتهاء من الحلقة تخرج الدالة بالنتيجة المخزنة في r.
2. الدالة الثانية squaresSum() تحسب تربيع مجموع الأعداد. و هس تشبه الدالة الأولى في التركيبة غير أن النتيجة مختلفة.
3. ثم نقوم بعرض النتيجة مستخدمين print التي تقوم بإستدعاء الدالة الاولة و الثانية ثم تعرض فرق النتيجة.

ملاحظة: إستخدام علامة النجمة مرتين ** يفيد حساب مربع عدد ما.

الحل الثاني:
كما تفضل الصديق أحمد يوسف في حله، يمكن كتابة الحل في سطر واحد:
print  sum(range(100+1))**2 - sum(x**2 for x in range(100+1))

الشرح:
1. يتم إنشاء قائمة تحتوي على سلسلة من الأرقام تبدأ من 0 إلى 100 ثم يتم حساب مجموع الأرقام في هذه الأرقام على الشكل التالي 0+1+2+3..+100 ثم يتم حساب مربع هذا المجموع.
2. يتم إنشاء قائمة تحتوي على مئة و واحد عنصر (0 إلى 100)، كل عنصر هو عبارة عن عدد كان أصله هو مربع رتبته في القائمة، بمعنى 0^2 و 1^2 و 2^2 ... إلى 100^2. ثم يتم حساب مجموع هذه الأعداد بواسطة الدالة sum() تماما كالجزء الأول.
3. بعد ذلك تقوم print  بعرض فارق المجموعين.

نعم، هذا الحل من حلول النينجا Python Ninja :)

يونيو 09، 2009

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

المشكلة رقم 5:
العدد 2520 هو أصغر عدد يمكن أن يقسم على كل عدد بدءا من 1 إلى 10 دون أي باقي.

المطلوب:
ما هو أصغر عدد يمكن قسمته على كل الأعداد من 1 إلى 20 دون أن يكون هنالك باقي (القسمة بالتساوي)


الحل الأول (إستغرق 24 ثانية على حاسوبي):
def euler5():
    i = 20
    seq = range(2, 20+1)
    while True:
        for j in seq:
            if i % j  !=  0:
                break
            elif j == 20:
                return i

        i += 20


print euler5()
الشرح:
1. نستخدم الكود داخل دالة حتى تزيد من سرعة الأداء. الدالة تم تحديدها بواسطة الكلمة المفتحية def يليها إسمها euler5 المتبوع ب () ثم :

2. المتغيرة i هي التي ستتزايد قيمتها تصاعديا حتى تصل إلى الرقم الذي يمكنه القسمة على جميع الأعداد من 1 إلى 20
3. المتغيرة seq هي قائمة بالأرقام التي سيتم إستخدامها كقاسم. القائمة تحتوي على كل الأعداد من 2 إلى 20
4. الحلقة شرطية while. و بالصيغة التي كُتبت بها فستبقى تدور إلى الأبد أو حتى يتم كسرها بتعليمة break أو return

5. الحلقة التسلسلية for التي تدور من أول عدد في القائمة seq إلى آخر عدد فيها. في كل دورة تأخد المتغير j قيمة العدد التالي من القائمة
6. الجملة الشرطية if التي تقوم بإجراء القسمة لإختبار قيمة الباقي هل هي 0 أم لا. إدا كان الباقي (و ليس الخارج) لا يساوي 0 يتم كسر الحلقة for بواسطة التعليمة break و ذلك لنختصر المسافة لأنه لا دعي لإختبار كل الأعداد المتبقية في القائمة seq إن كان العدد الذي نحن بصدده باقي قسمته لا بساوي 0. بمعنى ليس قاسما طبيعيا. و بعد دلك ينتقل الكود للسطر الذي يحتوي على i += 20 حتى يتم الصعود بقيمة 20 في كل دورة من دورات الحلقة while.
7. أما إدا كانت كل الأعداد المتواجد في القائمة seq تقبل القسمة بشكل طبيعي على قيمة المتغيرة i، فبالضرورة إدن أن قيمة المتغيرة j ستكون مساوية ل 20 و ذلك لأنه آخر رقم في القائمة قابل للقسمة بشكل طبيعي. بمعنى أننا إجتزنا كل الأعداد في القائمة حتى وصلنا إلى 20. و بعد التأكد من ذلك نخرج من الدالة euler5() بنتيجة المتغيرة i و تم عرضها من طرف الدالة print


الحل الثاني (يتوصل إلى النتيجة بشكل آني):
def isPrime(value):
    for i in range(2, value):
        if value % i == 0:           
            return False
    return True


def sumMultiply(seq):
    r = 1
    for i in seq:
        r = r * i
    return r


def findDivisible(value, seq=[]):
    multiplier = 1   
    while True:
        for i in seq:
            if (value * multiplier) % i != 0:
                multiplier += 1
                break
            elif i == seq[-1]:
                return (value * multiplier)


nbr = 20
divs = [x for x in range(nbr, 1, -1)]
primes = sumMultiply(filter(isPrime, divs))

print findDivisible(primes, divs)

الشرح:
يبدو و كانه صعب لكنه سهل :)

1. قمنا بإضافة دالة isPrime(value) التي ستقوم بمعرفة هل العدد الذي حصلت عليه من المعيار value أهو عدد أولي ام لا. هذه الدالة سيتم إعتمادها و تحسينها في مشاكل مستقبلية.
2. دالة sumMultiply(seq) تقوم بإعطا الخارج بعد قيامها بعملية ضرب كل أعداد القائمة seq في بعضها البعض.
3. دالة findDivisible(value, seq=[]) تقوم بالبحث عن أول قاسم للأعداد التي توصلت بها من القائمة seq.

فكرة هذا الحل هو إيجاد الأعداد الأولية في قائمة الأعداد من 2 إلى 20 ثم إجراء عملية ضرب بعضها في بعض، و العدد الذي نحصل عليه من هذه العملية يتم إستخدامه كأساس/كمنطلق يتم إستخدامه للبحث عن مضاعف له يقبل القسمة على كل الأعداد من 2 إلى 20. و هذا هو ماتقوم به الأسطر الأخيرة.

يونيو 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


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

يونيو 07، 2009

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

المشكلة رقم 3:
العوامل الرئيسية (prime factors) للعدد 13195 هي 5، 7، 13 و 29.

المطلوب:
ما هو أعلى عامل رئيسي للعدد 600851475143 ؟

الحل:
nbr = 600851475143
i = 1
factor = 0

while i + 1 <= nbr :
   
    i = i + 1
   
    if nbr % i == 0:
        factor = i
        nbr = nbr // i


print  factor

الشرح:
هذه المشكلة تحتاج إلى بعض الوقت من أجل التفكير لإيجاد حل بطرقة مختصرة لأن العدد الذي نتعامل معه أكبر من 600 مليار، و أية خوارزمية (algorithm) عادية ستأخد وقتا طويلا.

الطرقة التي إتبعتها هي كالتالي:
  • ابحث عن أول قاسم طبيعي ثم استخدم خارج القسمة كالعدد الذي نبحث له عن العامل الرئيسي.
  • هذه العملية تتكرر في حلقة حتى تستنزف كل الأرقام.
شرح الشفرة المصدرية (كود):
1. نستخدم ثلاثة متغيرات: nbr لتعبر عن العدد المعطى لنا في البداية، i التي سنستخدمها كقاسم، ثم factor التي ستحتوي على أعلى عامل رئيسي.
2. نستخدم الحلقة الشرطية while لاستنزاف كل الأرقام و العوامل الرئيسية.
3. i = i+1 فكل دورة من دورات الحلقة تتزايد قيمة المتغيرة i بـ 1
4. إدا كانت قيمة i كقاسم طبيعي لقيمة المتغيرة nbr يتم حفض العامل الرئيسي الذي عثرنا عليه و المعبر عليه بقيمة i حاليا في المتغيرة factor، و من ثم إستخدام الخارج  كالعدد الجديد بحيث نقوم بإسناده إلى المتغيرة nbr
5. في النهاية يتم عرض آخر (أعلى) عامل رئيسي توصلنا إليه و المعبر عنه من خلال المتغيرة factor

التسلسل الذي اتبعته الحلقة هو كالتالي:
i= 71     nbr= 8462696833
i= 839   nbr= 10086647
i= 1471 nbr= 6857
i= 6857 nbr= 1

يونيو 06، 2009

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

المشكلة رقم 2:
كل عدد جديد في متتالية فيبوناتشي يتشكل من مجموع العددين السابقين له.

و باستخدام 1 و 2 ستكون 10 العناصر الأولى كالتالي:
1,2,3,5,8,13,21,34,55,89,...

المطلوب:
ابحث عن مجموع الأعداد الزوجية في السلسلة التي لا يتجاوز أكبر عنصر فيها 4 ملايين.

الحل:
a, b = 1, 2
fibsum = 0

while  b <= 4000000:
   
    if  b % 2 == 0:
        fibsum += b

    a, b = b, a + b

print  fibsum

الشرح:
1. نقوم بإستعمال متغيرتين a و b. نعطي للأولى 1 كقيمة و للثانية 2 كقيمة.
2. نستعمل متغيرة بإسم fibsum قيمتها في البداية هي 0 و سنستعملها لتخزين مجموع الأعداد الزوجية التي سنكتشفها عند القيام بحساب متتالية فيبوناتشي.
3. سنقوم بإستخدام حلقة while و هذا النوع من الحلقات يستمر في الدوران حول نفسه ما دام الشرط صحيح. الشرط الذي إستخدمناه هو "ما دامت قيمة b أصغر من 4000000"
4. عند كل دورة من دورات الحلقة يتم التحقق من قابلية قسمة قيمة المتغيرة b على 2، و حيث يكون الباقي هو 0
5. إذا كان الشرط صحيحا تتم عملية جمع قيمة b بمجموع قيمة fibsum ثم تحديث هذه الأخيرة بالنتيجة التي حصلنا عليها من عملية الجمع.
6. في السطر الذي يحتوي على a, b = b, a + b يتم إسناد قيمة المتغيرة b إلى a و إسناد مجموع قيمة a+b إلى b في آن واحد.
7. عند الإنتهاء الحلقة من الدوران (عندما يصبح شرطها خاطئا) يتم عرض النتيجة (قيمة المتغيرة fibsum)


هل توصلتم إلى طريقة أخرى؟

يونيو 05، 2009

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

سنحاول معا أن نتعلم بايثون من خلال إيجاد حلول لمشاكل المشروع Euler Project. في كل يوم سأضع مشكلة جديدة و سأضع الحل الذي توصلت إليه بعد يومين. أرجوا أن يشارك الكل بلغة البرمجة التي يفضلها.

سأكتب دروس مبسطة عن بايثون في نهاية هذا الأسبوع، و أنصح بقراءة 90 صفحة الأولى من كتاب بايثون للصديق أحمد يوسف.


المشكلة رقم 1:
إذا قمنا بجرد كل الأرقام الطبيعية تحت العدد 10 بحثا عن  مضاعفات العدد 5 أو 3 سنجد 3، 5، 6 و 9. و إذا قمنا بحساب مجموع هذه الأرقام سنجد الخارج هو 23.

المطلوب:
قم بحساب مجموع مضاعفات 3 أو 5 تحت العدد 1000.

الحل:
result = 0
for i in range(1, 999+1):
    if i % 3 == 0 or i % 5 == 0:
        result += i

print result

الشرح:
1. سنستعمل المتغيرة result تخزين المجموع. و في الداية ستكون قيمتها تساوي 0
2. علينا أن نبحث عن جميع الأرقام تحت العدد 1000 (من 1 إلى 999) عن مضاعفات 3 أو 5. و لترجمة ذلك إلى لغة بايثون نستعمل for i in range(1, 999+1) و التي ستقوم بالدوران في حلقة تبدأ من 1 و تنتهي قبل الألف بمعنى عند 999.
3. في كل مرحلة من مراحل دوران تلك الحلقة تكون المتغيرة i تمثل قيمة أو رقم المرحلة. بمعنى 1, 2, 3, إلى أن تصل إلى 999. و نحن سنقوم بإختبار قيمة المتغيرة i في كل دورة و نرى هل يكون الباقي يساوي 0 إذا تمت قسمتها على 3 أو 5 قسمة أعداد صحيحة (بمعنى دون إجراء القسمة لحساب الأرقام بعد الفاصلة.)
4. هذا الإختبار إما أن يكون صحيح أو خطأ. إذا كان صحيح نظيف قيمة المتغيرة i إلى المتغيرة result. إذا كانت نتيجة الإختبار خاطئة تكمل الحلقة دورانها إلى أن تجد مجددا قيمة يمكن قسمتها على 3 أو 5 بباق يساوي0
5. بعد الإنتهاء من الدوران على كل قيم الحلقة نقوم بعرض نتيجة المتغيرة result


للمتقدمين في بايثون:
هل هنالك حلا آخر؟ مثلا في سطر واحد؟

الحل في سطر واحد:
print  sum([ i for i in range(1, 999+1) if i%3 == 0 or i%5 == 0])