دليل شامل: بناء محول أرقام رومانية ومخطط تفاعلي متقدم باستخدام JavaScript

دقائق القراءة: 6

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

ما هي الأرقام الرومانية؟

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

تُشكل الأرقام الرومانية من خلال مجموعات من حروف الأبجدية اللاتينية، والتي تعمل كـ “أرقام” في هذا النظام. على عكس نظام الأساس العشري الذي يستخدم الرموز من 0 إلى 9، يستخدم النظام الروماني سبعة أحرف لاتينية كبيرة هي: I، V، X، L، C، D، M. في الأصل، لم يكن هناك حرف واحد مخصص للصفر، بل كانوا يستخدمون الكلمة اللاتينية Nulla، والتي تعني “لا شيء”.

كيف تعمل الأرقام الرومانية؟

التمثيل الهندي-العربي لهذه الحروف هو كالتالي:

  • I = 1
  • V = 5
  • X = 10
  • L = 50
  • C = 100
  • D = 500
  • M = 1000

تُشكل الأرقام الأخرى بدمج هذه الحروف وفقًا لقواعد معينة:

قاعدة الإضافة

إذا وُضع رمز بعد رمز آخر له قيمة مساوية أو أكبر، تُضاف قيمته. على سبيل المثال:

  • VI = V + I = 5 + 1 = 6. تُقرأ VI على أنها “واحد أكثر من خمسة”.
  • LX = L + X = 50 + 10 = 60. تُقرأ LX على أنها “عشرة أكثر من خمسين”.

قاعدة الطرح

إذا وُضع رمز قبل رمز آخر له قيمة أكبر، تُطرح قيمته. على سبيل المثال:

  • IX = XI = 10 – 1 = 9. تُقرأ IX على أنها “واحد أقل من عشرة”.
  • XC = CX = 100 – 10 = 90. تُقرأ XC على أنها “عشرة أقل من مائة”.

الأرقام الأكبر من 1000

تُشكل الأرقام الأكبر من 1,000 بوضع خط فوق الرمز. هكذا، = 5,000، = 10,000، = 50,000، = 100,000، = 500,000، و = 1,000,000.

الشكل “القياسي” والاستثناءات

يمنع الشكل “القياسي” استخدام الرمز نفسه أكثر من ثلاث مرات متتالية. لكن في بعض الأحيان، يمكن رؤية استثناءات. على سبيل المثال، IIII للرقم 4، و VIIII للرقم 9، و LXXXX للرقم 90.

مخطط تفاعلي للأرقام الرومانية وتوليفاتها

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

على سبيل المثال، يمكن أن يعرض المخطط رموزًا مثل: I، II، III، IV، V، VI، VII، VIII، IX، X، XX، XXX، XL، L، LX، LXX، LXXX، XC، C، CC، CCC، CD، D، DC، DCC، DCCC، CM، M، ، ، ، ، ، .

المخطط التفاعلي المذكور في النص الأصلي قد تم تطويره باستخدام ملف HTML واحد يضم عناصر <style> و <script> للتصميم والوظائف، بدلاً من فصلها إلى ملفات HTML و CSS و JavaScript منفصلة. هذا النهج قد يكون مفيدًا في بيئات التضمين المحدودة. يمكن العثور على مستودع الشفرة الكامل للمخطط التفاعلي هنا.

بناء محول الأرقام الرومانية

الآن، دعنا ننتقل إلى الجزء العملي: بناء محول يحول الأرقام العربية إلى مكافئاتها الرومانية. هذا المحول سيقبل عددًا صحيحًا غير سالب بين 0 و 5,000، ثم يحوله إلى الرقم الروماني المقابل.

حدود التحويل

لا يوجد قيد برمجي على الرقم 5,000 أو ما بعده؛ فالخوارزمية التي تحكم التحويل ستعمل بنفس الطريقة. ومع ذلك، فإن المساحة المطلوبة لعرض المكافئات الرومانية للأرقام الكبيرة تزداد بشكل كبير دون إضافة فائدة كبيرة في الكشف عن شيء جديد، مما يجعل نطاق 5,000 نطاقًا عمليًا ومناسبًا للعرض.

هيكلة الشفرة

تتكون الشفرة نفسها من جزء HTML يصف المحتوى مع أنماط مضمنة (inline styles) لسهولة التفاعل، و JavaScript مضاف للوظائف. يوجد عنصر إدخال من نوع "number" لتقييد بيانات الإدخال بالقيم الرقمية، وزرين. الزر "Convert" (تحويل) مرتبط بالدالة التي تقوم بالتحويل، بينما الزر "Display" (عرض) يُخرج المكافئ الروماني.

للتوضيح، يتم تعيين هذه العناصر لمتغيرات JavaScript كالتالي:

const inputField = document.querySelector('input'); // input element
const convertButton = document.getElementById('convert'); // convert button
const outputField = document.getElementById('display'); // output element

منطق دالة التحويل convertToRoman()

تحتوي الدالة convertToRoman() على المنطق الرئيسي للتحويل وتعرض النتيجة. إليك هيكلها الأولي:

function convertToRoman() {
    let arabic = document.getElementById('arabicNumeral').value; // input value
    let roman = ''; // variable that will hold the result
}

تُحفظ القيمة الرقمية من عنصر الإدخال في متغير يسمى arabic للاختبارات اللاحقة. بينما سيحتفظ المتغير المسمى roman بالسلسلة النصية التي تمثل المكافئ الروماني للمدخل العربي.

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

// descending order simplifies subtraction while looping
const arabicArray = [5000, 4000, 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
const romanArray = ['V̅', 'MV̅', 'M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I'];

تساعد جداول يونيكود (Unicode) في تشكيل الرموز الأكبر من 1,000، مثل الخط العلوي ̅ المستخدم في .

المنطق الأساسي للتحويل

أخيرًا، إليك المنطق الذي يختبر الرقم المدخل ويقوم بتحويله:

if (/^(0|[1-9]\d*)$/.test(arabic)) { // Regular expression tests
    if (arabic == 0) { // for decimal points and negative
        outputField.innerHTML = "Nulla"; // signs
    } else if (arabic != 0) {
        for (let i = 0; i < arabicArray.length; i++) {
            while (arabicArray[i] <= arabic) {
                roman += romanArray[i];
                arabic -= arabicArray[i];
            }
        }
        outputField.innerHTML = roman;
    }
} else {
    outputField.innerHTML = "Please enter non negative integers only. No decimal points.";
}

يتحقق الاختبار الأول باستخدام تعبير نمطي (Regular Expression) مما إذا كان الرقم المدخل عددًا صحيحًا غير سالب. إذا تم العثور على نقاط عشرية أو إشارات سالبة، فستظهر رسالة تطلب “إدخال أعداد صحيحة غير سالبة فقط”.

يتحقق الاختبار التالي مما إذا كان الرقم المدخل يساوي صفرًا. في هذه الحالة، تُعرض السلسلة النصية "Nulla". بخلاف ذلك، تستمر الحلقات (loops) في دمج السلاسل الرومانية مع طرح الأرقام العربية حتى يفي الرقم العربي بالشرط المحدد لحلقة while. ثم يعرض المكافئ الروماني لإدخال المستخدم.

تمامًا كما هو الحال مع المخطط التفاعلي، تم إعداد شفرة محول الأرقام الرومانية بالكامل لتتمكن من نسخها وتضمينها في أي مقال. يمكن العثور على مستودع الشفرة الكامل هنا.

الخلاصة التقنية

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

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *