Leap Year
يُعطى لك عام year من التقويم الغريغوري. أعد true إذا كان عامًا كبيسًا، أي من الأعوام التي تضم 29 فبراير، وأعد false خلاف ذلك.
يكون العام كبيسًا إذا كان يقبل القسمة على 4، باستثناء الأعوام التي تقبل القسمة على 100، فهي ليست أعوامًا كبيسة إلا إذا كانت تقبل القسمة أيضًا على 400.
الدالة
- yearinteger
- السنة المطلوب التحقق منها
- تُرجعboolean
- true عندما يكون في السنة يوم 29 فبراير، وfalse بخلاف ذلك
القيود
1 ≤ year ≤ 106
أمثلة
- المدخلات
- year = 2024
- المخرجات
- true
- الشرح
- العدد
2024يقبل القسمة على4وليس سنة قرنية، لذا فهو سنة كبيسة.
- المدخلات
- year = 1900
- المخرجات
- false
- الشرح
1900يقبل القسمة على4، لكنه يقبل القسمة أيضًا على100ولا يقبل القسمة على400، لذا ينطبق استثناء السنوات المئوية، وهي ليست سنة كبيسة.
- المدخلات
- year = 2000
- المخرجات
- true
- الشرح
- العدد
2000يقبل القسمة على100، وهذا يستبعده، لكنه يقبل القسمة أيضًا على400، وهذا يعيده. إنه سنة كبيسة.
+16 اختبارات مخفية عند الإرسال
تلميحات
افتحها واحدًا تلو الآخر. كل تلميح يكشف أكثر قليلًا.
الباقي
0بعد القسمة على4هو القاعدة الأولى. ما السنوات التي تخالفها؟السنوات المئوية تكسر هذه القاعدة، ومضاعفات
400تكسر بدورها قاعدة السنوات المئوية. كل مضاعف لـ400هو أيضًا مضاعف لـ100و4، لذا فإن ترتيب عمليات التحقق هو ما يحدد الإجابة.تحقّق أولًا من قابلية القسمة على
400، ثم على100، ثم على4، ودع أول قاعدة تنطبق تحسم الأمر. أو اجمعها: يقبل القسمة على 4 ولا يقبل القسمة على 100، أو يقبل القسمة على 400.
الحل
تحتاج كل قاعدة إلى باقي واحد فقط، لذا يتكوّن العمل من ثلاثة اختبارات للقسمة. تكمن المعضلة في الترتيب: تتعارض القواعد على سنوات مثل 2000، فهي سنة قرنية ومضاعف لـ 400 أيضًا. اختبر القاعدة الأكثر تحديدًا أولًا، أو اكتب القاعدة كتعبير واحد تُبقي أقواسه الاستثناءات في مواضعها.
تحقّق من القواعد بدءًا من الأكثر تحديدًا وصولًا إلى الأقل تحديدًا
الفكرة
تشكّل القواعد الثلاث سلسلةً من الاستثناءات. القابلية للقسمة على 4 تجعل السنة كبيسة، والقسمة على 100 تلغي ذلك، والقسمة على 400 تلغي الإلغاء. السنة التي تنطبق عليها قاعدة لاحقة تنطبق عليها دائمًا القواعد السابقة أيضًا: كل مضاعف لـ 400 هو مضاعف لـ 100، وكل مضاعف لـ 100 هو مضاعف لـ 4.
لذا، فالقاعدة الأكثر تحديدًا من بين القواعد المنطبقة هي التي تحدد الإجابة. اختبر 400 أولًا، ثم 100، ثم 4، وأعِد النتيجة فور انطباق إحدى القواعد. بالنسبة إلى 2000، يعطي الاختبار الأول الإجابة «نعم» مباشرةً. وبالنسبة إلى 1900، يفشل الاختبار الأول وتكون إجابة الاختبار الثاني «لا». أما بالنسبة إلى 2024، فيفشل الاختباران الأولان وتكون إجابة الاختبار الثالث «نعم».
إذا لم تنطبق أي من القواعد الثلاث، فالسنة غير قابلة للقسمة على 4 أصلًا، لذا فهي سنة عادية.
الخوارزمية
- إذا كان
year % 400 == 0، فأعِدtrue. - إذا كان
year % 100 == 0، فأعِدfalse. - إذا كان
year % 4 == 0، فأعِدtrue. - وإلا فأعِد
false.
def isLeapYear(year):
if year % 400 == 0:
return True
if year % 100 == 0:
return False
if year % 4 == 0:
return True
return Falseتعبير منطقي واحد
الفكرة
اقرأ القاعدة على أنها طريقتان لتكون السنة كبيسة. إما أن تكون السنة قابلة للقسمة على 4 وألا تكون سنة قرنية، أو أن تكون قابلة للقسمة على 400. تُترجم هذه الجملة حرفيًا إلى (year % 4 == 0 and year % 100 != 0) or year % 400 == 0.
تحقق من ذلك باستخدام الأمثلة الثلاثة. تجتاز 2024 النصف الأول. لا تجتاز 1900 النصف الأول لأنها سنة قرنية، ولا تجتاز النصف الثاني لأن 1900 % 400 تساوي 300. لا تجتاز 2000 النصف الأول للسبب نفسه الذي لم تجتزه 1900، وتجتاز النصف الثاني.
يمكنك أيضًا تجميعها بالطريقة الأخرى: قابلة للقسمة على 4، وإما ألا تكون سنة قرنية أو أن تكون من مضاعفات 400. تتفق الصيغتان على كل سنة. لا يُجري التعبير أكثر من الفحوصات الثلاثة نفسها التي تجريها سلسلة if.
الخوارزمية
- احسب
year % 4 == 0 and year % 100 != 0: يقبل القسمة على 4 وليس سنةً مئوية. - احسب
year % 400 == 0. - أعِد
trueإذا تحقق أيٌّ من الشرطين.
def isLeapYear(year):
# Every 4th year, except centuries, except every 400th year.
return (year % 4 == 0 and year % 100 != 0) or year % 400 == 0
أخطاء شائعة وحالات حدّية
ينشأ كل خطأ هنا من التعامل مع القاعدة على أنها اختبار واحد بدلًا من سلسلة من الاستثناءات.
- التحقق من
year % 4 == 0فقط. يعطي الإجابة الصحيحة لكل سنة من1901إلى2099، ولهذا يظل الخطأ خفيًا، ويعطي الإجابة الخاطئة للسنتين1900و2100. - اختبار
100قبل400في سلسلة if. يُرجع اختبار القرنfalseللسنة2000قبل أن يُنفَّذ اختبار400. - إسقاط شرط القسمة على 4. التعبير
year % 100 != 0 or year % 400 == 0يعتبر2023سنة كبيسة، لأن2023ليست سنة قرن. - استخدام
year / 4حين يكون المقصود هو الباقي. تخبرك القسمة بعدد المرات التي يتسع فيها4، أما الباقي فيخبرك ما إذا كان يتسع فيها تمامًا.
أسئلة شائعة4
ما قاعدة السنة الكبيسة؟
تكون السنة الميلادية سنة كبيسة إذا كانت تقبل القسمة على 4، ما لم تكن تقبل القسمة على 100. أما السنة التي تقبل القسمة على 400 فهي سنة كبيسة على أي حال. لذا فإن 2024 و2000 سنتان كبيستان، بينما 1900 و2100 ليستا كذلك.
لماذا لا تُعدّ سنة 1900 سنة كبيسة، بينما تُعدّ سنة 2000 كذلك؟
كلاهما سنتان من سنوات القرن، تقبلان القسمة على 100، وهذا يستبعد السنة عادةً. كما أن 2000 تقبل القسمة على 400، وهذه القاعدة تتجاوز قاعدة سنوات القرن. يتبقى 1900 منها 300 عند قسمتها على 400، لذا تظل سنة عادية.
لماذا توجد قواعد القرون؟
تستمر السنة الشمسية حوالي 365.2422 يومًا. تؤدي إضافة يوم كل 4 سنوات إلى متوسط قدره 365.25، أي نحو 3 أيام إضافية كل 400 عام. ويؤدي إسقاط يوم السنة الكبيسة في 3 من كل 4 سنوات قرنية إلى إزالة تلك الأيام الثلاثة. يصبح المتوسط 365.2425 يومًا، وهو قريب بما يكفي لإبقاء التقويم متوافقًا مع الفصول لآلاف السنين.
ما هو التعقيد الزمني للتحقق مما إذا كانت السنة كبيسة؟
تعقيد الزمن والمساحة هو O(1). يتطلب التحقق ثلاث عمليات باقي قسمة كحد أقصى وبعض المقارنات، مهما كان حجم السنة.
مسائل مشابهة
مسائل تعتمد على الأفكار نفسها. حلّ اثنتين أو ثلاث منها يثبّت النمط.
Python
def isLeapYear(year):
# اكتب الكود هناالحالة 1
الحالة 2
الحالة 3
المدخلات
year = 2024
المتوقع
true