Perfect Number
القاسم الحقيقي للعدد n هو قاسم موجب أصغر من n نفسه. العدد الكامل يساوي مجموع قواسمه الحقيقية: 6 = 1 + 2 + 3. يُعطى لك عدد صحيح موجب n. أعد true إذا كان n عددًا كاملًا، وfalse خلاف ذلك.
الدالة
- ninteger
- العدد الصحيح الموجب المراد اختباره
- تُرجعboolean
- صحيح إذا كان n يساوي مجموع قواسمه الحقيقية، وخطأ خلاف ذلك
القيود
1 ≤ n ≤ 108
أمثلة
- المدخلات
- n = 28
- المخرجات
- true
- الشرح
- القواسم الحقيقية للعدد
28هي1و2و4و7و14. مجموعها هو28، لذا فإن28عدد كامل.
- المدخلات
- n = 12
- المخرجات
- false
- الشرح
- القواسم الحقيقية للعدد
12هي1و2و3و4و6. مجموعها16، وهو أكبر من12.
- المدخلات
- n = 1
- المخرجات
- false
- الشرح
- لا يوجد للعدد
1أيُّ قاسمٍ حقيقي، لذا فإن المجموع هو0، وليس1.
+16 اختبارات مخفية عند الإرسال
سؤال إضافي
كل عدد كامل زوجي يكون على الصورة 2^(p-1) × (2^p-1) حيث يكون 2^p-1 عددًا أوليًا. هل يمكنك سرد جميع الأعداد الكاملة الأصغر من 10^8 باستخدام هذه الصيغة، دون اختبار كل عدد؟
تلميحات
افتحها واحدًا تلو الآخر. كل تلميح يكشف أكثر قليلًا.
اكتب القواسم الحقيقية للعدد
28. أيٌّ منها ستجد إذا نظرت فقط إلى الأعداد حتى5؟تأتي القواسم في أزواج: إذا كان
dيقسمn، فإنn / dيقسمه أيضًا. يكون أحد عنصري كل زوج أصغر من أو يساوي√n.ابدأ المجموع عند
1، وأعِدfalseعندما يكونn == 1، وكرّرdبدءًا من2ما دامd * d ≤ n. أضفdوn / d، لكن مرة واحدة فقط عندما يكونان متساويين.
الحل
يطلب التعريف حساب مجموع القواسم، والحلقة الواضحة تختبر كل عدد مرشح حتى n / 2. عندما يكون n = 10^8، فهذا يعني 5 × 10^7 عملية قسمة. تأتي القواسم في أزواج حاصل ضربها n، لذا يمكنك جمع كلا العنصرين من كل زوج، مع البحث حتى √n فقط، أي نحو 10^4 خطوة.
أضف كل قاسم حقيقي
صحيحة، لكنها لا تنتهي في أكبر الاختبارات
الفكرة
اتبع التعريف. جرّب كل قيمة لـ d بدءًا من 1 تصاعديًا، وعندما يتحقق n % d == 0، أضف d إلى المجموع الجاري. في النهاية، قارن المجموع بـ n. بالنسبة إلى 28، تلتقط الحلقة القيم 1 و2 و4 و7 و14، و1 + 2 + 4 + 7 + 14 = 28.
يمكنك التوقف عند n / 2. فالقاسم الذي لا يساوي n ينتج خارج قسمة لا يقل عن 2، لذا لا يمكن أن يزيد أبدًا على نصف n. وينطبق هذا الحد أيضًا على n = 1: إذ تُنفّذ الحلقة صفر مرة، ويبقى المجموع 0، وتكون الإجابة false.
تقسيم المجال إلى النصف لا يغيّر معدل النمو. عندما تكون n = 10^8، تظل الحلقة تُنفّذ 5 × 10^7 مرة، وتفعل ذلك لكل مُدخل بهذا الحجم، سواء أكان قاسمًا أم لا.
الخوارزمية
- عيّن
totalإلى0. - كرّر
dمن1إلىn / 2. - إذا كان
n % d == 0، فأضفdإلىtotal. - أعِد ما إذا كان
total == n.
def isPerfect(n):
total = 0
# No proper divisor of n is larger than n / 2.
for d in range(1, n // 2 + 1):
if n % d == 0:
total += d
return total == nاجمع أزواج القواسم حتى الجذر التربيعي
الفكرة
عندما يقسم d العدد n، فإن n / d يقسمه أيضًا. بالنسبة إلى 28، تكون الأزواج هي 1 × 28 و2 × 14 و4 × 7. في كل زوج، يكون أحد العددين على الأكثر √n، لأن ضرب عددين أكبر من √n يعطي ناتجًا أكبر من n. لذا فإن البحث حتى √n يمر بكل زوج مرة واحدة، وتضيف كلا العددين أثناء التقدم.
هناك عضوان يحتاجان إلى الانتباه. فالزوج 1 × n يتضمن n نفسه، وهو ليس قاسمًا حقيقيًا: ابدأ المجموع عند 1 والبحث عند 2. هذا البدء غير صحيح عندما يكون n = 1، إذ إن قاسمه الوحيد هو نفسه، لذا أعد false له أولًا. وعندما يكون n مربعًا كاملًا، يقترن الجذر بنفسه: في حالة 36، يجب إضافة 6 مرة واحدة لا مرتين، لأن 6 × 6.
اكتب الحد على الصورة d * d ≤ n، وهي صيغة تبقى ضمن الأعداد الصحيحة. عندما يكون n = 10^8، تتوقف الحلقة عند d = 10^4، لذا تُنفَّذ نحو 10^4 مرة بدلًا من 5 × 10^7.
الخوارزمية
- إذا كان
n == 1، فأعِدfalse. - عيّن
totalإلى1وdإلى2. - ما دام
d * d ≤ n: إذا كانdيقسمn، فأضِفd، وأضِفn / dأيضًا إذا كان مختلفًا عنd. - انتقل إلى قيمة
dالتالية. - أعِد ما إذا كان
total == n.
def isPerfect(n):
if n == 1:
return False
total = 1 # 1 divides every n > 1; n itself does not count
d = 2
while d * d <= n:
if n % d == 0:
total += d
partner = n // d
if partner != d: # a square root pairs with itself: add it once
total += partner
d += 1
return total == n
أخطاء شائعة وحالات حدّية
حيلة الأزواج قصيرة، وكل خطأ فيها يغيّر المجموع بمقدار قاسم واحد بالضبط.
- احتساب
nنفسه. يضيف الزوج1 × nالعددn، وعندها يبدو أن مجموع قواسم كل عدد أكبر منn. ابدأ المجموع من1والبحث من2. - اعتبار
1عددًا كاملًا. عندما يبدأ المجموع من1، تكون المقارنة للمدخل1هي1 == 1. مجموع قواسمه الحقيقية هو0، لذا عالج هذه الحالة قبل الحلقة. - إضافة الجذر التربيعي مرتين. القواسم الحقيقية للعدد
16هي1و2و4و8، ومجموعها15. إضافة4مرتين تعطي19. - التوقف عند
d * d < n. يؤدي ذلك إلى تخطي الجذر التربيعي بالكامل، فلا يُحتسب4في16مطلقًا. - استخدام حدّ مستمد من الجذر التربيعي ذي الفاصلة العائمة. في الدقة الأحادية، أو عندما تكون القيمة أكبر من
2^53في الدقة المزدوجة، قد تكون نتيجة الجذر التربيعي لعدد مربع كامل أقل بواحد، فيُسقط أحد القواسم. يبقى الاختبارd * d ≤ nضمن الأعداد الصحيحة، ولا يواجه هذه المشكلة مطلقًا.
أسئلة شائعة4
ما التعقيد الزمني للتحقق مما إذا كان العدد كاملًا؟
يستغرق جمع أزواج القواسم حتى √n زمنًا قدره O(√n) ومساحة قدرها O(1). بالنسبة إلى n = 10^8، يعادل ذلك نحو 10^4 خطوة. أما اختبار كل مرشح حتى n / 2 فيستغرق زمنًا قدره O(n)، أي نحو 5 × 10^7 خطوة للمدخل نفسه.
كم عدد الأعداد التامة الأقل من 10^8؟
خمسة: 6، 28، 496، 8128 و33550336. يقلّ عددها بسرعة. أما العدد التالي، 8589869056، فلا يتسع حتى في عدد صحيح من 32 بت.
هل توجد أعداد كاملة فردية؟
لا أحد يعرف. كل عدد كامل عُثر عليه حتى الآن زوجي. وقد استبعدت عمليات البحث وجود أعداد كاملة فردية أقل من 10^1500، لكن لا يوجد برهان يثبت استحالة وجودها. يجب أن تعمل دالتك انطلاقًا من التعريف، لا من افتراض أن المدخل زوجي.
ما الفرق بين الأعداد التامة والوفيرة والناقصة؟
قارن مجموع القواسم الحقيقية بالعدد. إذا تساويا، فالعدد كامل، مثل 28. وإذا كان المجموع أكبر، فالعدد زائد، مثل 12، الذي مجموع قواسمه 16. وإذا كان المجموع أصغر، فالعدد ناقص، مثل كل عدد أولي، الذي قاسمه الحقيقي الوحيد هو 1.
مسائل مشابهة
مسائل تعتمد على الأفكار نفسها. حلّ اثنتين أو ثلاث منها يثبّت النمط.
Python
def isPerfect(n):
# اكتب الكود هناالحالة 1
الحالة 2
الحالة 3
المدخلات
n = 28
المتوقع
true