# Is it a leap year?

This challenge is quite simple. You will take an input which will be a year from 1801 to 2400, and output if it is a leap year or not.

Your input will have no newlines or trailing spaces:

1954


You will output in any way that you like that clearly tells the user if it is or isn't a leap year (I will accept y or n for yes/no)

You can get a list of leap years here: http://kalender-365.de/leap-years.php I would note that leap years are not ever four years always. 1896 is a leap year, but 1900 is not. The years that follow this "skip" are:

1900
2100
2200
2300


Test cases:

1936 ->  y
1805 ->  n
1900 ->  n
2272 ->  y
2400 ->  y


EDIT: This is based on a standard Gregorian calendar: http://www.epochconverter.com/date-and-time/daynumbers-by-year.php

## The Catalogue

The Stack Snippet at the bottom of this post generates the catalogue from the answers a) as a list of shortest solution per language and b) as an overall leaderboard.

## Language Name, N bytes


where N is the size of your submission. If you improve your score, you can keep old scores in the headline, by striking them through. For instance:

## Ruby, <s>104</s> <s>101</s> 96 bytes


If there you want to include multiple numbers in your header (e.g. because your score is the sum of two files or you want to list interpreter flag penalties separately), make sure that the actual score is the last number in the header:

## Perl, 43 + 2 (-p flag) = 45 bytes


You can also make the language name a link which will then show up in the snippet:

## [><>](https://esolangs.org/wiki/Fish), 121 bytes


/* Configuration */

var QUESTION_ID = 50798; // Obtain this from the url
// It will be like https://XYZ.stackexchange.com/questions/QUESTION_ID/... on any question page
var COMMENT_FILTER = "!)Q2B_A2kjfAiU78X(md6BoYk";
var OVERRIDE_USER = 8478; // This should be the user ID of the challenge author.

/* App */

return "https://api.stackexchange.com/2.2/questions/" +  QUESTION_ID + "/answers?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + ANSWER_FILTER;
}

}

jQuery.ajax({
method: "get",
dataType: "jsonp",
crossDomain: true,
success: function (data) {
data.items.forEach(function(a) {
});
comment_page = 1;
}
});
}

jQuery.ajax({
method: "get",
dataType: "jsonp",
crossDomain: true,
success: function (data) {
data.items.forEach(function(c) {
if (c.owner.user_id === OVERRIDE_USER)
});
else process();
}
});
}

var SCORE_REG = /<h\d>\s*([^\n,<]*(?:<(?:[^\n>]*>[^\n<]*<\/[^\n>]*>)[^\n,<]*)*),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/;

function getAuthorName(a) {
return a.owner.display_name;
}

function process() {
var valid = [];

var body = a.body;
if(OVERRIDE_REG.test(c.body))
body = '<h1>' + c.body.replace(OVERRIDE_REG, '') + '</h1>';
});

var match = body.match(SCORE_REG);
if (match)
valid.push({
user: getAuthorName(a),
size: +match[2],
language: match[1],
});
else console.log(body);
});

valid.sort(function (a, b) {
var aB = a.size,
bB = b.size;
return aB - bB
});

var languages = {};
var place = 1;
var lastSize = null;
var lastPlace = 1;
valid.forEach(function (a) {
if (a.size != lastSize)
lastPlace = place;
lastSize = a.size;
++place;

.replace("{{NAME}}", a.user)
.replace("{{LANGUAGE}}", a.language)
.replace("{{SIZE}}", a.size)

var lang = a.language;
lang = jQuery('<a>'+lang+'</a>').text();

languages[lang] = languages[lang] || {lang: a.language, lang_raw: lang, user: a.user, size: a.size, link: a.link};
});

var langs = [];
for (var lang in languages)
if (languages.hasOwnProperty(lang))
langs.push(languages[lang]);

langs.sort(function (a, b) {
if (a.lang_raw.toLowerCase() > b.lang_raw.toLowerCase()) return 1;
if (a.lang_raw.toLowerCase() < b.lang_raw.toLowerCase()) return -1;
return 0;
});

