article cover image
تعلم البرمجة: البرمجة التنافسية، أول خطوات تعلم البرمجة - Competitive programming
علوم الحاسب 15 دقيقة 4 تعليق 2985 مشاهدة
صورة المستخدم دريد عبدالله
مهندس برمجيات
تم النشر 2022-10-02 00:47:02 - آخر تحديث 2022-10-02 00:57:03

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

كما ذكرت في تلك المقالة، قد يكون الدخول في مجال البرمجة التنافسية من أفضل الطرق لتعلم أسس التفكير المنطقي وتعزيز مهاراته، هذا ما يسهل عملية تعلم البرمجة والعمل في مجال البرمجيات.

ماهي البرمجة التنافسية - Competitive Programming

هي نوع من أنواع "الرياضة العقلية"، تتضمن مشاركين يقومون بكتابة برامج حاسوبية لأداء مهام محددة أو حل مسائل منطقية معينة.

ماهو شكل المسألة (أو التحدي)؟

المسألة (Problem) هي عبارة توصيف قد يكون لحالة واقعية، أو تخيلية، مثال بسيط جدا: لديك سلسلة نصية (String) معين، يجب عليك كتابة برنامج يقوم بطباعة أكثر الكلمات تكراراً في هذا النص. في مثل هذه المسألة، يكون دخل البرنامج هو نص، ويجب على البرنامج ايجاد الحل الصحيح مهما كان الدخل.

يمكنك ممارسة البرمجة التنافسية إما من خلال مواقع البرمجة التنافسية (عبر الانترنت)، كما ويمكنك المشاركة في مسابقات البرمجة التنافسية التي تقام على الأرض، أو عبر الانترنت.

مواقع البرمجة التنافسية (Online competitive programming)

هناك العديد من المواقع على الانترنت، التي تساعدك في ممارسة وتعلم البرمجة التنافسية ومواضيعها المختلفة.
بإمكانك أن تجد في مثل هذه المواقع العديد من المسائل البرمجية والتحديات، ويمكنك رفع كودك (code) الخاص لحل هذه المسائل باستخدام العديد من لغات البرمجة، حيث يقوم الموقع باختبار الحل وتقييمه من خلال ما يدعى بـ (Online Judging System). تقوم مثل هذه الأنظمة بترجمة الكود، وتشغيله، وتجربته على العديد من حالات الاختبار (إعطاء البرنامج دخل معين، معاينة الخرج، ومقارنته مع النتيجة المتوقعة).
كما وتقوم العديد من هذه المواقع بتنظيم مسابقات برمجية دورية يمكنك أيضا المشاركة بها، إما للتدرب، او الحصول على جائزة.
من أمثلة هذه المواقع: spoj.com، codeforces.com وغيرها الكثير، يمكنك الاطلاع على هذه القائمة ببعض مواقع البرمجة التنافسية.
بعض هذه المواقع تذهب أبعد من موضوع البرمجة التنافسية وتساعدك في تعلم العديد من علوم الحاسب الأخرى، كما وتساعدك في التحضير لمقابلات العمل. مثلا: Hackerrank، Interviewbit، LeetCode وغيرها.

المسابقات البرمجية

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

الأولمبياد الدولي للمعلوماتية (International Olympiad in Informatics - IOI)  (ويكيبيديا)

وهي مسابقة تقام بشكل سنوي، كل سنة باستضافة دولة مختلفة، يقوم فيها المتسابقون النخبة المختارون من شتى الدول بالتنافس بشكل فردي لحل مجموعة من المسائل البرمجية الصعبة، وعادة تستهدف الأشخاص ماقبل مرحلة التعليم الجامعي.

المسابقة الدولية البرمجية للجامعات (International Collegiate Programming Contest - ICPC)

