Leap year: Difference between revisions

From Rosetta Code
Content added Content deleted
Line 104: Line 104:
end program leap</lang>
end program leap</lang>

Output:

<lang> F T F T </lang>


=={{header|Haskell}}==
=={{header|Haskell}}==

Revision as of 00:00, 17 August 2010

Task
Leap year
You are encouraged to solve this task according to the task description, using any language you may know.

Determine whether a given year is a leap year.

See Also

ActionScript

<lang actionscript>public function isLeapYear(year:int):Boolean {

   if (year % 100 == 0) {
       return (year % 400 == 0);
   }
   return (year % 4 == 0);

}</lang>

ALGOL 68

Works with: ALGOL 68 version Revision 1 - no extensions to language used
Works with: ALGOL 68G version Any - tested with release 1.18.0-9h.tiny

<lang algol68>MODE YEAR = INT, MONTH = INT, DAY = INT;

PROC year days = (YEAR year)DAY: # Ignore 1752 CE for the moment #

 ( month days(year, 2) = 28 | 365 | 366 );

PROC month days = (YEAR year, MONTH month) DAY:

 ( month | 31,
           28 + ABS (year MOD 4 = 0 AND year MOD 100 /= 0 OR year MOD 400 = 0),
           31, 30, 31, 30, 31, 31, 30, 31, 30, 31);

PROC is leap year = (YEAR year)BOOL: year days(year)=366;

test:(

 []INT test cases = (1900, 1994, 1996, 1997, 2000);
 FOR i TO UPB test cases DO
   YEAR year = test cases[i];
   printf(($g(0)" is "b("","not ")"a leap year."l$, year, is leap year(year)))
 OD

)</lang> Output:

1900 is not a leap year.
1994 is not a leap year.
1996 is a leap year.
1997 is not a leap year.
2000 is a leap year.

C/C++

<lang c>#include <stdio.h>

  1. include <stdbool.h>

bool is_leap_year(int year) {

 return !(year%4) && year%100 || !(year%400);

}

int main(){

 int test_case[] = {1900, 1994, 1996, 1997, 2000}, key;
 for(key=0; key<sizeof test_case/sizeof test_case[0]; key++){
   int year = test_case[key];
   printf("%d is %sa leap year.\n", year, is_leap_year(year)?"":"not ");
 }

}</lang> Output:

1900 is not a leap year.
1994 is not a leap year.
1996 is a leap year.
1997 is not a leap year.
2000 is a leap year.

Clojure

<lang clojure>(defn leap-year? [y]

 (and (zero? (mod y 4)) (or (pos? (mod y 100)) (zero? (mod y 400)))))</lang>

Common Lisp

<lang lisp> (defun leap-year-p (year)

 (destructuring-bind (fh h f)
     (mapcar #'(lambda (n) (zerop (mod year n))) '(400 100 4))
   (or fh (and (not h) f))))</lang>

Forth

<lang forth>: leap-year? ( y -- ? )

 dup 400 mod 0= if drop true  exit then
 dup 100 mod 0= if drop false exit then
       4 mod 0= ;</lang>

Fortran

<lang fortran>program leap

implicit none
write(*,*) leap_year([1900, 1996, 1997, 2000])
contains

pure elemental function leap_year(y) result(is_leap) implicit none logical :: is_leap integer,intent(in) :: y

is_leap = (mod(y,4)==0 .and. .not. mod(y,100)==0) .or. (mod(y,400)==0)

end function leap_year

end program leap</lang>

Output:

<lang> F T F T </lang>

Haskell

Simple version <lang haskell> import Data.List import Control.Monad import Control.Arrow

leaptext x b | b = show x ++ " is a leap year" | otherwise = show x ++ " is not a leap year"

isleapsf j | 0==j`mod`100 = 0 == j`mod`400 | otherwise = 0 == j`mod`4 </lang> Algorithmic <lang haskell> isleap = foldl1 ((&&).not).flip map [400, 100, 4]. ((0==).).mod </lang> Example using isleap <lang haskell>

  • Main> mapM_ (putStrLn. (ap leaptext isleap)) [1900,1994,1996,1997,2000]

1900 is not a leap year 1994 is not a leap year 1996 is a leap year 1997 is not a leap year 2000 is a leap year </lang>

Icon and Unicon

Gives leap year status for 2000,1900,2012 and any arguments you give <lang Icon>procedure main(arglist) every y := !([2000,1900,2012]|||arglist) do

 write("The year ",y," is ", leapyear(y) | "not ","a leap year.")

end

procedure leapyear(year) #: determine if year is leap

  if (numeric(year) % 4 = 0 & year % 100 ~= 0) | (numeric(year) % 400 = 0) then return

end </lang>

Icon

Unicon

The Icon solution works in Unicon.

J

<lang j>isLeap=: 0 -/@:= 4 100 400 |/ ]</lang>