for (var i = 0; i < langs.length; ++i)
{
var language = jQuery("#language-template").html();
var lang = langs[i];
language = language.replace("{{LANGUAGE}}", lang.lang)
.replace("{{NAME}}", lang.user)
.replace("{{SIZE}}", lang.size)
language = jQuery(language);
jQuery("#languages").append(language);
}

}
body {
text-align: left !important;
display: block !important;
}

width: 290px;
float: left;
}

#language-list {
width: 500px;
float: left;
}

font-weight: bold;
}

table td {
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="language-list">
<h2>Shortest Solution by Language</h2>
<table class="language-list">
<tr><td>Language</td><td>User</td><td>Score</td></tr>
<tbody id="languages">

</tbody>
</table>
</div>
<tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr>

</tbody>
</table>
</div>
<table style="display: none">
</tbody>
</table>
<table style="display: none">
<tbody id="language-template">
</tbody>
</table>

• You should be more clear: A given year is a leap year if and only if it is (divisible by 4)∧((divisible by 100)→(divisible by 400)). May 26, 2015 at 11:34
• Your input will have no newlines or trailing spaces. Dang it, that would have saved me 2 bytes... May 26, 2015 at 17:10
• You should extend the accepted input range to AD 1601 thru 2400. This covers two 400-year Gregorian cycles (which proleptically start on Monday). May 26, 2015 at 18:17
• Does falsy if leap year and truthy if not a leap year count as "clearly tells the user if it is or isn't"? May 28, 2015 at 21:27
• @lirtosiast I think so. A lot of user assume so. Jul 20, 2016 at 13:58

# PowerShell, 31 bytes

I am excited to say that I golfed this shorter than the builtin!

param($a)!($a%(4,16)[!($a%25)])  Outputs true for leap years and false otherwise. Builtin: [datetime]::IsLeapYear($args[0])


Though, if I wanted to stretch the statement 'clearly tells the user if it is or isn't a leap year' and do something non-standard, I could save 3 bytes and use:

param($a)$a%(4,16)[!($a%25)]  This outputs 0 for leap years and 1 or higher for non-leap years, which I don't like since I'd prefer to return a more standard truthy value for leap years. ## LOLCODE, 228202 159 bytes HOW IZ I f YR a MOD OF a AN 100 O RLY? YA RLY MOD OF a AN 4 O RLY? YA RLY b R 1 OIC NO WAI MOD OF a AN 400 O RLY? YA RLY b R 0 NO WAI b R 1 OIC OIC IF U SAY SO  Ungolfed: HAI 1.3 BTW "HAI" does nothing functionally in current versions and does not throw an error if you omit it. HOW IZ I leap YR input I HAS A output DIFFRINT MOD OF input AN 100 AN 0 BTW Thanks @LeakyNun, In LOLCODE any non-empty values, i.e. 0, "", etc. default to WIN. O RLY? YA RLY BOTH SAEM MOD OF a AN 4 AN 0 O RLY? YA RLY output R WIN BTW "WIN" is true, but in the actual program I used 1 as a truthy value because it's shorter. OIC NO WAI DIFFRINT MOD OF a AN 400 AN 0 O RLY? YA RLY output R FAIL BTW "Fail" is false, but in the actual program I used 0 as a falsy value. NO WAI output R WIN OIC OIC FOUND YR output BTW This statement is implied in the golfed version. IF U SAY SO BTW "KTHXBYE", just like "HAI" has no functional purpose and throws no error on omission. KTHXBYE  In Python ungolfed, because LOLCODE is confusing: def leap: if(year % 100 != 0): if(year % 4 == 0): output = true else: if(year % 400 != 0): output = false else: output = true return(output)  • Would it be shorter to define a function? Jul 22, 2016 at 16:55 • probably, but I will edit it later. Jul 22, 2016 at 16:59 • You have updated the main code to be a function, but not the ungolfed code? Jul 23, 2016 at 2:25 • I thought LOLCODE has automatic type coercion, meaning that any non-zero value is equivalent to WIN.. Jul 23, 2016 at 2:38 • It is, but how could I use that? I don't think I am doing any casting. Jul 23, 2016 at 2:41 # Mathematica, 15 bytes LeapYearQ@*List  Mathematica has a built-in for everything. List is there to make the integer input into a compact DateList object. Returns True or False. # PHP, 28 bytes Why calculate when there´s a builtin? <?=checkdate(2,29,$argv[1]);


prints 1 for leap year, empty string for no leap year.
Add + after <?= for 1/0.

INPUT Y?0DTREAD STR$(Y)+"/02/29"OUT,,,?1  Prints 0 1 if it's a leap year, otherwise prints 0 and errors. DTREAD parses a date string in the form of YYYY/MM/DD and gives the year, month, and day. It can also return the day of the week, and trying to get the day of the week of a day that doesn't exist (Feb. 29 of a non-leap year) will cause an error. This is shorter than the obvious answer using mod, because SB uses MOD instead of %, which takes up 3-5 characters. # PHP, 34 30 bytes echo+!($argn%($argn%25?4:16));  I'm using the + sign to convert false (which would normally be converted to an empty string) to 0, because that seems to comply closer to the "clearness" requirement (maybe not?). With standard truthy/falsy rules, 1 byte can be saved. Note: I shamelessly implemented the divisibility by 25 trick from @David Hammen. Without his algorithm it would be 37 bytes: <?=+!(($b=$argv[1])%400^$b%100^$b%4);  Run like this: echo 1900 | php -nR 'echo+!($argn%($argn%25?4:16));';echo  # Tweaks • Saved 4 bytes by using $argn
• Save one more byte on standard truthy/falsy with <1 instead of !() Feb 2, 2017 at 2:45

l x=mod x(if mod x 25<1then 16else 4)<1


If x is divisible by 25, check if it is also divisible by 16, making it divisible by the least common multiple of 25 and 16, which is 400.
If x is not divisible by 25, check if it is divisible by 4.

Inspired by @David Hammen's answer in JavaScript.

• I don't know Haskell, but can ==0 be <1? May 28, 2015 at 21:13
• You are right, it can. May 29, 2015 at 9:04
• You can drop the spaces before then and else. Mar 1, 2019 at 7:38
• The conditional can be equivalently expressed as (4+sum[12|mod x 25<1]) for a total of 33 bytes: Try it online! Mar 3, 2019 at 9:24

# 05AB1E, 9 7 bytes

т‰0Kθ4Ö


Explanation:

т‰         # Divmod the (implicit) input by 100
#  i.e. 1900 → [19,00]
#  i.e. 1936 → [19,36]
#  i.e. 1991 → [19,91]
#  i.e. 2000 → [20,00]
0K       # Remove all 0s
#  i.e. [19,00] → [19]
#  i.e. [19,36] → [19,36]
#  i.e. [19,91] → [19,91]
#  i.e. [20,00] → [20]
θ      # Pop and get the last item
#  i.e. [19] → 19
#  i.e. [19,36] → 36
#  i.e. [19,91] → 91
#  i.e. [20] → 20
4Ö    # Check if it's divisible by 4 (and output the result implicitly)
#  i.e. 19 → 0 (falsey)
#  i.e. 36 → 1 (truthy)
#  i.e. 91 → 0 (falsey)
#  i.e. 20 → 1 (truthy)


# x86 machine code, 14 bytes

00000000: adfd ad2d 3030 74fa 86c4 d50a a803       ...-00t.......


Unassembled

AD         LODSW           ; SI += 2 to start with last two digits
FD         STD             ; set direction for LODSW to decrement
2D 3030    SUB  AX, '00'   ; convert to decimal, test if year ends in 00?
74 FA      JZ   -6         ; if so, look at the first two digits instead
86 C4      XCHG AL, AH     ; endian convert
D5 0A      AAD             ; base convert from 10 to binary
A8 03      TEST AL, 3      ; mod 4 = 0?


Input string in SI, output is ZF if is a leap year.

Explanation

If the year does not end in 00, it is a leap year if last two digits mod 4 is 0. If it does end in 00, it will be a leap year if the first two digits mod 4 is 0. Example:

Leap year:

• 1936: 36 mod 4 == 0
• 2400: 24 mod 4 == 0

NOT leap year:

• 1805: 05 mod 4 == 1
• 1900: 19 mod 4 == 3

Test Program Output

# Excel, 30 25 bytes

Because of an intentional bug in Excel to maintain compatibility with Lotus 1-2-3 the year 1900 is treated as a leap year. We can however shift the year by 400 before doing the calculation. The leap year bug then occurs in 1500, which we don't care about anyway. For the following formula A1 serves as input.

=DAY(DATE(A1+400,2,29))>1

• If you can accept 1 for leap year and and #VALUE! for other years, you can get this down to 19 bytes: =("2/29/"&E1+400)^0. Jan 10, 2022 at 16:18

# Python 3, 26 bytes

lambda n:n%4**-~(n%25<1)<1


Try it online!

Using Kevin Cruijssen's Java approach.

# Python 3, 28 bytes

lambda n:(n%100or n/100)%4<1


Try it online!

Using Kevin Cruijssen's 05AB1E approach.

# Ruby, 28 bytes

The lambda takes an Integer y representing the year and returns true or false.

->y{y%4<1&&y%100>0||y%400<1}


Use like this:

f=->y{y%4<1&&y%100>0||y%400<1}
f[2004]
# => true


or this:

f=->y{y%4<1&&y%100>0||y%400<1}
[1936,1805,1900,2272,2400].map(&f)
# => [true, false, false, true, true]


Try it online

## Explanation

• y%4<1&&y%100>0
• Years that are divisible by 4 but not by 100 are leap years, e.g. 2004
• Years that are divisible by 4 and also by 100 are not leap years, e.g. 1700
• y%400<1
• Years that are divisible by 400 are leap years, e.g. 1600
• Welcome to Code Golf, and nice answer! According to site rules, you'll need to use a full program or function instead of assuming the input is in y. Jan 6, 2022 at 18:20
• Welcome to Code Golf, and nice first answer! Unfortunately, this isn't quite valid as submissions here must be full programs or functions. If you made this a function taking y as an argument, that'd be fine.Also, it helps to provide a TIO link or similar so others can test your code themselves. Jan 6, 2022 at 18:29
• @RedwolfPrograms thanks for pointing out, provided function (with additional 9 characters). Jan 7, 2022 at 9:09
• I just realized there's a 22 bytes Ruby solution already 🤷 Jan 7, 2022 at 9:21

# Arturo, 5 bytes

leap?


Try it!

# SpecBAS - 77

Not the shortest (but not the longest either).

1 INPUT y: PRINT y;"->";"ny"((y MOD 4=0 AND (y MOD 100<>0) OR y MOD 400=0)+1)


Uses the standard formula, then prints "n" or "y" based on return value (the final +1 at the end is due to strings being 1-based).

• I don't know the language, but based the fact that there are no booleans, you may be able to save some characters by using something like y MOD (4+12*(y MOD 100=0))=0. May 28, 2015 at 22:49

# Python, 50 48 bytes

import calendar as y
def a(b):print(y.isleap(b))


# C#, 26 bytes

y=>DateTime.IsLeapYear(y);


C# lambda (Predicate) where the input is a int and the output is a bool. I use a builtin.

• You don't really need the lambda here, and I would argue the answer is more valid without it. Jan 13, 2017 at 9:26
• @VisualMelon In the meta section, they ask for a function. (If I remember) Jan 14, 2017 at 15:24
• Aye, but DateTime.IsLeapYear is a function ;) generally the rule is that it has to evaluate to a function if it isn't named, and strictly your current submission is meaningless (join the argument here!), while System.DateTime.IsLeapYear is fully typed (System.Func<int,bool>A=System.DateTime.IsLeapYear compiles fine) without demanding any user inference (or indeed the text in your answer which specifies the input and output types). Jan 14, 2017 at 17:22