وهي مسابقة دولية تقام بشكل سنوي، تستهدف طلاب الجامعات، تستضيفها كل سنة جامعة مختلفة، يتنافس فيها فرق مكونة من ثلاث أشخاص، يتم اختيار هذه الفرق من قبل جامعاتهم بعد المرور بعدة تصفيات (حيث قد تبدأ بمسابقات على مستوى الجامعة، ثم القطر، ثم المسابقة الاقليمية وأخيرا العالمية)، وتهدف الى تعزيز مهارات حل المشاكل، وروح العمل كفريق لدى المتسابقين، كما وتساعد في وصلهم مع الشركات العالمية المختلفة. تنظم هذه المسابقة منظمة ACM وترعاها الكثير من الشركات العالمية مثل IBM, JetBrains وغيرها، بالاضافة الى الكثير من الراعيين المحليين لباقي التصفيات.

Google Code Jam (ويكيبيديا)

وهي مسابقة مماثة تنظمها شركة Google، تتضمن حل مجموعة من المسائل البرمجية التي تتطلب مهارات تفكير عالية.
تساعد هذه المسابقات (كذلك غيرها) غوغل على اختيار الأشخاص الأكثر تميزا.

أهمية البرمجة التنافسية

بالنسبة للعموم، ليس الهدف إجراء المسابقة والفوز بالميدالية بحد ذاته، فهذا الموضوع يعود للشخص نفسه، إنما تساعد البرمجة التنافسية عموما في جوانب عدة:

المهارات المكتسبة

الخوض في غمار البرمجة التنافسية يفتح الأذهان باتجاه نوع معين من رياضة العقل، أو التحديات الفكرية التي يتوجب على المتدرب حلها. كذلك تتطلب البرمجة التنافسية الاطلاع على (وأحيانا اتقان) بعض الجوانب من علوم الحاسب، مثل الخوارزميات (Algorithms)، بنى المعطيات أو هياكل البيانات (Data Structures)، نظرية التعقيد (Complexity Theory) وغير ذلك. هذه المهارات أساسية جدا عند العمل في مجال البرمجة.

مقابلات العمل

حاول أن تلقي نظرة على مقابلات العمل التي يخضع لها من يتقدم للعمل كمبرمج لدى شركات مثل Google، Amazon او أي شركة أخرى ضخمة. ستجد أنه على المتقدم أن يقوم بحل بضع مسائل من نفس نوع المسائل التي تجدها في مسابقات البرمجة التنافسية، وعادة ما تكون هذه المسائل على درجة كافية من الصعوبة.

إذا باختصار، الدخول في هذا المجال يساعدك في تعلم مهارات أساسية، بدورها ستساعدك في زيادة فرصك بشكل كبير أثناء البحث عن عمل في مجال البرمجة.

هل يمكنني البدء حالاً في مجال البرمجة التنافسية؟

سأخبرك الآن ما ينبقي عليك فعله للدخول في مجال البرمجة التنافسية.

- للبدء في مجال البرمجة التنافسية، ستحتاج الى معرفة أساسيات إحدى لغات البرمجة (Programming Language)، إذ انك ستقوم بكتابة الحلول البرمجية باستخدام لغة البرمجة، سأخبرك أكثر عما تحتاجه من لغة البرمجة.

- بالاضافة الى لغة البرمجة، قد تحتاج الى معرفة أساسيات الرياضيات، لا تقلق، أعتقد أنه لديك ما تحتاجه منها بالفعل.

- كما وقد تحتاج الى بعض المعرفة بمفاهيم الخوارزميات وبنى المعطيات. ليس بالضروري أن يكون لديك الخبرة المسبقة في مجال الخوارزميات وبنى المعطيات، فمن وجهة نظري، دخولك في مجال البرمجة التنافسية يجب أن يدفعك الى التعلم أكثر عن هذه المواضيع، لكن أبقها في ذهنك. من امثلة الخوارزميات المعيارية التي يمكنك دراستها خلال تعلمك: خوارزميات البحث (Search Algorithms)، خوارزميات الترتيب (Sorting Algorithms)، خوارزميات البيان (Graph Algorithms) وغير ذلك، ومن أمثلة بنى المعطيات المعيارية: القوائم المترابطة (Linked Lists)، المكدس (Stack)، الرتل (Queue)، البيان (Graph)، وغير ذلك.

