الأعداد الأولية ولعبة الحذف
درس 11 من 11
11الأعداد الأولية ولعبة الحذف
الصورة الكبيرةلعبة الحذف تبدو معقّدة، لكن كل دور يحذف عددًا أوليًا واحدًا مع مضاعفاته، فعدد الأدوار يساوي عدد الأعداد الأولية. اللعبة كلها تتحوّل لسؤال: هل هذا العدد زوجي أم فردي؟
ماذا تشاهد في الرسم: الغربال: لكل عدد أولي تجده، اشطب مضاعفاته. ما يبقى بلا شطب أولي. وتكفي الأعداد حتى الجذر التربيعي لـ n.
خارطة هذا الجزء
المفاهيم بالترتيب، اضغط أيًّا منها للقفز إليه:
طريقان إلى نفس الفكرة
العدد الأولي لا يقسمه إلا 1 ونفسه، مثل 2 و3 و5 و7. لتجد كل الأوليات حتى 30، اكتب الأعداد، واشطب كل مضاعفات 2 (4، 6، 8...)، ثم مضاعفات 3، ثم 5. ما بقي هو الأوليات، دون أن تقسم أي عدد بنفسك.
الغربال O(n log log n) زمنًا وO(n) ذاكرة، ويبدأ الشطب من p*p لأن المضاعفات الأصغر شُطبت بعوامل أصغر. prefix[i] = عدد الأوليات ≤ i، فعدّ الأوليات في [1, n] هو prefix[n]. لعدة أسئلة: غربل مرة حتى max(n). في الألعاب بالتناوب مع لعب أمثل، لو كان عدد الحركات ثابتًا مهما لعب اللاعبان، يقرّر الزوجية الفائز: فردي يفوز الأول، وزوجي يفوز الثاني.
قبل أن تبدأ
🔁الحلقات والقوائم
تكتب حلقات بخطوة: range(a, b, step).
➗باقي القسمة
تعرف % والزوجي والفردي.
الفكرة الجوهرية
1غربال إراتوستينس
قائمة صح/خطأ لكل عدد، ونشطب المضاعفات بخطوة p:
def sieve(n):
is_prime = [False, False] + [True] * (n - 1)
p = 2
while p * p <= n:
if is_prime[p]:
for m in range(p * p, n + 1, p):
is_prime[m] = False
p += 1
return is_prime
flags = sieve(30)
print([i for i, ok in enumerate(flags) if ok])2المجموع البادئ
بعد الغربال، prefix[i] يخزّن عدد الأوليات حتى i. أي سؤال «كم أولي حتى n؟» يصبح قراءة خانة:
def sieve(n):
is_prime = [False, False] + [True] * (n - 1)
for p in range(2, int(n ** 0.5) + 1):
if is_prime[p]:
for m in range(p * p, n + 1, p):
is_prime[m] = False
return is_prime
questions = [5, 10, 1, 30]
flags = sieve(max(questions))
prefix, running = [], 0
for ok in flags:
running += ok
prefix.append(running)
for n in questions:
print(n, "->", prefix[n], "primes")3تمرين: من يفوز؟
لعبة: الأعداد من 1 إلى n على الطاولة. لاعبان يتناوبان، وفي كل دور يختار اللاعب عددًا أوليًا موجودًا ويحذفه مع كل مضاعفاته. من لا يجد عددًا أوليًا يخسر. لاحظ أن كل دور يحذف عددًا أوليًا واحدًا بالضبط (مضاعفاته ليست أولية)، فعدد الأدوار = عدد الأوليات حتى n. اكتب دالة تأخذ قائمة أسئلة (قيم n) وتعيد من فاز أكثر جولات، مستخدمًا الغربال والمجموع البادئ. اختبر: n = 1 لا أوليات فيخسر الأول.
مثال محلول
المسألة: n = 6. التحليل: الأوليات 2 و3 و5. الدور 1: الأول يحذف 2 (ومعه 4 و6). الدور 2: الثاني يحذف 3. الدور 3: الأول يحذف 5. الدور 4: الثاني لا يجد أوليًا. النتيجة: 3 أدوار، عدد فردي، الأول يفوز، ولم نحتج محاكاة: يكفي prefix[6] = 3.
خرافة مقابل حقيقة
| الخرافة | الحقيقة |
|---|---|
| 1 عدد أولي. | لا. الأولي له قاسمان مختلفان بالضبط، و1 له قاسم واحد. |
| يجب محاكاة اللعبة حركة حركة. | عدد الحركات ثابت، فالزوجية تكفي. |
أين تقابله في العمل
🔐التشفير
RSA يقوم على أعداد أولية كبيرة.
#️⃣جداول التجزئة
أحجام أولية تقلّل التصادمات في بعض التصاميم.
اختبر فهمك
لماذا يبدأ الشطب من p*p؟
مثلًا 2×5 شُطب عند 2، فنبدأ مع 5 من 25.
كم عددًا أوليًا حتى 10؟
2 و3 و5 و7.
في اللعبة، n = 10. من يفوز؟
4 أوليات، عدد زوجي، فالثاني يأخذ الدور الأخير.
بطاقات مراجعة سريعة
تحقق من فهمك
لماذا نتوقف عند √n؟
لأن أي عدد مركّب ≤ n له عامل ≤ √n، فشُطب قبل ذلك.
مئة سؤال بقيم n مختلفة، كم غربالًا تحتاج؟
واحد فقط حتى أكبر n.
ماذا لو n = 1؟
لا أوليات، فاللاعب الأول لا يجد حركة ويخسر.
مصادر هذا الدرس
مرتّبة بالنوع. ابدأ بالتوثيق الرسمي إذا تبي المرجع الدقيق، وبالمقال أو الفيديو إذا تبي الشرح أولًا.
خلّصت الدرس؟
سجّل الدخول ليُحفظ تقدّمك.