## BASH, 68 bytes

((!(y % 4) && ( y % 100 || !(y % 400)))) &&  echo "leap" || echo "no"


## Retina, 24 bytes

[^04]00$.+$*
....

^$ Try it online! # PHP, 45 bytes <?=date_create($argv[1].'-1-1')->format('L');


Not the shortest, but using built in functions. Totally not code-golf.

# Jelly, 8 bytes

ȷ2*ḍ¥×4ḍ


Try it online!

# Bash, 14 bytes

date -d$1/2/29  Try it online! Outputs via exit code, 0 for leap year and 1 otherwise. date -d STRING will display the date indicated by STRING. $1/2/29 represents February 29th of \$1, the argument. If STRING is not valid, i.e. Feb 29 does not exist, then date errors out.

# Ruby, 22 bytes

->n{1>n%(n%25<1?16:4)}


Try it online!

The challenge is quite old, but I noticed there was no valid Ruby answer yet. Nothing particularly original, anyway.

# D, 43 42 bytes

T l(T)(T y){return!(y%4)&&y%100+!(y%400);}


Try it online!

Another port of @HatsuPointerKun's C++ answer.

## C++, 50 43 bytes

-7 bytes thanks to Zacharý

int l(int y){return!(y%4)&&y%100+!(y%400);}


