2
\$\begingroup\$

I wrote two functions for determining leap years. ("Kabisat" means "leap year" in Indonesia.)

def kabisat? y
 return false if y%4!=0 
 return true if y%100!=0 
 y%400==0 
end
def kabisat_2? y
 return true if y%400==0 
 return false if y%100==0 
 y%4==0 
end 
require 'date';
(1..Date.today.year).each { |y|
 puts y if kabisat?(y)!=kabisat_2?(y)
}

Is it correct? And it is possible to write a shorter one?

asked Mar 14, 2013 at 7:48
\$\endgroup\$
5
  • 4
    \$\begingroup\$ Why not use the built-in Date#leap? method? In any event, your kabisat_1 function is broken. It'll return true for, say, 2013, because it's not divisible by 100. But 2013 certainly isn't a leap year. \$\endgroup\$ Commented Mar 14, 2013 at 10:06
  • \$\begingroup\$ no it is not? kabisat? 2013 == false \$\endgroup\$ Commented Mar 14, 2013 at 10:30
  • \$\begingroup\$ Yes, your method checks y%4!=0 first, so it'll return the right thing. But reversing the checks is suspect. The logic is that "if a year is divisible by 100, it's not a leap year". But that does not mean, that every year that isn't divisible automatically is a leap year. I.e. the check against 100 can only can only tell you if something's not a leap year; it can't tell you if it is. \$\endgroup\$ Commented Mar 14, 2013 at 10:55
  • \$\begingroup\$ You should test it with some corner cases, e.g. 1900, 2000, 2004. \$\endgroup\$ Commented Mar 14, 2013 at 11:32
  • 1
    \$\begingroup\$ Why don't u google? rosettacode.org/wiki/Leap_year#Ruby \$\endgroup\$ Commented Mar 14, 2013 at 23:34

1 Answer 1

3
\$\begingroup\$

Some notes:

  • I assume that, for some reason, you want to write your own function/method instead of the existing Date#leap? that @Flambino linked above.
  • kabisat? We all love our mother tongue, but in computing English is the lingua franca, specially when you share your code with people around the world. It's a nice word to learn, though :-)
  • This is a personal advice, not all Ruby programmers agree: don't use inline returns. Use the good old full-fledged conditionals, it's much more clear. In general, use expressions instead of statements.

Let's see the standard algorithm. Ok, I'll just translate it to Ruby (if I felt fancy I'd even add Integer#divisible_by?(n) for a fully declarative code):

def is_leap_year?(year)
 if year % 400 == 0 
 true
 elsif year % 100 == 0
 false
 elsif year % 4 == 0
 true
 else
 false
 end
end

Too verbose? use boolean logic:

def is_leap_year?(year)
 (year % 400 == 0) || (year % 100 != 0 && year % 4 == 0)
end
answered Mar 14, 2013 at 10:37
\$\endgroup\$
1
  • \$\begingroup\$ i like the boolean logic :3 \$\endgroup\$ Commented Mar 14, 2013 at 12:05

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.