تعلم لغة البرمجة

بالنسبة للغة البرمجة، ليس من الضروري اتقان لغة البرمجة كي تبدأ في مجال البرمجة التنافسية، بل يكفي معرفة كيفية الاستخدام البسيط لإحدى لغات البرمجة بشكل أساسي. من وجهة نظري، يجب أن تستطيع ابراز المهارات التالية في واحدة من لغات البرمجة:

- القدرة على كتابة البرامج البسيطة وتشغيها

- الإدخال والإخراج من/الى الدخل/الخرج المعياري standard input/output، أو من/الى الملفات

- تعريف المتحولات (variables) والمصفوفات (arrays) واستخدامها

- استخدام العبارات الشرطية وحلقات التكرار

- تعريف التوابع واستدعاءها (اختياري للبداية)

بالنسبة للغات البرمجة التي يمكنك استخدامها، يمكنك نظريا استخدام أي لغة، فمعظم المواقع (والمسابقات) تسمح لك باستخدام تشكيلة واسعة من اللغات، مثل C++, Java, Python, Javascript, Ruby, Perl...

شخصيا، من أجل البرمجة التنافسية، أنصحك بتعلم واستخدام لغة مثل C++, Java او ما يشابهها، أكثر من استخدام لغة مثل Python, Ruby, Javascript. السبب وراء ذلك أن هذه اللغات الأخيرة تصنف كلغات عالية المستوى، وقد لا تعطيك السيطرة الكافية على طريقة تنفيذ الكود (إذ انها توفر ميزات اضافية قد يكون من الأفضل أن تتعلمها وتطبقها بنفسك بدلا من استخدامها جاهزة). في حال أن اللغات مثل C++ او Java مهيكلة أكثر، وتدفعك للتفكير في كل خطوة في كودك بشكل أعمق.

على أي حال، اذا كان لديك معرفة جيدة باحدى اللغات وترغب في استخدامها حالا، فلا مانع من ذلك.

مراجع لتعلم لغة البرمجة

حاولت إجراء بعض الأبحاث السريعة لإيجاد بعض الموارد المتوفرة لتعليم لغة البرمجة (ركزت بحثي على لغة C++)، إليك بعضها

تعلم لغة C++ في خمس ساعات (فيديو - يوتيوب)

وجدت هذا الدرس التعليمي جيد، حيث أنه يشرح جميع المفاهيم الأساسية التي تحتاجها للبدء في مجال البرمجة التنافسية. ليس عليك إلا ممارسة هذه الفاهيم كي تحترفها.

Fundementals of C++ Programming (كتاب - بالانكليزية)

كتاب شامل لتعليم جميع ما يتعلق بلغة C++.

C++ Tutorial (موقع - بالانكليزية)

موقع انترنت يساعدك في تعلم اللغة ومفاهيمها المختلفة.

للأسف، لم أجد كتب احترافية متوفرة عبر الانترنت باللغة العربية لتعليم لغة C++، لكن هناك العديد من الكتب والمساهمات الفردية المكتوبة من قبل الآخرين، يمكنك استخدام محركات البحث لايجادها والتعلم منها. كما ويمكنك اقتراح أي كتب قد تجدها مفيدة من خلال التعليقات. 

مراجع لممارسة البرمجة التنافسية وتعلم مواضيعها

كما ذكرنا، خلال رحلتك في البرمجة التنافسية، ستحتاج الى تعلم الكثير من المفاهيم في الخوارزميات (algorithms)، بنى المعطيات (data structures) وغيرها، بالإضافة الى تعلم بعض الخوارزميات وبنى المعطيات المعيارية، كما وستحتاج الى ممارسة هذه المفاهيم خلال رحلتك. هناك عدد غير محدود من المراجع المتوفرة على الانترنت لمساعدتك في هذه المواضيع.

مراجع لتعلم الخوارزميات وبنى المعطيات