And the test code is :

auto t = {
1936,1805,1900,2272,2400
};

for (auto&a : t) {
std::cout << "Year : " << a << " is " << (l(a) ? "" : "NOT") << " a leap year\n";
}

• You can make it int l(int y){return(y%4==0&&y%100)+(y%400==0);} to save a few bytes Mar 29, 2018 at 13:49
• I think making +(y%400==0) +!(y%400) might work as well. Apr 1, 2018 at 18:54
• int l(int y){return!(y%4)&&y%100+!(y%400);} Nov 10, 2018 at 20:21

# Kotlin, 30 bytes

{it%4<1&&(it%100>0||it%400>0)}


Try it online!

# Common Lisp, 46 bytes

(=(mod(setq x(read))(if(>(mod x 25)0)4 16))0)


Try it online!

Based on the David Hammen’s method.

# MathGolf, 9 bytes

4♀*]÷~≤*


Try it online!

## Explanation

4         Push 4
♀        Push 100
*      Duplicate top two elements of stack and multiply (400)
]     Wrap stack in array ([4, 100, 400])
÷    Check input for divisibility with all array items
~   Dump array onto stack
≤  Check if divisibility by 100 is <= than divisibility with 400
* Multiply with the divisibility bool for 4, works like logical and


The trick is that ≤ ensures that if a number is divisible by 100, it must also be divisible by 400, but if it's not divisible by 100, anything goes.

