Leap Year
October 5, 2018
This is just a matter of performing the tests in the right order:
(define (leap? n)
(if (positive? (modulo n 4)) #f
(if (positive? (modulo n 100)) #t
(if (positive? (modulo n 400)) #f
#t))))
> (leap? 2018)
#f
> (leap? 2016)
#t
> (leap? 2000)
#t
> (leap? 2100)
#f
You can run the program at https://ideone.com/54HPvM. It is astonishing how many ways there are to get this wrong; about half the responses to the user who posted the question on the internet were incorrect. Which is why this makes a good exercise, even if it looks simple.
Klong version
leap::{:[0=x!4;:[0=x!100;:[0=x!400;1;0];1];0]}Examples:
{.p(x,” –> “,leap(x))}'[2018 2016 2000 2100];””
[2018 –> 0]
[2016 –> 1]
[2000 –> 1]
[2100 –> 0]
“”
Here are two solutions in Python.
def is_leap_year1(y): return (y % 4 == 0) and ((y % 100 != 0) or (y % 400 == 0)) def is_leap_year2(y): if y % 4: return False if not (y % 400): return True return (y % 100) != 0 for i in range(1, 2019): leap1 = is_leap_year1(i) leap2 = is_leap_year2(i) assert leap1 == leap2 if leap1: print(i)Output:
A Haskell version.
Built-in in Ruby
require 'date'; Date.parse("2020-01-01").leap?=> true
Here’s a short one in Python, two of the mods can be replaced with bitmasks (if we don’t have to worry about negative years):
Recently covered this question in an MATLAB introductory course, so here’s a nice version for vector (or scalar) inputs:
function leap = is_leap_year(year)
mask = mod(year, 100) == 0;
year(mask) = year(mask) / 100;
leap = mod(year, 4) == 0;
end
@Appable: is that like “if year%100 == 0: year //= 100; return year%4 == 0” but for vectorized inputs (‘year(mask)’ is something like ‘the elements of year that have a 1 in mask’)? Interesting.