تحدي برمجي[004][سهل] : المصفوفة الاولية prime array

  • afaki

تسمى المصفوفة أولية إذا كان طولها (length) عددا أوليا وكان أي عدد أولي بداخلها يقع في فهرس (index) أولي

إذا تم إعطائك مصفوفة تحتوي على اعداد (integers) قم بإرجاع القيمة True إذا كانت أولية غير ذلك قم بإرجاع False

امثلة:

ex1 = [1,0,4,3,18]

هنا القيمة ستكون True لأن طول المصفوفة 5 و 3 عدد أولي يقع في الفهرس رقم 3

ex2 = [2112, 3224, 12334, 1244445]

هنا القيمةستكون False لأن طول المصفوفة ليس أوليا

تحقق من طول المصفوفة أولا
ex3 = []

القيمة False لأن المصفوفة فارغة

برمجة سعيدة


<?php 

// check if $number is prime return true otherwise return false
function isPrime($number)
{
    $x = str_repeat("1", $number);

    if( preg_match( '/^1?$|^(11+?)\1+$/', $x ) == 0 )
    {
        return true;
    }
    return false;
}


// check if array is prime or not
function isPreliminaryArray($array = [])
{
    // if count of array is not prime return false
    if(!isPrime(count($array))) return false;

    foreach($array as $key => $value)
    {
        // check if key is prime and his value is not prime -> return false
        if(isPrime($key) && !isPrime($value))
            return false;
    }

    // by default return true
    return true;
}


// how to use
$array = [5,5,5]; // its prime
// $array = [5,5]; // uts not prime 
echo (isPreliminaryArray($array) ? "its Prime Array" : "its not Prime Array");

هلا شرحت لنا الخوارزمية المُتبعة في تحديد العدد الأولي في التعبير القياسي:

/^1?$|^(11+?)\1+$/
mohab أضف ردا

أول جزء

^1?$|

يطابق 1 أو 0 (الرقمين غير أوليين).

ثاني جزء ^(11+?)\1+$ يحاول أولا أن يطابق أول 11 مع المتبقي من الواحدات (مرة أو أكثر، مثلا المتبقي 11 إذا العدد مطابق للتعبير القياسي، في هذه الحالة 4(1111)). إذا لم يتطابقوا يأخذ واحد زيادة (111) ويحاول أن يطابقهم مع الواحدات المتبقية (مرة أو أكثر). يكرر العملية حتى يجد أو يرجع خطأ، (لم يجد قاسم --> العدد أولي). مثلا:

العدد 5=11111
11 != 111
كرر:
111 != 11
كرر:
1111 != 1
كرر:
11111 != ""
العدد غير مطابق (أولي)

العدد 9 = 111111111
11 != 1111111
كرر:
111 == 111 111 (مطابقة مرتين)
العدد مطابق (غير أولي)

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

مجهول أضف ردا

التعبير القياسي يعمل على اكتشاف الارقام غير * الاولية* .

 preg_match( '/^1?$|^(11+?)\1+$/', $x ) == 0

0 تعني false

بداية الامر في السطر 

   $x = str_repeat("1", $number);

اعمل على استبدال العدد بالارقام واحد

مثلا ارسلت له 5 ستصبخ (11111)

بالنسبة للتعبير القياسي فهو يقوم بالتحقق ما اذا كان هذا العدد غير اولي

فـ 11 لا يعتبر اولي

111 اولي , وهكذا

التعبير القياسي /^1?$|^(11+?)\1+$/ لا يطابق 7 على سبيل المثال.

تحقق جيدا , فهو يعمل على جميع الارقام

أها، لم أنتبه أنك تحول الأرقام لواحدات أولا. حتى لو انتبهت لم أكن لأقتنع بالطريقة :)

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

من فهمي لطريقة عملها فإن تعقيدها O(n) . مثل الطرق الأخرى، لكن تبقى أنها مختصرة أكثر في الكتابة.

لست انا من اخترعها صديقي , دائما ما ابحث عن بعض الخدع في المدونات ما اراه جيد اقوم بتدوينه وحفظه , وهذه كانت احداها .

حتى لو انتبهت لم أكن لأقتنع بالطريقة

انا مثلك لم اقتنع حتى جربتها

نحتاج دوما لبعض الحيل ;)