# Clam, 33 31 bytes

=a*rp|e%a*"400"0&%a*"100"e%a*40


Try it online!

-2 bytes thanks to ASCII-only

Outputs true for leap years. Outputs false for other years

## Explanation

=a*rp|e%a*"400"0&%a*"100"e%a*40
=a*r                             read input and store in a*
p                            Print..
%a*"400"                    a* % 400
e                            ==
0                   0
|                             OR
%a*"100"            a* % 100
&                    AND
%a*4       a* % 4
e           ==
0      0


Very awkward explanation, but basically what it does is this:

print(year % 400 == 0 || (year % 100 && year % 4 == 0))


Clam follows JS rules for truthy and falsey values, meaning year % 100 is true if it does not equal 0 (and it's shorter than adding an e before it and an 0 after it)

Resulting JS:

myVar = read();
console.log(year % 400 == 0 || (year % 100 && year % 4 == 0));

• ew 8552. use something nicer like 4545 pls Jan 8, 2019 at 6:18
• jk, 31 Jan 8, 2019 at 6:19
• also pls fix your indentation in the explanation :| Jan 8, 2019 at 6:27
• fixed that year % 100 thing Jan 8, 2019 at 6:42

# Japt-h!, 8 bytes

Input is taken as a string.

k0 ò o%4


Try it online!

l x|x!25<1=x!16<1