Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

دالة الاستدعاء الذاتي: العاملي

جزء من قسم Logic & Flow في رحلة Dart على Coddy — الدرس 49 من 65.

مضروب العدد هو عملية رياضية كلاسيكية مثالية لتوضيح مفهوم العودية (recursion). مضروب العدد الصحيح الموجب n (والذي يُكتب n!) هو حاصل ضرب جميع الأعداد الصحيحة الموجبة من 1 إلى n. على سبيل المثال، 5! = 5 × 4 × 3 × 2 × 1 = 120.

ما يجعل المضروب (factorial) مثالياً للعودية (recursion) هو أنه ينقسم بشكل طبيعي إلى مشكلات أصغر ومتطابقة. لحساب !5، يمكنك التفكير فيه على أنه !4 × 5. و !4 هو ببساطة !3 × 4، وهكذا. يستمر هذا النمط حتى تصل إلى !1، والذي يساوي 1.

int factorial(int n) {
  if (n <= 1) {
    return 1; // الحالة الأساسية
  }
  
  return n * factorial(n - 1); // الخطوة العودية
}

تتوقف الحالة الأساسية عن الاستدعاء الذاتي عندما n <= 1، حيث تعيد 1. تقوم الخطوة الاستدعائية بضرب الرقم الحالي في مضروب الرقم الأصغر التالي. عندما تستدعي factorial(5)، فإنها تعيد 5 * factorial(4)، والتي تعيد 5 * 4 * factorial(3)، وهكذا حتى تصل إلى الحالة الأساسية.

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

challenge icon

التحدي

سهل

قم بإنشاء برنامج يحسب المضروب (factorials) لعدة أرقام باستخدام العودية (recursion). سيقوم برنامجك باستعراض دالة المضروب العودية من خلال معالجة قائمة من الأرقام وحساب مضروباتها.

  1. اقرأ مدخلاً نصياً يحتوي على أرقام مفصولة بفاصلة (على سبيل المثال، "3,5,0,7")
  2. قم بتقسيم النص المدخل إلى أرقام فردية وحوّل كل منها إلى عدد صحيح (integer)
  3. أنشئ دالة عودية تسمى factorial تأخذ معاملًا صحيحًا n
  4. يجب أن تنفذ دالة factorial المنطق التالي:
    • الحالة الأساسية (Base case): إذا كانت n أقل من أو تساوي 1، فقم بإرجاع 1
    • الخطوة العودية (Recursive step): قم بإرجاع n مضروبة في factorial(n - 1)
  5. لكل رقم في القائمة المدخلة، احسب المضروب الخاص به باستخدام دالتك العودية
  6. اعرض النتائج موضحاً كل رقم والمضروب المقابل له
  7. احسب واعرض مجموع جميع نتائج المضروب

على سبيل المثال، إذا كان المدخل هو "4,3,2"، يجب أن يخرج برنامجك:

Factorial Calculator
====================
Processing numbers: [4, 3, 2]
====================
Factorial Results:
4! = 24
3! = 6
2! = 2
====================
Sum of all factorials: 32
Calculation completed successfully

إذا كان المدخل هو "5,0,1"، يجب أن يخرج برنامجك:

Factorial Calculator
====================
Processing numbers: [5, 0, 1]
====================
Factorial Results:
5! = 120
0! = 1
1! = 1
====================
Sum of all factorials: 122
Calculation completed successfully

إذا كان المدخل هو "6"، يجب أن يخرج برنامجك:

Factorial Calculator
====================
Processing numbers: [6]
====================
Factorial Results:
6! = 720
====================
Sum of all factorials: 720
Calculation completed successfully

يجب أن يقوم برنامجك بتنفيذ دالة factorial العودية التي تستدعي نفسها بقيم متناقصة حتى تصل إلى الحالة الأساسية. يجب أن توضح الدالة كيف تقوم العودية بتفكيك حساب المضروب إلى مشكلات فرعية أصغر ومتطابقة. استخدم استكمال السلسلة النصية (string interpolation) لتنسيق نتائج المضروب كـ "$n! = $result". تذكر أن !0 يساوي 1 حسب التعريف الرياضي، وهو ما يجب أن تتعامل معه الحالة الأساسية بشكل صحيح.

ورقة مرجعية

مضروب العدد الصحيح الموجب n (الذي يُكتب n!) هو حاصل ضرب جميع الأعداد الصحيحة الموجبة من 1 إلى n. على سبيل المثال، 5! = 5 × 4 × 3 × 2 × 1 = 120.

يُعد المضروب مثالياً للعودية (recursion) لأنه ينقسم إلى مشكلات أصغر ومتطابقة: 5! = 5 × 4!، و 4! = 4 × 3!، ويستمر ذلك حتى الوصول إلى 1! = 1.

int factorial(int n) {
  if (n <= 1) {
    return 1; // الحالة الأساسية
  }
  
  return n * factorial(n - 1); // الخطوة العودية
}

تتوقف الحالة الأساسية عن العودية عندما يكون n <= 1، حيث تُرجع القيمة 1. أما الخطوة العودية فتقوم بضرب الرقم الحالي في مضروب الرقم الأصغر التالي.

جرّب بنفسك

import 'dart:io';

// TODO: أنشئ دالة المضروب (factorial) العودية هنا

void main() {
  // قراءة سلسلة الإدخال التي تحتوي على أرقام مفصولة بفاصلة
  String? input = stdin.readLineSync();
  
  // تقسيم الإدخال وتحويله إلى أعداد صحيحة
  List<int> numbers = input!.split(',').map((str) => int.parse(str.trim())).toList();
  
  // TODO: اكتب الكود الخاص بك أدناه من أجل:
  // 1. معالجة كل رقم باستخدام دالة المضروب الخاصة بك
  // 2. حساب مجموع كل قيم المضروب
  // 3. عرض النتائج بالتنسيق المطلوب
  
  print("Factorial Calculator");
  print("====================");
  print("Processing numbers: $numbers");
  print("====================");
  print("Factorial Results:");
  
  // TODO: احسب واعرض نتائج المضروب هنا
  
  print("====================");
  // TODO: عرض مجموع كل قيم المضروب
  print("Calculation completed successfully");
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس Logic & Flow