موقع geeksforgeeks.org (بالانكليزية)

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

يمكنك من خلال هذا الموقع تعلم الكثير حول:

- الخوارزميات (مقدمة عامة، انواع الخوارزميات، الخوارزميات المعيارية مثل خوارزميات البحث search، خوارزميات الترتيب sorting، خوارزميات البيان graph، وغير ذلك الكثير)

- بنى المعطيات (معناها، أنواعها، أشهر بنى المعطيات وكيفية تطبيقها مثل المصفوفات arrays، القوائم المترابطة linked lists، الأرتال queues، المكدسات stacks، الأشجار الثنائية binary trees، البيان graph وغيرها الكثير).

 كما ويحتوي محتوى تعليمي في شتى المواضيع المختلفة، بما فيها لغات البرمجة والتحضير لمقابلات العمل.

قناة Hard-code (بالعربية - يوتيوب)

قمت بالبحث عن المراجع الموجودة في اللغة العربية، ووجدت هذا المحتوى من قناة Hard-code جيد، فهو يغطي معظم المفاهيم بطريقة واضحة وبلغة عربية فصحى، مرفقا برسوم توضيحية وأحيانا عينات من الكود. لكنني أشجعك بشدة على عدم الاكتفاء بالفيديو، بل الاطلاع ايضا على الموارد النصية (من موقع Geeksforgeeks مثلا) لتعزيز ما تعلمته، كما وأشجعك على ممارسة هذه المفاهيم ومحاولة تطبيقها.

- كورس الخوارزميات

- كورس بنى المعطيات

التعلم من خلال الممارسة

تقدم معظم المواقع التي ذكرتها في هذه المقالة طرق ممنهجة لتعليم مواضيع البرمجة التنافسية من خلال الممارسة.

مثلا، موقع Hackerrank (قد يحتاج الى VPN من سوريا) يساعدك في ايجاد المسائل التي تركز على مواضيع معينة. مثلا، يمكنك بالنظر الى هذه القائمة ايجاد العديد من المسائل التي تركز على الخوارزمية، في حين أن هذه القائمة تحتوي على العديد من المسائل التي تتطلب التعامل مع بنى المعطيات. 

هكذا تبدو الواجهة الرئيسية للتعلم في موقع Hackerrank

صفحة التعلم في موقع Hackerrankوهنا قائمة ببعض المسائل المتعلقة ببنى المعطيات

قائمة مسائل تتعلق ببنى المعطياتكما تلاحظ، يقوم الموقع بتصنيف كل مسألة بحسب الصعوبة، الصنف (او المهارة) التي ستتعلمها، كما وهناك امكانية لفلترة المسائل التي تركز على مواضيع معينة.أنصحك بتجربة الموقع حالا، وممارسة حل بعض المسائل.

مثال تطبيقي - حل مسألة على أحد مواقع البرمجة التنافسية

أنصحك الآن بفتح أحد هذه المواقع، مثلا  HackerRank لإنشاء حساب (أو تسجيل الدخول)، ثم دعنا نحاول حل هذه المسألة البسيطة للغاية.

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

يقوم نص المسألة بتزويدك بمثال للدخل، وبالخرج المتوقع (مجموع الأعداد).

كما ويتم توصيف صيغة الدخل، في هذه الحالة، الدخل مكون من سطرين: السطر الأول يحتوي على عدد صحيح (n) يمثل عدد الأعداد المطلوب جمعها، وفي السطر الثاني يوجد n عدد مفصولين بمسافات. كما ويصف مجالات الأعداد: العدد n اصغر من ١٠٠٠، كذلك جميع الأعداد في المصفوفة.

تذكر، يجب على برنامجك أن يعمل على أي دخل معطى ضمن الحدود المعطاة.

بالنسبة لصيغة الخرج الموصوفة: سطر وحيد يحتوي على عدد وحيد يمثل مجموع عناصر المصفوفة.