Example use:

<lang> isLeap 1900 1996 1997 2000 0 1 0 1</lang>

Java

<lang java>new java.util.GregorianCalendar().isLeapYear(year)</lang>

or <lang java>public static boolean isLeapYear(int year){

   if(year % 100 == 0) return year % 400 == 0;
   return year % 4 == 0;

}</lang>

JavaScript

<lang javascript>function isLeapYear(year) {

   if (year % 100 == 0) {
       return (year % 400 == 0);
   }
   return (year % 4 == 0);

}</lang>

Liberty BASIC

Simple method

<lang lb>if leap(1996)then

   print "leap"

else

   print "ordinary"

end if wait

function leap(n)

   leap=date$("2/29/";n)

end function</lang>

Calculated method

<lang lb> year = 1908

   select case
       case year mod 400 = 0
           leapYear = 1
       case year mod 4 = 0 and year mod 100 <> 0
           leapYear = 1
       case else
           leapYear = 0
   end select
   if leapYear = 1 then
       print year;" is a leap year."
   else
       print year;" is not a leap year."
   end if</lang>

<lang logo>to multiple? :n :d

 output equal? 0 modulo :n :d

end to leapyear? :y

 output ifelse multiple? :y 100 [multiple? :y 400] [multiple? :y 4]

end</lang>

MUMPS

<lang MUMPS>ILY(X) ;IS IT A LEAP YEAR?

