في إحدى الأمسيات، عثرت على دفتر قديم مليء بخربشات غامضة، وكأن أحدهم كان يطارد فكرة بلا هوادة. في إحدى الصفحات، برز سؤال واحد: هل يستطيع كل عدد أن يجد طريقه إلى 1؟ وكان مرتبطًا بشيء يُسمى حدسية كولاتز، وهي أحجية حيّرت المفكرين لعقود.
كانت القواعد بسيطة ظاهريًا. اختر أي عدد صحيح موجب.
ثم كرّر هذه الخطوات على الناتج، واستمر بلا نهاية.
وبدافع الفضول، اخترت العدد 12 لتجربته وبدأت الرحلة:
12 ➜ 6 ➜ 3 ➜ 10 ➜ 5 ➜ 16 ➜ 8 ➜ 4 ➜ 2 ➜ 1
وبالعدّ من العدد الثاني (6)، استغرقت تسع خطوات للوصول إلى 1، وفي كل مرة كانت القواعد تتكرر، كان العدد يتغير باستمرار. في البداية، بدا التسلسل غير متوقع، يقفز صعودًا وهبوطًا وفي كل اتجاه. ومع ذلك، تؤكد الحدسية أنه مهما كان عدد البداية، فسننتهي دائمًا عند 1.
كان الأمر مذهلًا، لكنه محيّر أيضًا. لماذا يبدو هذا ناجحًا دائمًا؟ هل يمكن أن يوجد عدد تتعطل عنده العملية، فيدور في حلقة لا نهاية لها أو يهرب إلى ما لا نهاية؟ أشار الدفتر إلى أن حل هذه المسألة قد يكشف شيئًا عميقًا، ومعه ينتظر الشهرة والثروة ومكانة في التاريخ كل من يستطيع فك ألغازها.
بالنظر إلى عدد صحيح موجب، أرجِع عدد الخطوات اللازمة للوصول إلى 1 وفقًا لقواعد حدسية كولاتز.
أحيانًا تحتاج إلى رفع استثناء. وعندما تفعل ذلك، ينبغي أن تُضمّن دائمًا رسالة خطأ ذات معنى تُبيّن مصدر الخطأ. فهذا يجعل الكود أسهل في القراءة ويساعد كثيرًا في تصحيح الأخطاء. وفي الحالات التي تعرف فيها أن مصدر الخطأ سيكون من نوع معيّن، يمكنك أن تختار رفع أحد أنواع الأخطاء المضمّنة، لكن ينبغي أن تُضمّن رسالة ذات معنى رغم ذلك.
لا تهتم حدسية كولاتز إلا بـ الأعداد الصحيحة الموجبة تمامًا، لذلك يتوقع منك هذا التمرين أن تستخدم عبارة raise وأن «ترمي» ValueError في حلّك إذا كانت القيمة المعطاة صفرًا أو عددًا صحيحًا سالبًا. لن تنجح الاختبارات إلا إذا قمت بـ raise على exception وضمّنت معه رسالة.
ولرفع ValueError مع رسالة، اكتب الرسالة كوسيط لنوع exception:
# example when argument is zero or a negative integer
raise ValueError("Only positive integers are allowed")
سجّل في Exercism لتتعلّم وتتقن Python عبر 17 مفهومًا146 تمرينًا، وإرشاد بشري حقيقي، وكل ذلك مجانًا.