في القسم الأيمن، نجد نافذة الكود، هنا يمكنك إدخال الحل الخاص بك للمسألة. عادة ما نبدأ باختيار لغة البرمجة المناسبة من القائمة المنسدلة في الأعلى. نلاحظ وجود قالب مكتوب مسبقا لجعل مهمتك أسهل، وتم تزويدك بتابع  simpleArraySum يجب عليك كتابة محتوى التابع. يتلقى هذا التابع مصفوفة الأعداد كوسيط له، ويجب عليك إرجاع الخرج (مجموع هذه الأعداد). حاول أن تقوم بإكمال جسم التابع بنفسك.

في حالات أخرى أو مواقع أخرى، بدلا من تزويدك بتابع يجب عليك إتمامه، قد يتوجب عليك القيام بقراءة الدخل بنفسك من الدخل المعياري او من ملف، كما وقد يتوجب عليك طباعة الخرج إلى الخرج المعياري أو ملف، وفق الصيغ المحددة.

حل المسألة السابقة بسيط جدا، كل ماعليك كتابته هو حلقة تكرار تمر على جميع العناصر في المصفوفة وتقوم بجمع قيمها. قم بوضع الكود التالي ضمن جسم التابع simpleArraySum

int sum = 0;
for(int i=0; i < ar.size(); i++)
    sum += ar[i];
return sum;

ليصبح الكود بالشكل التالي

بعد كتابة هذا الكود، قم بالضغط على Run Code حيث يتم تشغيل الكود واختباره مقابل حالة الاختبار المذكورة في الوصف. 

إذا نجحت العملية، يمكنك (بعد التأكد من صحة الكود) القيام بالضغط على Submit Code لرفع كودك. سيقوم النظام باختبار كودك مقابل جميع حالات الاختبار المخفية لمعرفة إذا ماكان حلك صحيح أو لا.

لاحظ وجود عدة تابات عمودية في القسم الأيسر من الشاشة, جرب الدخول الى قسم Discussions لمشاهدة النقاشات حول المسألة.

جرب الآن استعراض باقي المسائل في الموقع وحل بعضها الآخر بنفسك.

في الختام

قمنا من خلال هذه المقالة باستعراض مفهوم البرمجة التنافسية كوسيلة وخطوة مهمة في طريقك لتعلم البرمجة، وتعلم مهارات حل المشاكل، كما وقمنا بتقديم العديد من الموارد والمراجع التي يمكنك استخدامها خلال رحتلك.

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

لا تتردد في التفاعل مع المقال من خلال التعليقات، لطرح أسئلتك، مشاركة معارفك أو ما تعلمته في هذا المجال، أو أي مواد مفيدة ترغب في مشاركتها مع الآخرين.


صورة الغلاف من موقع Geeksforgeeks

التعليقات (4)
  • صورة المستخدم يوشع يوسف
    2022-10-02 21:32:45

    مقال ممتاز

  • صورة المستخدم يوشع يوسف
    2022-10-02 21:42:19

    أرجو الكتابة حول موقع Github وهل هناك اختلاف بين نسخة الموبايل ونسخة الكمبيوتر

    • صورة المستخدم دريد عبدالله
      2022-10-02 22:39:16

      شكرا لاقتراحك يوشع! أنصحك بمراجعة مقالي "مقدمة الى Git، الأداة التي يجب على كل مبرمج اتقانها" رابط المقال:
      https://oufok.com/article/view/bbf4ed3535714d8a8bc3d8f5e359a512
      وهو يشرح أنظمة التحكم بالمصدر (موقع GitHub هو مخزن يمكن استخدامه مع Git بالاضافة الى انه يوفر ميزات تكامل متعددة). أوردت مثال عن استخدام موقع GitHub في هذا المقال.
      أخبرني إذا كان هذا المقال يجيب على أسئلتك، أو اذا كنت تقصد شيئا مختلفاً!

  • صورة المستخدم Ali Mohamad
    2022-10-03 19:15:06

    الله يعطيك العافية 👏🏻👏🏻