QUIT ((X#4=0)&(X#100'=0))!((X#100=0)&(X#400=0))</lang>

Usage:

USER>W $SELECT($$ILY^ROSETTA(1900):"Yes",1:"No")
No
USER>W $SELECT($$ILY^ROSETTA(2000):"Yes",1:"No")
Yes
USER>W $SELECT($$ILY^ROSETTA(1999):"Yes",1:"No")
No

OCaml

<lang ocaml>let is_leap_year ~year =

 if (year mod 100) = 0
 then (year mod 400) = 0
 else (year mod 4) = 0</lang>

Using Unix Time functions:

<lang ocaml>let is_leap_year ~year =

 let tm =
   Unix.mktime {
     (Unix.gmtime (Unix.time())) with
       Unix.tm_year = (year - 1900);
       tm_mon = 1 (* feb *);
       tm_mday = 29
     }
 in
 (tm.Unix.tm_mday = 29)</lang>


Oz

<lang oz>declare

 fun {IsLeapYear Year}
    case Year mod 100 of 0 then

Year mod 400 == 0

    else

Year mod 4 == 0

    end
 end

in

 for Y in [1900 1996 1997 2000] do
    if {IsLeapYear Y} then

{System.showInfo Y#" is a leap year."}

    else

{System.showInfo Y#" is NOT a leap year."}

    end
 end</lang>

Output:

1900 is NOT a leap year.
1996 is a leap year.
1997 is NOT a leap year.
2000 is a leap year.

Perl

<lang Perl>sub leap {

   my $yr = $_[0];
   if ($yr % 100 == 0) {
       return ($yr % 400 == 0);
   }
   return ($yr % 4 == 0);

}</lang>

Or more concisely:

<lang Perl>sub leap {!($_[0] % 100) ? !($_[0] % 400) : !($_[0] % 4)}</lang>

Using library function/method:

<lang Perl>use Date::Manip; Date_LeapYear($year);

use Date::Manip::Base; my $dmb = new Date::Manip::Base; $dmb->leapyear($year);</lang>

Perl 6

Works with: Rakudo version 2010.07

<lang perl6>say "$year is a {Date.is-leap-year($year) ?? 'leap' !! 'common'} year."</lang>

In Rakudo 2010.07, Date.is-leap-year is implemented as

<lang perl6>multi method is-leap-year($y = $!year) {

   $y %% 4 and not $y %% 100 or $y %% 400

}</lang>

PHP

<lang php><?php function isLeapYear(year) {

   if (year % 100 == 0) {
       return (year % 400 == 0);
   }
   return (year % 4 == 0);

}</lang>

With date('L'):

<lang php><?php function isLeapYear(year) {

   return (date('L', mktime(0, 0, 0, 2, 1, year)) === '1')

}</lang>

PicoLisp

<lang PicoLisp>(de isLeapYear (Y)

  (bool (date Y 2 29)) )</lang>

Output:

: (isLeapYear 2010)
-> NIL

: (isLeapYear 2008)
-> T

: (isLeapYear 1600)
-> T

: (isLeapYear 1700)
-> NIL

PL/I

<lang PL/I> declare year picture '9999'; /* 16 August 2010 */ get edit (year) (f(4)); if days(year || '1231', 'YYYYMMDD') - days(year || '0101', 'YYYYMMDD') = 365 then

  put ( year || ' is a leap year');

else

  put (year || ' is not a leap year');

</lang>

PureBasic

<lang PureBasic>Procedure isLeapYear(Year)

 If (Year%4=0 And Year%100) Or Year%400=0
   ProcedureReturn #True
 Else
   ProcedureReturn #False
 EndIf

EndProcedure</lang>

Python

<lang python>import calendar calendar.isleap(year)</lang>

or <lang python>def is_leap_year(year):

   if year % 100 == 0:
       return year % 400 == 0
   return year % 4 == 0</lang>

Asking for forgiveness instead of permission:

<lang python>import datetime

def is_leap_year(year):

   try:
       datetime.date(year, 2, 29)
   except ValueError:
       return False
   return True</lang>

Ruby

<lang ruby>require 'date' def is_leap_year(year)

 Date.new(year).leap?

end</lang>

SNOBOL4

Predicate leap( ) succeeds/fails, returns nil.

<lang SNOBOL4> define('leap(yr)')  :(end_leap) leap eq(remdr(yr,400),0) :s(return)

       eq(remdr(yr,100),0) :s(freturn)
   	eq(remdr(yr,4),0)   :s(return)f(freturn)

end_leap

  • # Test and display (with ?: kluge)
       test = "output = ('10' ? (*leap(yr) 1 | 0)) ': ' yr"
       yr = '1066'; eval(test)
       yr = '1492'; eval(test)
       yr = '1900'; eval(test)
       yr = '2000'; eval(test)

end</lang>

Output:

0: 1066
1: 1492
0: 1900
1: 2000

Tcl

The "classic" modulo comparison <lang tcl>proc isleap1 {year} {

   return [expr {($year % 4 == 0) && (($year % 100 != 0) || ($year % 400 == 0))}]

} isleap1 1988 ;# => 1 isleap1 1989 ;# => 0 isleap1 1900 ;# => 0 isleap1 2000 ;# => 1</lang>

Does Feb 29 exist in the given year? If not a leap year, the clock command will return "03-01" <lang tcl>proc isleap2 year {

   return [expr {[clock format [clock scan "$year-02-29" -format "%Y-%m-%d"] -format "%m-%d"] eq "02-29"}]

} isleap2 1988 ;# => 1 isleap2 1989 ;# => 0 isleap2 1900 ;# => 0 isleap2 2000 ;# => 1</lang>