1122-leap-year — Leap Year
Functional Programming
Tutorial
The Problem
A leap year in the Gregorian calendar occurs every 4 years, except for centuries (divisible by 100), which are only leap years if also divisible by 400. The rule has three conditions arranged in a specific priority: (divisible by 4) AND NOT (divisible by 100) OR (divisible by 400). This is a classic exercise in boolean logic and is the first date-calculation building block.
The Gregorian calendar reform in 1582 introduced this rule to keep the calendar aligned with the solar year (365.2425 days). Software that handles dates — from scheduling systems to financial calculations — must implement this rule correctly.
🎯 Learning Outcomes
Code Example
#![allow(clippy::all)]
//! Stub to satisfy cargo.
pub fn stub() {}Key Differences
&& binds tighter than || in Rust and OCaml, making the formula a || (b && c) without explicit parentheses — but adding them improves clarity.% / mod) for the divisibility checks; negative years behave differently in each language's modulo semantics.chrono crate**: Production Rust uses the chrono crate for date calculations; OCaml uses Calendar or Ptime.chrono handles this, raw implementations often do not.OCaml Approach
let is_leap_year year =
year mod 400 = 0 || (year mod 4 = 0 && year mod 100 <> 0)
Identical logic. OCaml uses mod instead of % and <> instead of != for not-equal, but the boolean structure is the same.
Full Source
#![allow(clippy::all)]
//! Stub to satisfy cargo.
pub fn stub() {}Exercises
days_in_month(year: i32, month: u32) -> u32 using is_leap_year for February.day_of_year(year: i32, month: u32, day: u32) -> u32 that returns the ordinal day (1–365/366).quickcheck that verifies is_leap_year matches the chrono crate's answer for all years from 1 to 9999.